###
# 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 nova.core import (exec_build, atom_integer_encode,
    check_integer, Compound, set, exec_unify,
    make_check, make_error, check_number, check_atom)


#######################################################################
# 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.
##
def test_sys_number_atom(args):
    num = exec_build(args[0])
    check_number(num)
    spec = exec_build(args[1])
    check_atom(spec)
    digs = exec_build(args[2])
    check_integer(digs)
    if digs < 0:
        raise make_error(Compound("domain_error",
            ["not_less_than_zero", digs]))
    try:
        num = float(num)
    except OverflowError:
        raise make_error(Compound("evaluation_error", ["float_overflow"]))
    if "fFeEgG".find(spec) != -1:
        text = ("%."+str(digs)+spec) % num
    else:
        raise make_error(Compound("existence_error",
            ["format_character", spec]))
    return exec_unify(args[3], text)


#######################################################################
# 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.
##
def test_sys_integer_atom(args):
    num = exec_build(args[0])
    check_integer(num)
    spec = exec_build(args[1])
    check_atom(spec)
    radix = exec_build(args[2])
    check_integer(radix)
    if "r" == spec:
        text = atom_integer_encode(num, radix)
    elif "R" == spec:
        text = atom_integer_encode(num, radix)
        text = text.upper()
    else:
        raise make_error(Compound("existence_error",
                                  ["format_character", spec]))
    return exec_unify(args[3], text)


#######################################################################
# Str Lib Init                                                        #
#######################################################################

def main():
    set("sys_number_atom", 4, make_check(test_sys_number_atom))
    set("sys_integer_atom", 4, make_check(test_sys_integer_atom))
