Skip to content

Commit fd9ca3f

Browse files
committed
more improvements to the new compiler, can compile deftypes
1 parent 8a22208 commit fd9ca3f

5 files changed

Lines changed: 259 additions & 24 deletions

File tree

pixie/compiler.pxi

Lines changed: 180 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
(seq? x) :seq
1010
(vector? x) :vector
1111
(symbol? x) :symbol
12-
(number? x) :number)))
12+
(number? x) :number
13+
(keyword? x) :keyword)))
1314

1415
(defmulti analyze-seq (fn [x]
1516
(let [f (first x)]
@@ -51,7 +52,7 @@
5152
[body]
5253
body)
5354
analyzed-bodies (reduce
54-
analyze-fn-body
55+
(partial analyze-fn-body name)
5556
{}
5657
arities)]
5758
{:op :fn
@@ -62,9 +63,14 @@
6263
:arities (vals analyzed-bodies)}
6364
))
6465

65-
(defn analyze-fn-body [acc [args & body]]
66+
(defn analyze-fn-body [fn-name acc [args & body]]
6667
; TODO: Add support for variadic fns
6768
(let [arity (count args)
69+
new-env (assoc-in *env* [:locals fn-name] {:op :binding
70+
:type :fn-self
71+
:name fn-name
72+
:form fn-name
73+
:env *env*})
6874
new-env (reduce
6975
(fn [acc idx]
7076
(let [arg-name (nth args idx)]
@@ -74,7 +80,7 @@
7480
:name arg-name
7581
:form arg-name
7682
:env *env*})))
77-
*env*
83+
new-env
7884
(range (count args)))]
7985
(assert (not (acc arity)) (str "Duplicate arity for " (cons args body)))
8086
(assoc acc arity {:op :fn-body
@@ -130,7 +136,8 @@
130136
(defmethod analyze-seq :default
131137
[[sym & args :as form]]
132138
(println form)
133-
(let [resolved (resolve-in (the-ns (:ns *env*)) sym)]
139+
(let [resolved (and (symbol? sym)
140+
(resolve-in (the-ns (:ns *env*)) sym))]
134141
(if (and resolved
135142
(macro? @resolved))
136143
(analyze-form (apply @resolved args))
@@ -145,6 +152,14 @@
145152
(defmethod analyze-form :number
146153
[x]
147154
{:op :const
155+
:type :number
156+
:form x
157+
:env *env*})
158+
159+
(defmethod analyze-form :keyword
160+
[x]
161+
{:op :const
162+
:type :keyword
148163
:form x
149164
:env *env*})
150165

@@ -156,9 +171,30 @@
156171
[x]
157172
(if-let [local (get-in *env* [:locals x])]
158173
local
159-
{:op :global
160-
:env *env*
161-
:form x}))
174+
(maybe-var x)))
175+
176+
(defmethod analyze-form :vector
177+
[x]
178+
(println "analyze " x)
179+
{:op :vector
180+
:children [:items]
181+
:items (mapv analyze-form x)
182+
:form x
183+
:env *env*})
184+
185+
(defn maybe-var [x]
186+
(let [resolved (resolve-in (the-ns (:ns *env*)) x)]
187+
(if resolved
188+
{:op :var
189+
:env *env*
190+
:ns (namespace resolved)
191+
:name (name resolved)
192+
:form x}
193+
{:op :var
194+
:env *env*
195+
:ns (name (:ns *env*))
196+
:name (name x)
197+
:form x})))
162198

163199

164200
;; ENV Functions
@@ -190,21 +226,25 @@
190226
(selector node))
191227
post))
192228

229+
(defn post-walk [f ast]
230+
(walk f identity :children ast))
231+
232+
(defn clean-do [ast]
233+
(post-walk
234+
(fn [{:keys [op statements ret] :as do}]
235+
(println ">-- " op (count statements))
236+
(if (and (= op :do)
237+
(= (count statements) 0))
238+
(do (println "reducing ") ret)
239+
ast))
240+
ast))
193241

194242
(defn remove-env [ast]
195243
(walk #(dissoc % :env)
196244
identity
197245
:children
198246
ast))
199247

200-
(let [form '((fn this [i max]
201-
(if (-lt i max)
202-
(this (-add i 1)
203-
max)
204-
i))
205-
1000)]
206-
(println (string-builder @(to-rpython (atom (string-builder)) 0 (remove-env (analyze form))))))
207-
208248
(defn write! [sb val]
209249
(swap! sb conj! val)
210250
sb)
@@ -214,6 +254,7 @@
214254
(write! sb " ")))
215255

216256
(defmulti to-rpython (fn [sb offset node]
257+
(println (:op node))
217258
(:op node)))
218259

