def eval(self, node, env): from Tree.ConsNode import ConsNode if node.get_cdr().get_car().is_pair(): # function def params = node.get_cdr().get_car().get_cdr() fun_name = node.get_cdr().get_car().get_car() body = node.get_cdr().get_cdr() val = ConsNode(IdentNode("lambda"), ConsNode(params, body)).eval(env) env.define(fun_name, val) else: # normal def val = node.get_cdr().get_cdr().get_car().eval(env) ident = node.get_cdr().get_car() env.define(ident, val) return val
def reverse(node): from Tree.ConsNode import ConsNode if node.is_null() or node == None: return nil_node else: return Special.append_lists(Special.reverse(node.get_cdr()), ConsNode( \ node.get_car(), nil_node))
def eval_list(l, env): # this is here to avoid circular imports between Tree.ConsNode and Special.Regular from Tree.ConsNode import ConsNode if l.is_null(): return nil_node else: return ConsNode(l.get_car().eval(env), Special.eval_list(l.get_cdr(), env))
def parse_exp(self, token): if token.get_type() == TokenTypes.LPAREN: return self.parse_rest1(self.scanner.get_next_token()) elif token.get_type() == TokenTypes.STRING: return StringNode(token.get_string_val()) elif token.get_type() == TokenTypes.IDENT: return IdentNode(token.get_name()) elif token.get_type() == TokenTypes.INT: return IntNode(token.get_int_val()) elif token.get_type() == TokenTypes.QUOTE: return ConsNode(IdentNode("quote"), ConsNode( \ self.parse_exp(self.scanner.get_next_token()) \ , nil_node)) elif token.get_type() == TokenTypes.TRUE: return true_node elif token.get_type() == TokenTypes.FALSE: return false_node else: raise Exception("unrecognized token received")
def apply(self, args): from Tree.ConsNode import ConsNode params = self.f.get_cdr().get_car() if not Node.same_length_lists(params, args): raise Exception("params and argument count don't match") head = nil_node env = Environment(self.env) while not params.is_null(): if not params.is_pair(): # n-ary function ? env.define(params, args) break else: env.define(params.get_car(), args.get_car()) params = params.get_cdr() args = args.get_cdr() body = self.f.get_cdr().get_cdr() return ConsNode(IdentNode("begin"), body).eval(env)
def apply(self, args): built_in = self.symbol args_length = Node.list_length(args) if args_length == 0: if built_in == "newline": print() return nil_node elif built_in == "builtin-env": return BuiltInNode.built_in_env elif built_in == "global-env": return BuiltInNode.global_env else: raise Exception("unknown builtin function with 0 params") arg1 = args.get_car() if args_length == 1: if built_in == "write": arg1.print(0) return nil_node elif built_in == "car": return arg1.get_car() elif built_in == "cdr": return arg1.get_cdr() elif built_in == "null?": return true_node if arg1.is_null() else false_node elif built_in == "pair?": return true_node if arg1.is_pair() else false_node elif built_in == "procedure?": return true_node if arg1.is_procedure() else false_node elif built_in == "symbol?": return true_node if arg1.is_symbol() else false_node elif built_in == "number?": return true_node if arg1.is_number() else false_node elif built_in == "display": return arg1 else: raise Exception("unknown builtin function with 1 param") arg2 = args.get_cdr().get_car() if args_length == 2: if built_in == "eval": return arg1.eval(arg2) elif built_in == "b-": return IntNode(arg1.get_value() - arg2.get_value()) elif built_in == "b+": return IntNode(arg1.get_value() + arg2.get_value()) elif built_in == "b*": return IntNode(arg1.get_value() * arg2.get_value()) elif built_in == "b/": return IntNode(arg1.get_value() / arg2.get_value()) elif built_in == "b=": return true_node if arg1.get_value() == arg2.get_value( ) else false_node elif built_in == "b<": return true_node if arg1.get_value() < arg2.get_value( ) else false_node elif built_in == "eq?": return true_node if arg1 == arg2 else false_node elif built_in == "cons": return ConsNode(arg1, arg2) elif built_in == "apply": return arg1.apply(arg2) elif built_in == "eval": return arg1.eval(arg2) elif built_in == "set-car!": arg1.set_car(arg2) return arg1 elif built_in == "set-cdr!": arg1.set_cdr(arg2) return arg1 else: raise Exception("unknown builtin function with 2 params") raise Exception("unknown builtin function %s" % built_in)
def parse_rest1(self, token): if token.get_type() == TokenTypes.RPAREN: return nil_node else: return ConsNode(self.parse_exp(token), self.parse_rest2( \ self.scanner.get_next_token()))
def append_lists(node1, node2): from Tree.ConsNode import ConsNode if node1.is_null(): return node2 else: return ConsNode(node1.get_car(), Special.append_lists(node1.get_cdr(), node2))