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 }