Mercurial > repos > tabletprog
comparison modules/llcompile.tp @ 360:0b83f15e819d
Update llcompile for changes to llFun syntax
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 21 Apr 2015 09:00:56 -0700 |
parents | f237d0cae58b |
children | 06dceff348ea |
comparison
equal
deleted
inserted
replaced
359:023c29e1f595 | 360:0b83f15e819d |
---|---|
312 } | 312 } |
313 } | 313 } |
314 } | 314 } |
315 | 315 |
316 _compileAssign <- :expr syms ilf assignTo { | 316 _compileAssign <- :expr syms ilf assignTo { |
317 dest <- _compileExpr: (expr to) syms: syms ilfun: ilf dest: (option none) | 317 dest <- ((expr to) type) value: :typeexpr { |
318 type <- _parseType: typeexpr | |
319 _notError: [type] { | |
320 syms define: ((expr to) name) #{ | |
321 val <- ilf getReg | |
322 size <- type size | |
323 signed? <- type signed? | |
324 } | |
325 } | |
326 } none: { | |
327 _compileExpr: (expr to) syms: syms ilfun: ilf dest: (option none) | |
328 } | |
318 _notError: [dest] { | 329 _notError: [dest] { |
319 value <- _compileExpr: (expr assign) syms: syms ilfun: ilf dest: dest | 330 value <- _compileExpr: (expr assign) syms: syms ilfun: ilf dest: dest |
320 _notError: [value] { | 331 _notError: [value] { |
321 //TODO: adjust size of value if necessary | 332 //TODO: adjust size of value if necessary |
322 //ilf add: (il mov: (value val) (dest val) (dest size)) | 333 //ilf add: (il mov: (value val) (dest val) (dest size)) |
375 _funMap set: "if:else" _compileIfElse | 386 _funMap set: "if:else" _compileIfElse |
376 //_funMap set: "while:do" _compileWhileDo | 387 //_funMap set: "while:do" _compileWhileDo |
377 } | 388 } |
378 } | 389 } |
379 | 390 |
380 llFun:syms:vars:code <- :name :syms :vars :code{ | 391 llFun:syms:code:returns <- :name :syms :code :returnType{ |
381 _initHandlers: | 392 _initHandlers: |
382 syms <- symbols tableWithParent: syms | 393 syms <- symbols tableWithParent: syms |
383 argnames <- dict hash | 394 |
384 foreach: (code args) :idx arg { | 395 rType <- _parseType: returnType |
385 if: (arg startsWith?: ":") { | 396 _notError: [rType] { |
386 arg <- arg from: 1 | 397 argErrors <- [] |
387 } | 398 foreach: (code args) :argnum argsym { |
388 argnames set: arg idx | 399 (argsym type) value: :typeexpr { |
389 } | 400 type <- _parseType: typeexpr |
390 ilf <- _ilFun: name | 401 _notError: [type] { |
391 _nextReg <- 0 | 402 arg <- argsym name |
392 varErrors <- (vars expressions) fold: [] with: :acc var { | 403 if: (arg startsWith?: ":") { |
393 type <- _parseType: (var assign) | 404 arg <- arg from: 1 |
394 _notError: [type] { | 405 } |
395 varname <- ((var to) name) | 406 syms define: arg #{ |
396 v <- argnames ifget: varname :argnum { | 407 val <- il arg: argnum |
397 il arg: argnum | 408 size <- type size |
398 } else: { | 409 signed? <- type signed? |
399 ilf getReg | 410 } |
400 } | 411 } else: :err { |
401 syms define: varname #{ | 412 argErrors <- err | argErrors |
402 val <- v | 413 } |
403 size <- (type size) | 414 } none: { |
404 signed? <- (type signed?) | 415 argErrors <- (_compileError: "Arguments to llFun must have type declarations" 0) | argErrors |
405 } | 416 } |
406 acc | 417 } |
407 } else: :err { | 418 |
408 err | acc | 419 |
409 } | 420 |
410 } | 421 |
411 if: (varErrors empty?) { | 422 if: (argErrors empty?) { |
412 last <- option none | 423 ilf <- _ilFun: name |
413 numexprs <- (code expressions) length | 424 last <- option none |
414 foreach: (code expressions) :idx expr { | 425 numexprs <- (code expressions) length |
415 asn <- if: idx = numexprs - 1 { | 426 foreach: (code expressions) :idx expr { |
416 option value: #{ | 427 asn <- if: idx = numexprs - 1 { |
417 val <- ilf getReg | 428 option value: #{ |
418 //TODO: FIxme | 429 val <- ilf getReg |
419 size <- il q | 430 //TODO: FIxme |
420 signed? <- true | 431 size <- il q |
421 } | 432 signed? <- true |
422 } else: { | 433 } |
423 option none | 434 } else: { |
424 } | 435 option none |
425 last <- option value: (_compileExpr: expr syms: syms ilfun: ilf dest: asn) | 436 } |
426 } | 437 last <- option value: (_compileExpr: expr syms: syms ilfun: ilf dest: asn) |
427 last value: :v { | 438 } |
428 ilf add: (il return: (v val) (v size)) | 439 last value: :v { |
429 } none: { | 440 ilf add: (il return: (v val) (v size)) |
430 ilf add: (il return: 0 (il l)) | 441 } none: { |
431 } | 442 ilf add: (il return: 0 (il l)) |
432 ilf | 443 } |
433 } else: { | 444 ilf |
434 varErrors | 445 } else: { |
446 argErrors | |
447 } | |
435 } | 448 } |
436 } | 449 } |
437 | 450 |
438 compileText <- :text { | 451 compileText <- :text { |
439 res <- parser top: text | 452 res <- parser top: text |
441 tree <- res yield | 454 tree <- res yield |
442 if: (tree nodeType) = obj { | 455 if: (tree nodeType) = obj { |
443 errors <- [] | 456 errors <- [] |
444 syms <- symbols table | 457 syms <- symbols table |
445 functions <- (tree messages) fold: [] with: :curfuncs msg { | 458 functions <- (tree messages) fold: [] with: :curfuncs msg { |
446 if: (msg nodeType) = call { | 459 if: (msg nodeType) = assignment { |
447 if: ((msg tocall) name) = "llFun:withVars:andCode" { | 460 def <- msg assign |
448 if: ((msg args) length) = 3 { | 461 if: (def nodeType) = call { |
449 fname <- ((msg args) value) name | 462 if: ((def tocall) name) = "llFun:returns" { |
450 syms define: fname #{ | 463 if: ((def args) length) = 2 { |
451 type <- "topfun" | 464 fname <- (msg to) name |
465 syms define: fname #{ | |
466 type <- "topfun" | |
467 } | |
468 #{ | |
469 name <- fname | |
470 body <- (def args) value | |
471 returnType <- ((def args) tail) value | |
472 } | curfuncs | |
473 } else: { | |
474 errors <- ( | |
475 _compileError: "llFun:returns takes exactly 2 arguments" 0 | |
476 ) | errors | |
477 curfuncs | |
452 } | 478 } |
453 rest <- (msg args) tail | |
454 #{ | |
455 name <- fname | |
456 vars <- rest value | |
457 body <- (rest tail) value | |
458 } | curfuncs | |
459 } else: { | 479 } else: { |
460 errors <- ( | 480 errors <- ( |
461 _compileError: "llFun:withVars:andCode takes exactly 3 arguments" 0 | 481 _compileError: "Top level definitions must be a call to llFun:returns" 0 |
462 ) | errors | 482 ) | errors |
463 curfuncs | 483 curfuncs |
464 } | 484 } |
465 } else: { | 485 } else: { |
466 errors <- ( | 486 errors <- ( |
467 _compileError: "Only llFun:withVars:andCode expressions are allowed in top level object" 0 | 487 _compileError: "Right side of top-level assignment must be a call expression" 0 |
468 ) | errors | 488 ) | errors |
469 curfuncs | 489 curfuncs |
470 } | 490 } |
471 } else: { | 491 } else: { |
472 errors <- ( | 492 errors <- ( |
473 _compileError: "Only call expresions are allowed in top level object" 0 | 493 _compileError: "Only assignment expresions are allowed in top level object" 0 |
474 ) | errors | 494 ) | errors |
475 curfuncs | 495 curfuncs |
476 } | 496 } |
477 } | 497 } |
478 if: (errors empty?) { | 498 if: (errors empty?) { |
479 errors <- [] | 499 errors <- [] |
480 fmap <- functions fold: (dict hash) with: :acc func { | 500 fmap <- functions fold: (dict hash) with: :acc func { |
481 ilf <- llFun: (func name) syms: syms vars: (func vars) code: (func body) | 501 ilf <- llFun: (func name) syms: syms code: (func body) returns: (func returnType) |
482 _notError: ilf { | 502 _notError: ilf { |
483 acc set: (func name) (ilf buffer) | 503 acc set: (func name) (ilf buffer) |
484 } else: { | 504 } else: { |
485 errors <- ilf . errors | 505 errors <- ilf . errors |
486 } | 506 } |