Java "strlib"

Admin User, created Apr 11. 2024
         
package liblet.util;
import nova.envir.ComputeCompare;
import nova.envir.ComputeElem;
import nova.Machine;
import nova.Special;
import nova.Store;
import java.util.Locale;
/**
* Modern Albufeira Prolog Interpreter
* <p>
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
* <p>
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
* <p>
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
* <p>
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
* <p>
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
public final class strlib {
/*******************************************************************/
/* Number Formatting */
/*******************************************************************/
/**
* sys_float_atom(F, S, N, A):
* The built-in succeeds in A with the number F
* formatted according to the format specifier S
* and the number of digits N.
*/
private static boolean test_sys_float_atom(Object[] args) {
Object value = Machine.deref(Machine.exec_build(args[0]));
Special.check_number(value);
Object spec = Machine.deref(Machine.exec_build(args[1]));
Special.check_atom(spec);
Object alpha = Machine.deref(Machine.exec_build(args[2]));
Special.check_integer(alpha);
if (ComputeCompare.integer_signum((Number) alpha) < 0)
throw Machine.make_error(new Store.Compound("domain_error",
new Object[]{"not_less_than_zero", alpha}));
if (Special.is_bigint(alpha))
throw Machine.make_error(new Store.Compound("representation_error",
new Object[]{"int"}));
int digs = ((Integer)alpha).intValue();
String res;
value = value instanceof Double ? value :
Double.valueOf(ComputeElem.narrow_float((Number)value));
if ("f".equals(spec)) {
res = String.format(Locale.UK, "%." + Integer.toString(digs) + "f", value);
res = shapeFloat(res, 0);
} else if ("e".equals(spec)) {
res = String.format(Locale.UK, "%." + Integer.toString(digs) + "e", value);
res = shapeFloat(res, 0);
} else if ("g".equals(spec)) {
res = String.format(Locale.UK, "%." + Integer.toString(digs) + "g", value);
res = shapeFloat(res, 2);
} else {
throw Machine.make_error(new Store.Compound("domain_error",
new Object[]{"illegal_format", spec}));
}
return Machine.exec_unify(args[3], res);
}
/**
* Shape the number string so that it has no exponent positive
* sign and lower case exponent. If (flag & 2) !== 0 remove
* trailing zeros, with removing the period, from mantissa.
* Further remove the exponent from leading zeros.
*
* @param res The ascii number string.
* @param flag The shaping flags.
* @return The shaped number string.
*/
public static String shapeFloat(String res, int flag) {
int peek = res.indexOf('e');
if (peek != -1) {
res = shapeFloatMantissa(res.substring(0, peek), flag) +
"e" + shapeFloatExponent(res.substring(peek + 1));
} else {
res = shapeFloatMantissa(res, flag);
}
return res;
}
private static String shapeFloatMantissa(String res, int flag) {
if ((flag & 2) != 0) {
if (res.indexOf('.') != -1) {
int pos = res.length();
while (res.charAt(pos - 1) == '0')
pos--;
if (res.charAt(pos - 1) == '.')
pos--;
if (pos != res.length())
res = res.substring(0, pos);
}
}
if ((flag & 1) != 0) {
if (res.indexOf('.') == -1)
res += ".0";
}
return res;
}
private static String shapeFloatExponent(String res) {
if (0 < res.length() && res.charAt(0) == '+')
res = res.substring(1);
if (res.startsWith("0") && 1 < res.length())
res = res.substring(1);
else if (res.startsWith("-0") && 2 < res.length())
res = "-" + res.substring(2);
return res;
}
/*********************************************************************/
/* Str Lib Init */
/*********************************************************************/
public static void main() {
Store.add("sys_float_atom", 4, Special.make_check(strlib::test_sys_float_atom));
}
}