from tokens import * from std import STD def peek(inp): if len(inp) == 0: return None return inp[0] 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 evaluate(items, pop): nxt = peek(items) if nxt is None: return pop elif isinstance(nxt, NebLiteral): return evaluate(items[1:], nxt) elif isinstance(nxt, NebSymbol): if not nxt.name in STD: raise Exception(f"no such symbol: '{nxt.name}'") this_func = STD[nxt.name] return evaluate(items[1:], this_func[list(this_func.keys())[0]].impl) # TODO show all elif isinstance(nxt, NebExpression): return evaluate(items[1:], evaluate_expression(nxt)) else: raise Exception("expected a literal or an expression")