Python "strlib"

Admin User, created Dec 04. 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.
##
from dogelog import (exec_build, deref,
check_integer, Compound, add, exec_unify,
make_check, make_error, check_number, check_atom)
#######################################################################
# 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.
##
def test_sys_float_atom(args):
value = deref(exec_build(args[0]))
check_number(value)
spec = deref(exec_build(args[1]))
check_atom(spec)
digs = deref(exec_build(args[2]))
check_integer(digs)
if digs < 0:
raise make_error(Compound("domain_error",
["not_less_than_zero", digs]))
try:
value = float(value)
except OverflowError:
raise make_error(Compound("evaluation_error", ["float_overflow"]))
if spec == "f":
text = ("%."+str(digs)+"f") % value
text = shape_float(text)
elif spec == "e":
text = ("%."+str(digs)+"e") % value
text = shape_float(text)
elif spec == "g":
text = ("%."+str(digs)+"g") % value
text = shape_float(text)
else:
raise make_error(Compound("domain_error",
["illegal_format", spec]))
return exec_unify(args[3], text)
###
# Shape the number string so that it has no exponent positive
# sign and lower case exponent. Further remove the exponent
# from leading zeros.
#
# @param res The ascii number string.
# @return The shaped number string.
##
def shape_float(res):
peek = res.find("e")
if peek != -1:
res = shape_float_mantissa(res[0:peek]) + \
"e" + shape_float_exponent(res[peek+1:])
else:
res = shape_float_mantissa(res)
return res
def shape_float_mantissa(res):
return res
def shape_float_exponent(res):
if 0 < len(res) and ord(res[0]) == 43: # '+'
res = res[1:]
if res.startswith("0") and 1 < len(res):
res = res[1:]
elif res.startswith("-0") and 2 < len(res):
res = "-" + res[2:]
return res
#######################################################################
# Str Lib Init #
#######################################################################
def main():
add("sys_float_atom", 4, make_check(test_sys_float_atom))