219260
(defmethod to-rpython :if
@@ -223,7 +264,7 @@
223264
(let [offset (inc offset)]
224265
(doseq [[nm form] [[:test test]
225266
[:then then]
226-
[:else else]]]
267+
[:els else]]]
227268
(offset-spaces sb offset)
228269
(write! sb (name nm))
229270
(write! sb "=")
@@ -232,12 +273,129 @@
232273
(offset-spaces sb offset)
233274
(write! sb ")")))
234275

235-
(defmethod to-rpython :const
276+
(defmulti write-const (fn [sb offset const]
277+
(:type const)))
278+
279+
(defmethod write-const :keyword
236280
[sb offset {:keys [form]}]
237-
(write! sb "i.Const(rt.wrap(")
238-
(write! sb (str form))
239-
(write! sb "))"))
281+
(write! sb "kw(u\"")
282+
(when (namespace form)
283+
(write! sb (namespace form))
284+
(write! sb "/"))
285+
(write! sb (name form))
286+
(write! sb "\")"))
287+
288+
(defmethod to-rpython :const
289+
[sb offset ast]
290+
(write! sb "i.Const(")
291+
(write-const sb offset ast)
292+
(write! sb ")"))
293+
294+
(defmethod to-rpython :invoke
295+
[sb offset ast]
296+
(write! sb "i.Invoke(\n")
297+
(let [offset (inc offset)]
298+
(offset-spaces sb offset)
299+
(write! sb "args=[\n")
300+
(let [offset (inc offset)]
301+
(doseq [x `(~(:fn ast) ~@(:args ast))]
302+
(offset-spaces sb offset)
303+
(to-rpython sb offset x)
304+
(write! sb ",\n")))
305+
(offset-spaces sb offset)
306+
(write! sb "],\n"))
307+
(offset-spaces sb offset)
308+
(write! sb ")"))
309+
310+
311+
(defmethod to-rpython :do
312+
[sb offset {:keys [ret statements]}]
313+
(write! sb "i.Do(\n")
314+
(let [offset (inc offset)]
315+
(offset-spaces sb offset)
316+
(write! sb "args=[\n")
317+
(let [offset (inc offset)]
318+
(doseq [x `(~@statements ~ret)]
319+
(offset-spaces sb offset)
320+
(to-rpython sb offset x)
321+
(write! sb ",\n")))
322+
(offset-spaces sb offset)
323+
(write! sb "],\n"))
324+
(offset-spaces sb offset)
325+
(write! sb ")"))
326+
327+
328+
(defmethod to-rpython :fn
329+
[sb offset {:keys [name arities]}]
330+
(assert (= (count arities) 1))
331+
(to-rpython-fn-body sb offset name (nth arities 0)))
332+
333+
(defn to-rpython-fn-body
334+
[sb offset name {:keys [args body]}]
335+
(write! sb "i.Fn(args=[")
336+
(write! sb (->> args
337+
(map (fn [name]
338+
(str "kw(u\"" name "\")")))
339+
(interpose ",")
340+
(apply str)))
341+
(write! sb "],name=kw(u\"")
342+
(write! sb (str name))
343+
(write! sb "\"),\n")
344+
(let [offset (inc offset)]
345+
(offset-spaces sb offset)
346+
(write! sb "body=")
347+
(to-rpython sb offset body)
348+
(write! sb ",\n"))
349+
(offset-spaces sb offset)
350+
(write! sb ")"))
351+
352+
(defmethod to-rpython :var
353+
[sb offset {:keys [ns name]}]
354+
(write! sb "i.Const(code.intern_var(")
355+
(write! sb "u\"")
356+
(write! sb ns)
357+
(write! sb "\", u\"")
358+
(write! sb name)
359+
(write! sb "\"))"))
360+
361+
(defmethod to-rpython :binding
362+
[sb offset {:keys [name]}]
363+
(write! sb "i.Lookup(kw(u\"")
364+
(write! sb name)
365+
(write! sb "\"))"))
366+
367+
(defmethod to-rpython :def
368+
[sb offset {:keys [name env val]}]
369+
(write! sb "i.Invoke(args=[\n")
370+
(write! sb (str "# (def " (:ns env) "/" name ")\n"))
371+
(let [offset (inc offset)]
372+
(offset-spaces sb offset)
373+
(write! sb "i.Const(code.intern_var(u\"pixie.stdlib\", u\"set-var-root!\")),\n")
374+
(offset-spaces sb offset)
375+
(write! sb "i.Const(code.intern_var(u\"")
376+
(write! sb (:ns env))
377+
(write! sb "\",u\"")
378+
(write! sb name)
379+
(write! sb "\")),\n")
380+
(offset-spaces sb offset)
381+
(to-rpython sb offset val)
382+
(write! sb "])")
383+
))
384+
385+
(defmethod to-rpython :vector
386+
[sb offset {:keys [items]}]
387+
(write! sb "i.Invoke(args=[\n")
388+
(let [offset (inc offset)]
389+
(offset-spaces sb offset)
390+
(write! sb "i.Const(code.intern_var(u\"pixie.stdlib\", u\"vector\")),\n")
391+
(doseq [item items]
392+
(offset-spaces sb offset)
393+
(to-rpython sb offset item)
394+
(write! sb ",\n"))
395+
(offset-spaces sb offset)
396+
(write! sb "])")))
240397

