-
Notifications
You must be signed in to change notification settings - Fork 128
Expand file tree
/
Copy pathast-output.pxi
More file actions
124 lines (100 loc) · 3.36 KB
/
ast-output.pxi
File metadata and controls
124 lines (100 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
(ns pixie.ast-output
(:require [pixie.ast.internal :as iast]
[pixie.ast :as ast]))
(defprotocol ToNativeAST
(-to-ast [this]))
(defn meta-ast [ast]
(let [{:keys [line file line-number column-number] :as m} (or (meta (:form ast))
(:meta (:env ast)))
line (if (string? line)
line
(apply str @line))]
(iast/->Meta (or line
"<unknown>")
(or file
"<unknown>")
(or line-number -1)
(or column-number 1))))
(defn to-ast [this]
(-to-ast (simplify this)))
(extend-protocol ToNativeAST
ast/If
(-to-ast [{:keys [test then else] :as ast}]
(iast/->If (to-ast test)
(to-ast then)
(to-ast else)
(meta-ast ast)))
ast/Let
(-to-ast [{:keys [bindings body] :as ast}]
(iast/->Let (apply array (map #(keyword (name (:name %)))
bindings))
(apply array (map #(to-ast (:value %))
bindings))
(to-ast body)
(meta-ast ast)))
ast/Do
(-to-ast [{:keys [statements ret] :as ast}]
(let [args-array (make-array (inc (count statements)))]
(dotimes [idx (count statements)]
(aset args-array idx
(to-ast (nth statements idx))))
(aset args-array (count statements)
(to-ast ret))
(iast/->Do args-array
(meta-ast ast))))
ast/LetBinding
(-to-ast
[{:keys [name] :as ast}]
(iast/->Lookup (keyword (pixie.stdlib/name name))
(meta-ast ast)))
ast/Const
(-to-ast [{:keys [form] :as ast}]
(iast/->Const form (meta-ast ast)))
ast/Invoke
(-to-ast [{:keys [args env] :as ast}]
(let [args-array (make-array (count args))]
(dotimes [idx (count args)]
(aset args-array idx
(to-ast (nth args idx))))
(iast/->Invoke args-array
(meta-ast ast))))
ast/Recur
(-to-ast [{:keys [args env] :as ast}]
(let [args-array (make-array (count args))]
(dotimes [idx (count args)]
(aset args-array idx
(to-ast (nth args idx))))
(iast/->Recur args-array
(meta-ast ast))))
ast/Var
(-to-ast [{:keys [ns var-name] :as ast}]
(iast/->VDeref (name ns)
var-name
(meta-ast ast)))
ast/VarConst
(-to-ast [{:keys [ns name env] :as ast}]
(iast/->VarConst ns
name
(meta-ast ast)))
ast/FnBody
(-to-ast [{:keys [name args body] :as ast}]
(iast/->Fn (keyword (pixie.stdlib/name name))
(to-array (map (fn [x]
(keyword (pixie.stdlib/name x)))
args))
(to-ast body)
(meta-ast ast)))
ast/Binding
(-to-ast [{:keys [name] :as ast}]
(iast/->Lookup (keyword (pixie.stdlib/name name))
(meta-ast ast)))
Object
(-to-ast [this]
(println "Encoding" this "of type" (type this))
(throw [:pixie.stdlib/IllegalArgumentException
(str "Can't encode " this)])))
(defn simplify [ast]
(let [simplified (ast/simplify-ast ast)]
(if (identical? simplified ast)
ast
(simplify simplified))))