Permalink
Browse files

latest changes

  • Loading branch information...
1 parent f2047aa commit 3e22fca72a07e262a193bfac9257b91f45c76e65 @halgari committed Dec 4, 2011
View
@@ -402,10 +402,10 @@ def gen_overloadfn(max_count = 20):
def gen_polymorph(cg, argc):
cg.writeln(get_invoke_def(argc))
cg.indent()
- cg.writeln("tp = arg0.type()")
+ cg.writeln("tp = arg0.typedef()")
cg.writeln("if tp in self.dispatches:")
cg.indent()
- cg.writeln("self.dispatches[tp].invoke"+str(argc)+get_arg_list(argc, nil))
+ cg.writeln("return self.dispatches[tp].invoke"+str(argc)+get_arg_list(argc, nil))
cg.dedent()
cg.writeln("else:")
cg.indent()
@@ -424,6 +424,7 @@ def gen_polymorphic_fn(max_count = 20):
cg.writeln("def add(self, tp, fn):")
cg.indent()
cg.writeln("self.dispatches[tp] = fn")
+ cg.dedent()
for x in range(1, max_count):
gen_polymorph(cg, x)
return cg.end()
@@ -518,16 +519,100 @@ def wrapfn(name, fn):
cg = CodeGenerator()
cg.writeln("class _WrapClass_" + str(ccount) + "(AFn):")
cg.indent()
+ cg.writeln("def __init__(self):")
+ cg.indent()
+ cg.writeln("AFn.__init__(self)")
+ cg.dedent()
argc = len(inspect.getargspec(fn).args)
cg.writeln(get_invoke_def(argc))
cg.indent()
- cg.writeln(fn.__name__ + get_arg_list(argc, nil))
+ cg.writeln("return " + fn.__name__ + get_arg_list(argc, nil))
cg.dedent()
cg.dedent()
cg.writeln("Var(sym(\""+name+"\"), _WrapClass_"+str(ccount)+"())")
return cg.end()
-def println(x):
- print x
-exec wrapfn("println", println)
+class Protocol(Obj):
+ def __init__(self, name, fns):
+ Var(name, self)
+ self.implementors = {}
+ def add_implementor(self, tp):
+ self.implementors[tp] = tp
+ def implements(self, obj):
+ if obj.type() in self.implementors:
+ return true
+ return false
+
+
+
+def protocol(name, funcs):
+ Protocol(sym(name), funcs)
+ for x in range(len(funcs)):
+ Var(sym(funcs[x]), PolymorphicFn())
+
+def extend(polymorph, type, fn):
+ poly = lookup(sym(polymorph))
+ poly.add(type, fn)
+
+
+
+protocol("ISeqable", ["seq"])
+protocol("ISeq", ["first", "rest"])
+
+
+def seq(obj):
+ return lookup(sym("seq")).invoke1(obj)
+
+def first(obj):
+ return lookup(sym("first")).invoke1(obj)
+
+def rest(obj):
+ return lookup(sym("rest")).invoke1(obj)
+
+class Array(Obj):
+ _type = TypeDef("Array")
+ def __init__(self, array):
+ Obj.__init__(self)
+ self.array = array
+ def typedef(self):
+ return Array._type
+
+class ArraySeq(Obj):
+ _type = TypeDef("ArraySeq")
+ def __init__(self, array, idx):
+ Obj.__init__(self)
+ self.idx = idx
+ self.array = array
+ def typedef(self):
+ return ArraySeq._type
+
+def ArraySeq_first(arr):
+ return arr.array[arr.idx]
+
+def ArraySeq_rest(arr):
+ if arr.idx + 1 >= len(arr.array):
+ return nil
+ return ArraySeq(arr.array, arr.idx + 1)
+
+def Array_seq(arr):
+ return ArraySeq(arr.array, 0)
+
+x = wrapfn("array-seq", Array_seq)
+exec x
+exec wrapfn("first-arrayseq", ArraySeq_first)
+exec wrapfn("rest-arrayseq", ArraySeq_rest)
+
+
+extend("seq", Array._type, lookup(sym("array-seq")))
+extend("first", ArraySeq._type, lookup(sym("first-arrayseq")))
+extend("rest", ArraySeq._type, lookup(sym("rest-arrayseq")))
+
+
+v = Array([1, 2, 3, 4, 5])
+
+s = seq(v)
+
+while s is not nil:
+ print first(s)
+ s = rest(s)
View
@@ -0,0 +1,3 @@
+
+
+
View
Binary file not shown.
View
Binary file not shown.
View
@@ -0,0 +1,77 @@
+import string
+
+
+class CodeGeneratorBackend:
+ def begin(self, tab="\t"):
+ self.code = []
+ self.tab = tab
+ self.level = 0
+ def end(self):
+ return string.join(self.code, "")
+ def writeln(self, string):
+ return self.write(string+"\n")
+ def write(self, string):
+ self.code.append(self.tab * self.level + string)
+ def indent(self):
+ self.level = self.level + 1
+ def dedent(self):
+ import sys
+ if self.level == 0:
+ raise SyntaxError, "internal error in code generator"
+ self.level = self.level - 1
+
+
+def gen_invoke(cg, argc):
+ arglist = ["self"]
+ for x in range(argc):
+ arglist.append("arg"+str(x))
+ cg.writeln("def invoke" + str(argc)+"(" + ", ".join(arglist) +"):")
+ cg.indent()
+ cg.writeln("raise Exception('bad arity ' + str(" + str(argc)+"))")
+ cg.dedent()
+
+def gen_apply_block(cg, argc, evalstr = ".evaluate()"):
+ cg.writeln("if lst.length().int_value() == " + str(argc) + ":")
+ cg.indent()
+ args = []
+ for x in range(argc):
+ cg.writeln("arg" + str(x) + " = lst.first()"+evalstr)
+ cg.writeln("lst = lst.rest()")
+ args.append("arg" + str(x))
+ cg.writeln("return self.invoke"+str(argc)+"(" + ",".join(args)+")")
+ cg.dedent()
+
+def gen_applies(cg, max_count = 20):
+ cg.writeln("def apply(self, lst):")
+ cg.indent()
+ cg.writeln("if self.is_builtin().bool_value():")
+ cg.indent()
+ for x in range(max_count):
+ gen_apply_block(cg, x, "")
+ cg.dedent()
+ cg.writeln("else:")
+ cg.indent()
+ for x in range(max_count):
+ gen_apply_block(cg, x)
+ cg.dedent()
+
+def gen_afn(max_count = 20):
+ cg = CodeGeneratorBackend()
+ cg.begin()
+ cg.writeln("# This file is autogenerated.")
+ cg.writeln("# DO NOT EDIT!!!!!")
+ cg.writeln("from clojure.lang.primitives import Obj")
+ cg.writeln("class AFn(Obj):")
+ cg.indent()
+ for x in range(max_count):
+ gen_invoke(cg, x)
+ gen_applies(cg, max_count)
+ cg.dedent()
+ f = open("clojure/lang/afn_gen.py", "w")
+ res = cg.end()
+ f.write(res)
+ return res
+
+gen_afn()
+from clojure.lang.afn_gen import AFn
+
View
Binary file not shown.
View
Binary file not shown.
View
@@ -0,0 +1,105 @@
+from clojure.lang.primitives import Obj, BoolObj
+from clojure.lang.list import List, EmptyList
+from clojure.lang.var import Var, push_frame, Binding, pop_frame
+from clojure.lang.symbol import Symbol
+from clojure.lang.primitives import Obj, IntObj
+
+class RecurInfo(Obj):
+ def set_recur(self, recur):
+ self._inrecur = recur
+ def get_recur(self):
+ return self._inrecur
+
+_RecurInfo = RecurInfo()
+
+class UserFn(Obj):
+ def __init__(self, bindings, forms):
+ self._bindings = bindings
+ self._forms = forms
+ def evaluate(self):
+ return self
+ def invoke(self, args):
+ res = None
+ while True:
+ res = self.inner_invoke(args)
+ if _RecurInfo.get_recur() is not None:
+ args = _RecurInfo.get_recur()
+ else:
+ break
+ _RecurInfo.set_recur(None)
+ return res
+ def inner_invoke(self, args):
+ binds = EmptyList()
+ bs = self._bindings
+ for x in range(self._bindings.length().int_value()):
+ binds = binds.cons(Binding(bs.first(), args[x]))
+ bs = bs.rest()
+ push_frame(binds)
+ form = self._forms
+ res = None
+ for x in range(len(form)):
+ res = form[x].evaluate()
+ pop_frame()
+ return res
+ def is_builtin(self):
+ return BoolObj(False)
+
+
+
+class Fn(Obj):
+ def __init__(self):
+ pass
+ def is_builtin(self):
+ return BoolObj(True)
+ def evaluate(self):
+ return self
+ def invoke(self, args):
+ return UserFn(args[0], args[1:])
+
+class If(Obj):
+ def __init__(self):
+ pass
+ def is_builtin(self):
+ return BoolObj(True)
+ def evaluate(self):
+ return self
+ def invoke(self, args):
+ res = args[0].evaluate().bool_value()
+ if res:
+ return args[1].evaluate()
+ if len(args) == 2:
+ return None
+ return args[2].evaluate()
+
+class Def(Obj):
+ def __init__(self):
+ pass
+ def is_builtin(self):
+ return BoolObj(True)
+ def evaluate(self):
+ return self
+ def invoke(self, args):
+ val = args[1].evaluate()
+ return Var(args[0], val)
+
+
+class Recur(Obj):
+ def __init__(self):
+ pass
+ def is_builtin(self):
+ return BoolObj(True)
+ def evaluate(self):
+ return self
+ def invoke(self, args):
+ nlist = []
+ for x in range(len(args)):
+ nlist.append(args[x].evaluate())
+ _RecurInfo.set_recur(nlist)
+ return None
+
+recur = Var(Symbol.from_string("recur"), Recur())
+d = Var(Symbol.from_string("def"), Def())
+fn = Var(Symbol.from_string("fn"), Fn())
+
+ifsym = Var(Symbol.from_string("if"), If())
+
View
Binary file not shown.
Oops, something went wrong.

0 comments on commit 3e22fca

Please sign in to comment.