|
4 | 4 | (:import [org.antlr.v4.runtime.tree TerminalNodeImpl] |
5 | 5 | [mini_java.antlr MiniJavaParser])) |
6 | 6 |
|
| 7 | +(defn- node-line-and-column [node] |
| 8 | + (let [token (.getStart node)] |
| 9 | + (util/token-line-and-column token))) |
| 10 | + |
| 11 | +(defn- with-line-and-column [node ctx obj] |
| 12 | + (let [[line column] (node-line-and-column node)] |
| 13 | + (with-meta obj |
| 14 | + {:line line |
| 15 | + :column column |
| 16 | + :context ctx}))) |
| 17 | + |
| 18 | +(defn context [node] |
| 19 | + (:context (meta node))) |
| 20 | + |
7 | 21 | (def ^{:private true} parser-inner-classes |
8 | 22 | (.getClasses MiniJavaParser)) |
9 | 23 |
|
|
24 | 38 | (assoc (into {} (map (comp vec reverse typeify) parser-inner-classes)) |
25 | 39 | TerminalNodeImpl :terminal-node)) |
26 | 40 |
|
| 41 | +(def ^{:private true} obj-type-key |
| 42 | + (comp type->key type)) |
27 | 43 |
|
28 | 44 | (defn- children [node] |
29 | 45 | (map #(.getChild node %) (range (.getChildCount node)))) |
|
40 | 56 | (defn- method-declaration? [[k v]] |
41 | 57 | (= k :method-declaration)) |
42 | 58 |
|
43 | | -(defmulti ast (comp type->key type)) |
| 59 | +(defmulti ast obj-type-key) |
44 | 60 |
|
45 | 61 | (defmethod ast :default [node] |
46 | 62 | [(type->key (type node)), node]) |
|
54 | 70 | (let [children (children node) |
55 | 71 | main-class (first children) |
56 | 72 | classes (-> children rest butlast)] |
57 | | - {:main (ast main-class), |
58 | | - :classes (map ast classes)})) |
| 73 | + (with-line-and-column node :goal |
| 74 | + {:main (ast main-class), |
| 75 | + :classes (map ast classes)}))) |
59 | 76 |
|
60 | 77 | (defmethod ast :main-class-declaration [node] |
61 | | - {:name (ast (.getChild node 1)), |
62 | | - :body (ast (.getChild node 2))}) |
| 78 | + (with-line-and-column node :main-class-declaration |
| 79 | + {:name (ast (.getChild node 1)), |
| 80 | + :body (ast (.getChild node 2))})) |
63 | 81 |
|
64 | 82 | (defmethod ast :class-declaration [node] |
65 | 83 | (let [child? (= 5 (.getChildCount node)) |
66 | 84 | body-idx (if child? 4 2) |
67 | 85 | {:keys [vars methods]} (ast (.getChild node body-idx))] |
68 | | - {:name (ast (.getChild node 1)), |
69 | | - :parent (when child? (ast (.getChild node 3))), |
70 | | - :vars (map remove-type vars), |
71 | | - :methods (map remove-type methods)})) |
| 86 | + (with-line-and-column node :class-declaration |
| 87 | + {:name (ast (.getChild node 1)), |
| 88 | + :parent (when child? (ast (.getChild node 3))), |
| 89 | + :vars (map remove-type vars), |
| 90 | + :methods (map remove-type methods)}))) |
72 | 91 |
|
73 | 92 | (defmethod ast :main-class-body [node] |
74 | 93 | (ast (.getChild node 1))) |
|
81 | 100 | declarations (map ast (remove-braces children)) |
82 | 101 | vars (filter var-declaration? declarations) |
83 | 102 | methods (filter method-declaration? declarations)] |
84 | | - {:vars vars, |
85 | | - :methods methods})) |
| 103 | + (with-line-and-column node :class-body |
| 104 | + {:vars vars, |
| 105 | + :methods methods}))) |
86 | 106 |
|
87 | 107 | (defmethod ast :method-declaration [node] |
88 | 108 | (let [{:keys [vars statements]} (ast (.getChild node 4))] |
89 | 109 | [:method-declaration, |
90 | | - {:name (ast (.getChild node 2)), |
91 | | - :type (ast (.getChild node 1)), |
92 | | - :args (ast (.getChild node 3)), |
93 | | - :vars vars, |
94 | | - :statements statements}])) |
| 110 | + (with-line-and-column node :method-declaration |
| 111 | + {:name (ast (.getChild node 2)), |
| 112 | + :type (ast (.getChild node 1)), |
| 113 | + :args (ast (.getChild node 3)), |
| 114 | + :vars vars, |
| 115 | + :statements statements})])) |
95 | 116 |
|
96 | 117 | (defmethod ast :method-body [node] |
97 | 118 | (let [children (remove-braces (children node)) |
98 | 119 | body-nodes (map ast children)] |
99 | | - {:vars (map remove-type (filter var-declaration? body-nodes)) |
100 | | - :statements (filter (comp not var-declaration?) body-nodes)})) |
| 120 | + (with-line-and-column node :method-body |
| 121 | + {:vars (map remove-type (filter var-declaration? body-nodes)) |
| 122 | + :statements (filter (comp not var-declaration?) body-nodes)}))) |
101 | 123 |
|
102 | 124 | (defmethod ast :var-declaration [node] |
103 | 125 | [:var-declaration, |
104 | | - {:name (ast (.getChild node 1)), |
105 | | - :type (ast (.getChild node 0))}]) |
| 126 | + (with-line-and-column node :var-declaration |
| 127 | + {:name (ast (.getChild node 1)), |
| 128 | + :type (ast (.getChild node 0))})]) |
106 | 129 |
|
107 | 130 | (defmethod ast :nested-statement [node] |
108 | 131 | [:nested-statement, |
109 | | - (->> node |
110 | | - children |
111 | | - remove-braces |
112 | | - (map ast))]) |
| 132 | + (with-line-and-column node :nested-statement |
| 133 | + (->> node |
| 134 | + children |
| 135 | + remove-braces |
| 136 | + (map ast)))]) |
113 | 137 |
|
114 | 138 | (defmethod ast :if-else-statement [node] |
115 | 139 | [:if-else-statement |
116 | | - {:pred (ast (.getChild node 2)), |
117 | | - :then (ast (.getChild node 4)), |
118 | | - :else (ast (.getChild node 6))}]) |
| 140 | + (with-line-and-column node :if-else-statement |
| 141 | + {:pred (ast (.getChild node 2)), |
| 142 | + :then (ast (.getChild node 4)), |
| 143 | + :else (ast (.getChild node 6))})]) |
119 | 144 |
|
120 | 145 | (defmethod ast :while-statement [node] |
121 | 146 | [:while-statement, |
122 | | - {:pred (ast (.getChild node 2)), |
123 | | - :body (ast (.getChild node 4))}]) |
| 147 | + (with-line-and-column node :while-statement |
| 148 | + {:pred (ast (.getChild node 2)), |
| 149 | + :body (ast (.getChild node 4))})]) |
124 | 150 |
|
125 | 151 | (defmethod ast :print-statement [node] |
126 | 152 | [:print-statement, |
127 | | - (ast (.getChild node 2))]) |
| 153 | + (with-line-and-column node :print-statement |
| 154 | + {:arg (ast (.getChild node 2))})]) |
128 | 155 |
|
129 | 156 | (defmethod ast :assign-statement [node] |
130 | 157 | [:assign-statement, |
131 | | - {:target (ast (.getChild node 0)), |
132 | | - :source (ast (.getChild node 2))}]) |
| 158 | + (with-line-and-column node :assign-statement |
| 159 | + {:target (ast (.getChild node 0)), |
| 160 | + :source (ast (.getChild node 2))})]) |
133 | 161 |
|
134 | 162 | (defmethod ast :array-assign-statement [node] |
135 | 163 | [:array-assign-statement, |
136 | | - {:target (ast (.getChild node 0)), |
137 | | - :index (ast (.getChild node 2)), |
138 | | - :source (ast (.getChild node 5))}]) |
| 164 | + (with-line-and-column node :array-assign-statement |
| 165 | + {:target (ast (.getChild node 0)), |
| 166 | + :index (ast (.getChild node 2)), |
| 167 | + :source (ast (.getChild node 5))})]) |
139 | 168 |
|
140 | 169 | (defmethod ast :return-statement [node] |
141 | 170 | [:return-statement, |
142 | | - (ast (.getChild node 1))]) |
| 171 | + (with-line-and-column node :return-statement |
| 172 | + {:return-value (ast (.getChild node 1))})]) |
143 | 173 |
|
144 | 174 | (defmethod ast :recur-statement [node] |
145 | 175 | [:recur-statement, |
146 | | - {:pred (ast (.getChild node 1)), |
147 | | - :args (ast (.getChild node 3)), |
148 | | - :base (ast (.getChild node 5))}]) |
149 | | - |
150 | | - |
151 | | - |
| 176 | + (with-line-and-column node :recur-statement |
| 177 | + {:pred (ast (.getChild node 1)), |
| 178 | + :args (ast (.getChild node 3)), |
| 179 | + :base (ast (.getChild node 5))})]) |
152 | 180 |
|
153 | 181 | (defmethod ast :method-argument-list [node] |
154 | 182 | (let [children (children node) |
155 | 183 | args (take-nth 2 (-> children rest butlast))] |
156 | | - (map ast args))) |
| 184 | + (with-line-and-column node :method-argument-list |
| 185 | + (map ast args)))) |
157 | 186 |
|
158 | 187 | (defmethod ast :formal-parameters [node] |
159 | | - (let [length (.getChildCount node)] |
160 | | - (if (= 3 length) |
161 | | - (ast (.getChild node 1)) |
162 | | - []))) |
| 188 | + (with-line-and-column node :formal-parameters |
| 189 | + (let [length (.getChildCount node)] |
| 190 | + (if (= 3 length) |
| 191 | + (ast (.getChild node 1)) |
| 192 | + [])))) |
163 | 193 |
|
164 | 194 | (defmethod ast :formal-parameter-list [node] |
165 | 195 | (->> node |
|
168 | 198 | (map ast))) |
169 | 199 |
|
170 | 200 | (defmethod ast :formal-parameter [node] |
171 | | - {:type (ast (.getChild node 0)), |
172 | | - :name (ast (.getChild node 1))}) |
| 201 | + (with-line-and-column node :formal-parameter |
| 202 | + {:type (ast (.getChild node 0)), |
| 203 | + :name (ast (.getChild node 1))})) |
173 | 204 |
|
174 | 205 |
|
175 | 206 | (defmethod ast :type [node] |
176 | 207 | (ast (.getChild node 0))) |
177 | 208 |
|
178 | 209 | (defn- unary-expression [node] |
179 | | - (ast (.getChild node 1))) |
| 210 | + (with-line-and-column node (obj-type-key node) |
| 211 | + {:operand (ast (.getChild node 1))})) |
180 | 212 |
|
181 | 213 | (defn- binary-expression [node] |
182 | | - {:left (ast (.getChild node 0)), |
183 | | - :right (ast (.getChild node 2))}) |
| 214 | + (with-line-and-column node (obj-type-key node) |
| 215 | + {:left (ast (.getChild node 0)), |
| 216 | + :right (ast (.getChild node 2))})) |
184 | 217 |
|
185 | 218 | (defmethod ast :and-expression [node] |
186 | 219 | [:and-expression, |
|
204 | 237 |
|
205 | 238 | (defmethod ast :array-access-expression [node] |
206 | 239 | [:array-access-expression, |
207 | | - {:array (ast (.getChild node 0)), |
208 | | - :index (ast (.getChild node 2))}]) |
| 240 | + (with-line-and-column node :array-access-expression |
| 241 | + {:array (ast (.getChild node 0)), |
| 242 | + :index (ast (.getChild node 2))})]) |
209 | 243 |
|
210 | 244 | (defmethod ast :array-length-expression [node] |
211 | 245 | [:array-length-expression, |
212 | | - (ast (.getChild node 0))]) |
| 246 | + (with-line-and-column node :array-length-expression |
| 247 | + (ast (.getChild node 0)))]) |
213 | 248 |
|
214 | 249 | (defmethod ast :method-call-expression [node] |
215 | 250 | [:method-call-expression, |
216 | | - {:caller (ast (.getChild node 0)), |
217 | | - :method (ast (.getChild node 2)), |
218 | | - :args (ast (.getChild node 3))}]) |
| 251 | + (with-line-and-column node :method-call-expression |
| 252 | + {:caller (ast (.getChild node 0)), |
| 253 | + :method (ast (.getChild node 2)), |
| 254 | + :args (ast (.getChild node 3))})]) |
219 | 255 |
|
220 | 256 | (defmethod ast :int-lit-expression [node] |
221 | 257 | [:int-lit-expression, |
222 | | - (-> node |
223 | | - (.getChild 0) |
224 | | - ast |
225 | | - Integer.)]) |
| 258 | + (with-line-and-column node :int-lit-expression |
| 259 | + {:value (-> node |
| 260 | + (.getChild 0) |
| 261 | + ast |
| 262 | + Integer.)})]) |
226 | 263 |
|
227 | 264 | (defmethod ast :boolean-expression [node] |
228 | 265 | [:boolean-expression, |
229 | | - (-> node |
230 | | - (.getChild 0) |
231 | | - ast |
232 | | - Boolean.)]) |
| 266 | + (with-line-and-column node :boolean-expression |
| 267 | + {:value (-> node |
| 268 | + (.getChild 0) |
| 269 | + ast |
| 270 | + Boolean.)})]) |
233 | 271 |
|
234 | 272 | (defmethod ast :identifier-expression [node] |
235 | 273 | [:identifier-expression, |
236 | | - (ast (.getChild node 0))]) |
| 274 | + (with-line-and-column node :identifier-expression |
| 275 | + {:id (ast (.getChild node 0))})]) |
237 | 276 |
|
238 | 277 | (defmethod ast :this-expression [node] |
239 | 278 | :this) |
240 | 279 |
|
241 | 280 | (defmethod ast :array-instantiation-expression [node] |
242 | 281 | [:array-instantiation-expression, |
243 | | - (ast (.getChild node 3))]) |
| 282 | + (with-line-and-column node :array-instantiation-expression |
| 283 | + {:size (ast (.getChild node 3))})]) |
244 | 284 |
|
245 | 285 | (defmethod ast :object-instantiation-expression [node] |
246 | 286 | [:object-instantiation-expression, |
247 | | - (ast (.getChild node 1))]) |
| 287 | + (with-line-and-column node :object-instantiation-expression |
| 288 | + {:type (ast (.getChild node 1))})]) |
248 | 289 |
|
249 | 290 | (defmethod ast :not-expression [node] |
250 | 291 | [:not-expression, |
|
0 commit comments