Mercurial > repos > icfp2014
comparison code/lmc.tp @ 9:526bec3b2090
Function call and lambda expression support. Fix ABI for main function. Use main definition for number of args rather than assuming 2 of them.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 25 Jul 2014 14:45:55 -0700 |
parents | 494ef2e3a756 |
children | 66d0858692a9 |
comparison
equal
deleted
inserted
replaced
8:494ef2e3a756 | 9:526bec3b2090 |
---|---|
174 prog add: (inst: "CEQ" #[]) | 174 prog add: (inst: "CEQ" #[]) |
175 } | 175 } |
176 | 176 |
177 _exprHandlers set: (ast call) :expr syms { | 177 _exprHandlers set: (ast call) :expr syms { |
178 tc <- (expr tocall) | 178 tc <- (expr tocall) |
179 normal <- true | |
179 if: (tc nodeType) = (ast sym) { | 180 if: (tc nodeType) = (ast sym) { |
180 _funHandlers ifget: (tc name) :handler { | 181 _funHandlers ifget: (tc name) :handler { |
181 handler: (expr args) syms | 182 handler: (expr args) syms |
183 normal <- false | |
182 } else: { | 184 } else: { |
183 error: "function calls not implemented yet" | 185 } |
184 } | 186 } |
185 } else: { | 187 if: normal { |
186 error: "call expression to value not implemented yet - " . tc | 188 compileExpr: tc syms: syms |
189 num <- 0 | |
190 foreach: (expr args) :idx arg { | |
191 compileExpr: arg syms: syms | |
192 num <- num + 1 | |
193 } | |
194 prog add: (inst: "AP" #[num]) | |
187 } | 195 } |
188 } | 196 } |
189 | 197 |
190 _exprHandlers set: (ast sym) :expr syms { | 198 _exprHandlers set: (ast sym) :expr syms { |
191 syms ifDefined: (expr name) :info { | 199 syms ifDefined: (expr name) :info { |
210 ]) | 218 ]) |
211 } else: { | 219 } else: { |
212 error: "symbol " . (sym name) . " is not defined" | 220 error: "symbol " . (sym name) . " is not defined" |
213 } | 221 } |
214 } | 222 } |
223 | |
224 compileLambda:syms <- :fname fun :syms { | |
225 prog setLabel: fname | |
226 argsyms <- symbols tableWithParent: syms | |
227 foreach: (fun args) :idx el { | |
228 argsyms define: (if: (el startsWith?: ":") { el from: 1 } else: { el }) idx | |
229 } | |
230 | |
231 slot <- 0 | |
232 locsyms <- symbols tableWithParent: argsyms | |
233 foreach: (fun expressions) :idx expr { | |
234 if: (expr nodeType) = (ast assignment) { | |
235 locsyms ifDefined: ((expr to) name) :sym { | |
236 //already defined, nothing to do here | |
237 } else: { | |
238 locsyms define: ((expr to) name) slot | |
239 slot <- slot + 1 | |
240 } | |
241 } | |
242 } | |
243 fsyms <- if: slot > 0 { | |
244 //allocate frame for locals | |
245 prog add: (inst: "DUM" #[slot]) | |
246 i <- 0 | |
247 while: { i < slot } do: { | |
248 prog add: (inst: "LDC" #[0]) | |
249 i <- i + 1 | |
250 } | |
251 prologue_end <- prog makeLabel: fname . "_real" | |
252 prog add: (inst: "LDF" #[prologue_end]) | |
253 prog add: (inst: "TRAP" #[slot]) | |
254 prog setLabel: prologue_end | |
255 locsyms | |
256 } else: { argsyms } | |
257 | |
258 foreach: (fun expressions) :idx expr { | |
259 compileExpr: expr syms: fsyms | |
260 } | |
261 prog add: (inst: "RTN" #[]) | |
262 } | |
263 | |
264 _exprHandlers set: (ast lambda) :expr syms { | |
265 fname <- prog makeLabel: "lambda" | |
266 end <- prog makeLabel: "lambda_end" | |
267 prog add: (inst: "LDC" #[1]) | |
268 prog add: (inst: "TSEL" #[ | |
269 end | |
270 end | |
271 ]) | |
272 compileLambda: fname expr syms: syms | |
273 prog setLabel: end | |
274 } | |
215 #{ | 275 #{ |
216 compile <- :code { | 276 compile <- :code { |
217 res <- parser top: code | 277 res <- parser top: code |
218 if: res { | 278 if: res { |
219 outer <- res yield | 279 outer <- res yield |
222 num <- (outer messages) length | 282 num <- (outer messages) length |
223 syms <- symbols table | 283 syms <- symbols table |
224 | 284 |
225 prog add: (inst: "DUM" #[num]) | 285 prog add: (inst: "DUM" #[num]) |
226 slot <- 0 | 286 slot <- 0 |
287 mainArgs <- 0 | |
227 foreach: (outer messages) :idx msg { | 288 foreach: (outer messages) :idx msg { |
228 if: (msg nodeType) = (ast assignment) { | 289 if: (msg nodeType) = (ast assignment) { |
229 def <- msg assign | 290 def <- msg assign |
230 sym <- (msg to) name | 291 sym <- (msg to) name |
231 | 292 |
232 if: (def nodeType) = (ast lambda) { | 293 if: (def nodeType) = (ast lambda) { |
233 prog add: (inst: "LDF" #[sym]) | 294 prog add: (inst: "LDF" #[sym]) |
234 functions set: sym def | 295 functions set: sym def |
296 if: sym = "main" { | |
297 mainArgs <- (def args) length | |
298 } | |
235 } else: { | 299 } else: { |
236 compileExpr: def syms: syms | 300 compileExpr: def syms: syms |
237 } | 301 } |
238 syms define: sym slot | 302 syms define: sym slot |
239 slot <- slot + 1 | 303 slot <- slot + 1 |
243 } | 307 } |
244 after_env <- prog makeLabel: "after_env" | 308 after_env <- prog makeLabel: "after_env" |
245 prog add: (inst: "LDF" #[after_env]) | 309 prog add: (inst: "LDF" #[after_env]) |
246 prog add: (inst: "TRAP" #[num]) | 310 prog add: (inst: "TRAP" #[num]) |
247 prog setLabel: after_env | 311 prog setLabel: after_env |
312 | |
313 i <- 0 | |
314 while: { i < mainArgs } do: { | |
315 prog add: (inst: "LD" #[ | |
316 0 | |
317 i | |
318 ]) | |
319 i <- i + 1 | |
320 } | |
321 | |
248 prog add: (inst: "LDF" #["main"]) | 322 prog add: (inst: "LDF" #["main"]) |
249 prog add: (inst: "TAP" #[2]) | 323 prog add: (inst: "TAP" #[mainArgs]) |
250 | 324 |
251 foreach: functions :fname fun { | 325 foreach: functions :fname fun { |
252 prog setLabel: fname | 326 compileLambda: fname fun syms: syms |
253 argsyms <- symbols tableWithParent: syms | |
254 foreach: (fun args) :idx el { | |
255 argsyms define: (if: (el startsWith?: ":") { el from: 1 } else: { el }) idx | |
256 } | |
257 | |
258 slot <- 0 | |
259 locsyms <- symbols tableWithParent: argsyms | |
260 foreach: (fun expressions) :idx expr { | |
261 if: (expr nodeType) = (ast assignment) { | |
262 locsyms ifDefined: ((expr to) name) :sym { | |
263 //already defined, nothing to do here | |
264 } else: { | |
265 locsyms define: ((expr to) name) slot | |
266 slot <- slot + 1 | |
267 } | |
268 } | |
269 } | |
270 fsyms <- if: slot > 0 { | |
271 //allocate frame for locals | |
272 prog add: (inst: "DUM" #[slot]) | |
273 i <- 0 | |
274 while: { i < slot } do: { | |
275 prog add: (inst: "LDC" #[0]) | |
276 i <- i + 1 | |
277 } | |
278 prologue_end <- prog makeLabel: fname . "_real" | |
279 prog add: (inst: "LDF" #[prologue_end]) | |
280 prog add: (inst: "TRAP" #[slot]) | |
281 prog setLabel: prologue_end | |
282 locsyms | |
283 } else: { argsyms } | |
284 | |
285 foreach: (fun expressions) :idx expr { | |
286 compileExpr: expr syms: fsyms | |
287 } | |
288 prog add: (inst: "RTN" #[]) | |
289 } | 327 } |
290 print: prog | 328 print: prog |
291 } else: { | 329 } else: { |
292 error: "Parse failed!" | 330 error: "Parse failed!" |
293 } | 331 } |