241398

399+
(let [form '(do (deftype Cons [head tail meta]))]
400+
(println (string-builder @(to-rpython (atom (string-builder)) 0 (clean-do (analyze form))))))
242401

243-
(defmethod rpython-node)

pixie/vm2/interpreter.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,32 @@ def call_continuation(self, val, stack):
188188
stack = stack_cons(stack, InterpretK(ast._c_else, self._c_locals))
189189
else:
190190
stack = stack_cons(stack, InterpretK(ast._c_then, self._c_locals))
191-
return nil, stack
191+
return nil, stack
192+
193+
194+
class Do(AST):
195+
_immutable_fields_ = ["_c_body_asts"]
196+
def __init__(self, args, meta=nil):
197+
AST.__init__(self, meta)
198+
self._c_body_asts = args
199+
200+
@jit.unroll_safe
201+
def interpret(self, val, locals, stack):
202+
return val, stack_cons(stack, DoK(self._c_body_asts, locals))
203+
204+
205+
class DoK(Continuation):
206+
_immutable_ = True
207+
def __init__(self, do_asts, locals, idx=0):
208+
self._c_locals = locals
209+
self._c_body_asts = do_asts
210+
self._c_idx = idx
211+
212+
def call_continuation(self, val, stack):
213+
if self._c_idx + 1 < len(self._c_body_asts):
214+
stack = stack_cons(stack, DoK(self._c_body_asts, self._c_locals, self._c_idx + 1))
215+
stack = stack_cons(stack, InterpretK(self._c_body_asts[self._c_idx], self._c_locals))
216+
return nil, stack
217+
else:
218+
stack = stack_cons(stack, InterpretK(self._c_body_asts[self._c_idx], self._c_locals))
219+
return nil, stack

pixie/vm2/object.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ def run_stack(val, cont, stack=None):
152152
## TODO: fix
153153
def affirm(f, msg):
154154
if not f:
155+
print msg
155156
raise NotImplementedError()
156157

157158
def runtime_error(msg):

pixie/vm2/rt.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def wrapper(*args):
5151

5252
import pixie.vm2.code as code
5353
import pixie.vm2.numbers as numbers
54+
import pixie.vm2.stdlib
5455
#import pixie.vm.bits
5556
#import pixie.vm.interpreter
5657
#import pixie.vm.atom

target2.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,52 @@ def testit(max):
2323

2424
c = i.Invoke([f, i.Const(rt.wrap(0)), i.Const(rt.wrap(10))])
2525

26+
c = i.Do(
27+
args=[
28+
i.Invoke(args=[
29+
# (def user/it)
30+
i.Const(code.intern_var(u"pixie.stdlib", u"set-var-root!")),
31+
i.Const(code.intern_var(u"user", u"it")),
32+
i.Fn(args=[kw(u"i"),kw(u"max")],name=kw(u"this"),
33+
body=i.Do(
34+
args=[
35+
i.If(
36+
test=i.Invoke(
37+
args=[
38+
i.Const(code.intern_var(u"pixie.stdlib", u"-lt")),
39+
40+
i.Lookup(kw(u"i")),
41+
i.Lookup(kw(u"max")),
42+
],
43+
),
44+
then=i.Invoke(
45+
args=[
46+
i.Lookup(kw(u"this")),
47+
i.Invoke(
48+
args=[
49+
i.Const(code.intern_var(u"pixie.stdlib", u"-add")),
50+
i.Lookup(kw(u"i")),
51+
i.Const(rt.wrap(1)),
52+
],
53+
),
54+
i.Lookup(kw(u"max")),
55+
],
56+
),
57+
els=i.Lookup(kw(u"i")),
58+
),
59+
],
60+
),
61+
)]),
62+
i.Invoke(
63+
args=[
64+
i.Const(code.intern_var(u"user", u"it")),
65+
i.Const(rt.wrap(0)),
66+
i.Const(rt.wrap(1000)),
67+
],
68+
),
69+
],
70+
)
71+
2672

2773
return run_stack(None, i.InterpretK(c, None))
2874

@@ -122,4 +168,5 @@ def target(*args):
122168
print rpython.config.translationoption.get_combined_translation_config()
123169

124170
if __name__ == "__main__":
125-
run_debug(sys.argv)
171+
#run_debug(sys.argv)
172+
entry_point()

0 commit comments

Comments
 (0)