Java "strlib"

         
package doglet.text;
import nova.Machine;
import nova.Store;
import nova.eval;
import nova.special;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
/**
* 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.
*
* 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.
*
* 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.
*
* 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.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
public final class strlib {
/*******************************************************************/
/* Number Formatting */
/*******************************************************************/
/**
* sys_number_atom(F, S, N, A): internal only
* 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_number_atom(Object[] args) {
Object num = Machine.exec_build(args[0]);
special.check_number(num);
Object spec = Machine.exec_build(args[1]);
special.check_atom(spec);
Object alpha = Machine.exec_build(args[2]);
special.check_integer(alpha);
if (Machine.is_bigint(alpha))
throw Machine.make_error(new Store.Compound("representation_error",
new Object[]{"int"}));
int digs = ((Integer) alpha).intValue();
if (digs < 0)
throw Machine.make_error(new Store.Compound("domain_error",
new Object[]{"not_less_than_zero", alpha}));
String text;
double value = num instanceof Double ? ((Double) num).doubleValue() :
special.narrow_float((Number) num);
if ("fF".contains((String)spec)) {
text = floatAtom(value, digs, "0.0");
text = shapeFloat(text, (String)spec);
} else if ("eE".contains((String)spec)) {
text = floatAtom(value, digs, "0.0E00");
text = shapeFloat(text, (String)spec);
} else if ("gG".contains((String)spec)) {
int mag = (value != 0 ? (int)Math.floor(Math.log10(
Math.abs(value))) : 0);
if (mag >= digs || mag < -4) {
text = floatAtom(value, digs - 1, "0.0E00");
} else {
text = floatAtom(value, digs - 1 - mag, "0.0");
}
text = shapeFloat(text, (String)spec);
} else {
throw Machine.make_error(new Store.Compound("existence_error",
new Object[]{"format_character", spec}));
}
return Machine.exec_unify(args[3], text);
}
private static String floatAtom(double value, int digs, String type) {
DecimalFormat fmt = (DecimalFormat)NumberFormat.getInstance(Locale.UK);
fmt.applyPattern(type);
fmt.setMaximumFractionDigits(digs);
fmt.setMinimumFractionDigits(digs);
fmt.setRoundingMode(RoundingMode.HALF_EVEN);
fmt.setGroupingUsed(false);
return fmt.format(value);
}
/**
* Shape the number string.
*
* @param res The number string.
* @param spec The format specifier.
* @return The shaped number string.
*/
public static String shapeFloat(String res, String spec) {
int peek = res.indexOf('E');
if (peek != -1) {
res = shapeFloatMantissa(res.substring(0, peek), spec) +
("FEG".contains(spec) ? "E": "e")
+ shapeFloatExponent(res.substring(peek + 1));
} else {
res = shapeFloatMantissa(res, spec);
}
return res;
}
private static String shapeFloatMantissa(String res, String spec) {
if ("gG".contains(spec)) {
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);
}
}
return res;
}
private static String shapeFloatExponent(String res) {
if (res.startsWith("-"))
return res;
return "+"+res;
}
/*******************************************************************/
/* Integer Formatting */
/*******************************************************************/
/**
* sys_integer_atom(F, S, N, A): internal only
* The built-in succeeds in A with the integer F formatted according
* to the format specifier S and the radix N.
*/
private static boolean test_sys_integer_atom(Object[] args) {
Object num = Machine.exec_build(args[0]);
special.check_integer(num);
Object spec = Machine.exec_build(args[1]);
special.check_atom(spec);
Object alpha = Machine.exec_build(args[2]);
special.check_integer(alpha);
if (Machine.is_bigint(alpha))
throw Machine.make_error(new Store.Compound("representation_error",
new Object[]{"int"}));
int radix = ((Integer) alpha).intValue();
if (radix < 2 || radix > 36)
throw Machine.make_error(new Store.Compound("domain_error",
new Object[]{"radix", alpha}));
String text;
if ("r".equals(spec)) {
text = special.atom_integer_encode(num, radix);
} else if ("R".equals(spec)) {
text = special.atom_integer_encode(num, radix);
text = text.toUpperCase();
} else {
throw Machine.make_error(new Store.Compound("existence_error",
new Object[]{"format_character", spec}));
}
return Machine.exec_unify(args[3], text);
}
/*******************************************************************/
/* Str Lib Init */
/*******************************************************************/
public static void main() {
Store.set("sys_number_atom", 4, special.make_check(strlib::test_sys_number_atom));
Store.set("sys_integer_atom", 4, special.make_check(strlib::test_sys_integer_atom));
}
}

Use Privacy (c) 2005-2026 XLOG Technologies AG