def __init__(self, env, outer={}, bindings=None, args=None): super().__init__(env, outer={}, bindings=bindings, args=args) self.env = { datatypes.Symbol("+"): primitives._plus, datatypes.Symbol("-"): primitives._minus, datatypes.Symbol("*"): primitives._mult, datatypes.Symbol("/"): primitives._div, datatypes.Symbol("="): primitives._eq, datatypes.Symbol("<"): primitives._lt, datatypes.Symbol(">"): primitives._gt, datatypes.Symbol("not"): primitives._not, datatypes.Symbol("print"): primitives._print, datatypes.Symbol("read"): primitives._read, }
def _eval_quote(data, env): assert len(data) == 1 quoted_syntax_tree = data[0] if isinstance(quoted_syntax_tree, list): # TODO(jasonpr): Use a Lisp list. return [_eval_quote([subtree], env) for subtree in quoted_syntax_tree] else: return datatypes.Symbol(quoted_syntax_tree)
def _symbol(self, node): itm = node.tail[0] if itm == 'nil' or itm == 'None': return None elif itm == 'true' or itm == 'True': return True elif itm == 'false' or itm == 'False': return False elif isint(itm): return int(itm) elif isfloat(itm): return float(itm) elif iskeyword(itm): return datatypes.Keyword(itm) else: return datatypes.Symbol(itm)
def eval_list(self, expr, env): if len(expr) == 0: return expr head = expr[0] if datatypes.isSymbol(head): if head.name == 'def': env.set(expr[1], self.eval(expr[2], env)) return None elif head.name == 'set-attribute!': e = self.eval(expr[1], env) setattr(e, self.eval(expr[2], env), self.eval(expr[3], env)) return None elif head.name == 'quote': return expr[1] elif head.name == 'fn': return datatypes.Lambda(expr[1], expr[2], copy.copy(env)) elif head.name == 'do': v = None for e in expr[1:]: v = self.eval(e, env) return v elif head.name == 'if': test = self.eval(expr[1], env) if test: return self.eval(expr[2], env) elif len(expr) == 4: return self.eval(expr[3], env) else: return None elif head.name == 'and': v = True for e in expr[1:]: v = self.eval(e, env) if not v: return v return v elif head.name == 'or': v = None for e in expr[1:]: v = self.eval(e, env) if v: return v return v elif head.name == 'import': return dynamic.import_module(expr[1].name) elif head.name == 'load-class': class_name = expr[1].name.split('.') module = self.eval(datatypes.Symbol(class_name[0]), env) rest = expr[1].name.split('.')[1:] return dynamic.load_class(module, rest) elif head.name == 'new': class_object = self.eval(expr[1], env) args = [self.eval(arg, env) for arg in expr[2:]] return dynamic.make_instance(class_object, args) elif head.name == 'count': return len(expr[1]) elif head.name == 'type': return type(self.eval(expr[1], env)) elif head.name == '.': obj = self.eval(expr[1], env) attribute = expr[2].name attr = dynamic.attribute(obj, attribute) if callable(attr): args = [self.eval(arg, env) for arg in expr[3:]] return attr(args) else: return attr elif head.name[0] == '.': instance = self.eval(expr[1], env) method_name = head.name[1:] args = [self.eval(arg, env) for arg in expr[2:]] return dynamic.attribute_or_call(instance, method_name, args) elif head.name[-1] == '.': class_name_chain = head.name.split('.')[:-1] class_object = dynamic.load_class( self.eval( datatypes.Symbol(class_name_chain[0]), env), class_name_chain[1:]) args = [self.eval(arg, env) for arg in expr[1:]] return dynamic.make_instance(class_object, args) else: args = [self.eval(v, env) for v in expr[1:]] return self.apply_function(env.get(head), args, env) elif datatypes.isKeyword(head): arg = self.eval(expr[1], env) if datatypes.isHashMap(arg) or isinstance(arg, dict): return arg.get(head) elif datatypes.isSet(arg): if head in arg: return head return None raise Exception("applying Keyword to type " + str(type(arg)) + "is not implemented") elif datatypes.isLambda(head): args = [self.eval(v, env) for v in expr[1:]] return self.apply_function(head, args, env) elif datatypes.isHashMap(head): return head.get(self.eval(expr[1], env)) elif datatypes.isSet(head): v = self.eval(expr[1], env) if v in head: return v else: return None elif isinstance(head, list): head = self.eval(head, env) return self.eval([head] + expr[1:], env) raise Exception("evaluation not yet implemented for head of type " + str(type(head)))
def _quoted(self, node): return [datatypes.Symbol('quote')] + node.tail