Mercurial > repos > tabletprog
view modules/ast.tp @ 251:2557ce4e671f
Fix a couple of compiler bugs. topenv was getting initialized in multiple places. This resulted in multiple copies of modules getting created which caused problems for macro expansion. Additionally, arguments were not being marked as declared during code generation so assigning to an argument that was not closed over generated invalid C code.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 11 Apr 2014 22:29:32 -0700 |
parents | b76f683d076e |
children | 004946743678 |
line wrap: on
line source
{ _binary <- 0 _string <- 1 _int <- 2 _symbol <- 3 _call <- 4 _object <- 5 _sequence <- 6 _assignment <- 7 _lambda <- 8 #{ binary <- { _binary } stringlit <- { _string } intlit <- { _int } sym <- { _symbol } call <- { _call } obj <- { _object } sequence <- { _sequence } assignment <- { _assignment } lambda <- { _lambda } binaryOp:withArgs <- :opname :_left _right { #{ nodeType <- { _binary } left <- _left op <- opname right <- _right leftAssociative? <- { op != "|" } stringIndent <- :indent { (left stringIndent: indent) . " " . op . (right stringIndent: indent) } string <- { stringIndent: "" } } } stringLit <- :_val { #{ nodeType <- { _string } val <- _val stringIndent <- :indent { "\"" . val . "\"" } string <- { stringIndent: "" } } } intLit:withBits:andBase:signed? <- :_val :_bits :_base :_signed? { #{ nodeType <- { _int } val <- _val base <- _base bits <- _bits signed? <- _signed? stringIndent <- :indent { suffix <- "" if: bits != 32 || (not: signed?) { suffix <- (if: signed? {"i"} else: {"u"}) . bits } if: base = 16 { "0x" . (hex: val) . suffix } else: { if: base = 2 { str <- "0b" i <- bits - 1 printzero <- false while: { i >= 0 } do: { str <- str . (if: (lshift: 1 by: i) and val > 0 { printzero <- true "1" } else: { if: printzero {"0"} else: {""} }) i <- i - 1 } str . suffix } else: { (string: val) . suffix } } } string <- { stringIndent: "" } } } symbol <- :_name { #{ nodeType <- { _symbol } name <- _name stringIndent <- :indent { name } string <- { stringIndent: "" } } } funcall:withArgs:hasReceiver? <- :_tocall :_args :_receiver? { #{ tocall <- _tocall args <- _args hasReceiver? <- _receiver? stringIndent <- :indent { argparts <- [] if: (tocall nodeType) = _symbol { argparts <- (tocall name) splitOn: ":" } else: { argparts <- [tocall stringIndent: indent] } curarg <- args str <- "" if: hasReceiver? { str <- ((curarg value) stringIndent: indent) . " " curarg <- curarg tail } foreach: argparts :idx part { str <- str . part . ":" if: (not: (curarg empty?)) { str <- str . " " . ((curarg value) stringIndent: indent) curarg <- curarg tail } } while: { not: (curarg empty?) } do: { str <- str . " " . ((curarg value) stringIndent: indent) curarg <- curarg tail } str } string <- { stringIndent: "" } } } object <- :_messages { #{ nodeType <- { _object } messages <- _messages stringIndent <- :indent { nextindent <- "\t" . indent (messages fold: "#{" with: :acc el { acc . "\n" . nextindent . (el stringIndent: nextindent) }) . "\n" . indent . "}" } string <- { stringIndent: "" } } } seqLit:array? <- :_els :_array? { #{ nodeType <- { _sequence } els <- _els array? <- _array? stringIndent <- :indent { nextIndent <- "\t" . indent (els fold: (if: array? {"#["} else: {"["}) with: :acc el { acc . "\n" . nextIndent . (el stringIndent: nextIndent) }) . "\n" . indent . "]" } string <- { stringIndent: "" } } } assign:to <- :_expr :_sym { #{ nodeType <- { _assignment } assign <- _expr to <- _sym stringIndent <- :indent { (to stringIndent: indent) . " <- " . (assign stringIndent: indent) } string <- { stringIndent: "" } } } lambda:withArgs <- :_exprs :_args { #{ nodeType <- { _lambda } args <- _args expressions <- _exprs stringIndent <- :indent { argStr <- args join: " " if: (argStr length) > 0 { argStr <- argStr . " " } nextIndent <- "\t" . indent (expressions fold: argStr . "{" with: :acc el { acc . "\n" . nextIndent . (el stringIndent: nextIndent) }) . "\n" . indent . "}" } string <- { stringIndent: "" } } } } }