aboutsummaryrefslogtreecommitdiff
path: root/std.py
blob: 8897446e07054efeb131d28c58cf89e577ea16b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from tokens import *
#from runner import evaluate_expression
import sys
from collections import namedtuple

FuncImpl = namedtuple("FuncImpl", ("func", "impl"))

STD = {}
DEBUG = True
USER = {}

def _get_debug():
    return DEBUG

def std_exit(status=None):
    out = 0 if status is None else status.value
    sys.exit(out)
    return NebLiteral(NebType.BOOL, True)  # this should never be reached

def std_print(arg):
    print(arg.value)
    #return []  # TODO this should return empty list
    return NebLiteral(NebType.BOOL, True)

def std_debug_on():
    global DEBUG
    DEBUG = True
    return NebLiteral(NebType.BOOL, True)

def std_debug_off():
    global DEBUG
    DEBUG = False
    return NebLiteral(NebType.BOOL, True)

# math
def std_add(arg1, arg2):
    typ = NebType.INT
    if NebType.FLOAT in (arg1.type_, arg2.type_):
        typ = NebType.FLOAT
    return NebLiteral(typ, arg1.value + arg2.value)

def std_subtract(arg1, arg2):
    typ = NebType.INT
    if NebType.FLOAT in (arg1.type_, arg2.type_):
        typ = NebType.FLOAT
    return NebLiteral(typ, arg1.value - arg2.value)

def std_multiply(arg1, arg2):
    typ = NebType.INT
    if NebType.FLOAT in (arg1.type_, arg2.type_):
        typ = NebType.FLOAT
    return NebLiteral(typ, arg1.value * arg2.value)

# strings
def std_concat(arg1, arg2):
    return NebLiteral(NebType.STRING, f"{arg1.value}{arg2.value}")

# flow control
def std_if(cond, t_branch, f_branch):
    if cond.value:
        ret = evaluate_expression(t_branch)
    else:
        ret = evaluate_expression(f_branch)
    #return NebLiteral(NebType.BOOL, True)
    #return NebLiteral(, True)
    return ret

def evaluate_expression(expr):
    if not expr.symbol.name in STD:
        raise Exception(f"no such symbol: {expr.symbol.name}")
    this_func = STD[expr.symbol.name]

    # try to match the signature
    in_sig = expr.in_sig()
    if in_sig in this_func:
        ret = this_func[expr.in_sig()].impl(*(expr.args))
        return ret

    # evaluate inner expressions, if possible/necessary
    for idx, arg in enumerate(expr.args):
        if arg.type_ == NebType.EXPR:
            expr.args[idx] = evaluate_expression(arg)
            return evaluate_expression(expr)

    raise Exception(f"'{expr.symbol.name}' called with unknown signature: '{expr.in_sig()}'")

def build_sig_dict(*args):
    return {arg.func.in_sig(): arg for arg in args}

def build_std():
    print_string = FuncImpl(NebFunction("print", [NebType.STRING], NebType.BOOL), std_print)
    STD["print"] = build_sig_dict(print_string)

    exit_ = FuncImpl(NebFunction("exit", [], NebType.BOOL), std_exit)
    exit_int = FuncImpl(NebFunction("exit", [NebType.INT], NebType.BOOL), std_exit)
    STD["exit"] = build_sig_dict(exit_, exit_int)

    debug_on = FuncImpl(NebFunction("debug-on", [], NebType.BOOL), std_debug_on)
    STD["debug-on"] = build_sig_dict(debug_on)
    debug_off = FuncImpl(NebFunction("debug-off", [], NebType.BOOL), std_debug_off)
    STD["debug-off"] = build_sig_dict(debug_off)

    # arithmetic
    add_int_int = FuncImpl(NebFunction("+", [NebType.INT, NebType.INT], NebType.INT), std_add)
    add_int_float = FuncImpl(NebFunction("+", [NebType.INT, NebType.FLOAT], NebType.FLOAT), std_add)
    add_float_int = FuncImpl(NebFunction("+", [NebType.FLOAT, NebType.INT], NebType.FLOAT), std_add)
    add_float_float = FuncImpl(NebFunction("+", [NebType.FLOAT, NebType.FLOAT], NebType.FLOAT), std_add)
    STD["+"] = build_sig_dict(add_int_int, add_int_float, add_float_int, add_float_float)

    subtract_int_int = FuncImpl(NebFunction("-", [NebType.INT, NebType.INT], NebType.INT), std_subtract)
    subtract_int_float = FuncImpl(NebFunction("-", [NebType.INT, NebType.FLOAT], NebType.FLOAT), std_subtract)
    subtract_float_int = FuncImpl(NebFunction("-", [NebType.FLOAT, NebType.INT], NebType.FLOAT), std_subtract)
    subtract_float_float = FuncImpl(NebFunction("-", [NebType.FLOAT, NebType.FLOAT], NebType.FLOAT), std_subtract)
    STD["-"] = build_sig_dict(subtract_int_int, subtract_int_float, subtract_float_int, subtract_float_float)

    multiply_int_int = FuncImpl(NebFunction("*", [NebType.INT, NebType.INT], NebType.INT), std_multiply)
    multiply_int_float = FuncImpl(NebFunction("*", [NebType.INT, NebType.FLOAT], NebType.FLOAT), std_multiply)
    multiply_float_int = FuncImpl(NebFunction("*", [NebType.FLOAT, NebType.INT], NebType.FLOAT), std_multiply)
    multiply_float_float = FuncImpl(NebFunction("*", [NebType.FLOAT, NebType.FLOAT], NebType.FLOAT), std_multiply)
    STD["*"] = build_sig_dict(multiply_int_int, multiply_int_float, multiply_float_int, multiply_float_float)

    # strings
    concat_string_string = FuncImpl(NebFunction("concat", [NebType.STRING, NebType.STRING], NebType.STRING), std_concat)
    STD["concat"] = build_sig_dict(concat_string_string)

    # flow control
    if_bool_expr_expr = FuncImpl(NebFunction("if", [NebType.BOOL, NebType.EXPR, NebType.EXPR], NebType.ANY), std_if)
    STD["if"] = build_sig_dict(if_bool_expr_expr)

build_std()