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