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()
|