JavaScript "strlib"

Admin User, erstellt 04. Dez. 2023
         
/**
* Modern Albufeira Prolog Interpreter
*
* 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.
*/
import {exec_build, check_integer, add, check_number,
narrow_float, check_atom, make_check,
exec_unify, Compound, make_error, deref
} from "../../dogelog.mjs";
function test_sys_float_atom(args) {
let value = deref(exec_build(args[0]));
check_number(value);
let spec = deref(exec_build(args[1]));
check_atom(spec);
let digs = deref(exec_build(args[2]));
check_integer(digs);
if (digs < 0)
throw make_error(new Compound("domain_error",
["not_less_than_zero", digs]));
let text;
value = narrow_float(value);
if (spec === "f") {
text = value.toFixed(digs);
text = shape_float(text, 0);
} else if (spec === "e") {
text = value.toExponential(digs);
text = shape_float(text, 0);
} else if (spec === "g") {
text = value.toPrecision(digs);
text = shape_float(text, 2);
} else {
throw make_error(new Compound("domain_error",
["illegal_format", spec]));
}
return exec_unify(args[3], text);
}
function shape_float(res, flag) {
let peek = res.indexOf("e");
if (peek !== -1) {
res = shape_float_mantissa(res.slice(0, peek), flag) +
"e" + shape_float_exponent(res.slice(peek+1));
} else {
res = shape_float_mantissa(res, flag);
}
return res;
}
function shape_float_mantissa(res, flag) {
if ((flag & 2) !== 0) {
if (res.indexOf(".") !== -1) {
let pos = res.length;
while (res.codePointAt(pos - 1) === 48) // '0'
pos--;
if (res.charCodeAt(pos - 1) === 46) // '.'
pos--;
if (pos !== res.length)
res = res.slice(0, pos);
}
}
return res;
}
function shape_float_exponent(res) {
if (0 < res.length && res.charCodeAt(0) === 43) // '+'
res = res.slice(1);
return res;
}
export function main() {
add("sys_float_atom", 4, make_check(test_sys_float_atom));
}