# HG changeset patch # User Michael Pavone # Date 1406324755 25200 # Node ID 526bec3b2090fda7840ec2927473fff478acaedd # Parent 494ef2e3a756caae39499e96b61e50e69de8144f Function call and lambda expression support. Fix ABI for main function. Use main definition for number of args rather than assuming 2 of them. diff -r 494ef2e3a756 -r 526bec3b2090 code/lmc.tp --- a/code/lmc.tp Fri Jul 25 13:59:43 2014 -0700 +++ b/code/lmc.tp Fri Jul 25 14:45:55 2014 -0700 @@ -176,14 +176,22 @@ _exprHandlers set: (ast call) :expr syms { tc <- (expr tocall) + normal <- true if: (tc nodeType) = (ast sym) { _funHandlers ifget: (tc name) :handler { handler: (expr args) syms + normal <- false } else: { - error: "function calls not implemented yet" } - } else: { - error: "call expression to value not implemented yet - " . tc + } + if: normal { + compileExpr: tc syms: syms + num <- 0 + foreach: (expr args) :idx arg { + compileExpr: arg syms: syms + num <- num + 1 + } + prog add: (inst: "AP" #[num]) } } @@ -212,6 +220,58 @@ error: "symbol " . (sym name) . " is not defined" } } + + compileLambda:syms <- :fname fun :syms { + prog setLabel: fname + argsyms <- symbols tableWithParent: syms + foreach: (fun args) :idx el { + argsyms define: (if: (el startsWith?: ":") { el from: 1 } else: { el }) idx + } + + slot <- 0 + locsyms <- symbols tableWithParent: argsyms + foreach: (fun expressions) :idx expr { + if: (expr nodeType) = (ast assignment) { + locsyms ifDefined: ((expr to) name) :sym { + //already defined, nothing to do here + } else: { + locsyms define: ((expr to) name) slot + slot <- slot + 1 + } + } + } + fsyms <- if: slot > 0 { + //allocate frame for locals + prog add: (inst: "DUM" #[slot]) + i <- 0 + while: { i < slot } do: { + prog add: (inst: "LDC" #[0]) + i <- i + 1 + } + prologue_end <- prog makeLabel: fname . "_real" + prog add: (inst: "LDF" #[prologue_end]) + prog add: (inst: "TRAP" #[slot]) + prog setLabel: prologue_end + locsyms + } else: { argsyms } + + foreach: (fun expressions) :idx expr { + compileExpr: expr syms: fsyms + } + prog add: (inst: "RTN" #[]) + } + + _exprHandlers set: (ast lambda) :expr syms { + fname <- prog makeLabel: "lambda" + end <- prog makeLabel: "lambda_end" + prog add: (inst: "LDC" #[1]) + prog add: (inst: "TSEL" #[ + end + end + ]) + compileLambda: fname expr syms: syms + prog setLabel: end + } #{ compile <- :code { res <- parser top: code @@ -224,6 +284,7 @@ prog add: (inst: "DUM" #[num]) slot <- 0 + mainArgs <- 0 foreach: (outer messages) :idx msg { if: (msg nodeType) = (ast assignment) { def <- msg assign @@ -232,6 +293,9 @@ if: (def nodeType) = (ast lambda) { prog add: (inst: "LDF" #[sym]) functions set: sym def + if: sym = "main" { + mainArgs <- (def args) length + } } else: { compileExpr: def syms: syms } @@ -245,47 +309,21 @@ prog add: (inst: "LDF" #[after_env]) prog add: (inst: "TRAP" #[num]) prog setLabel: after_env + + i <- 0 + while: { i < mainArgs } do: { + prog add: (inst: "LD" #[ + 0 + i + ]) + i <- i + 1 + } + prog add: (inst: "LDF" #["main"]) - prog add: (inst: "TAP" #[2]) + prog add: (inst: "TAP" #[mainArgs]) foreach: functions :fname fun { - prog setLabel: fname - argsyms <- symbols tableWithParent: syms - foreach: (fun args) :idx el { - argsyms define: (if: (el startsWith?: ":") { el from: 1 } else: { el }) idx - } - - slot <- 0 - locsyms <- symbols tableWithParent: argsyms - foreach: (fun expressions) :idx expr { - if: (expr nodeType) = (ast assignment) { - locsyms ifDefined: ((expr to) name) :sym { - //already defined, nothing to do here - } else: { - locsyms define: ((expr to) name) slot - slot <- slot + 1 - } - } - } - fsyms <- if: slot > 0 { - //allocate frame for locals - prog add: (inst: "DUM" #[slot]) - i <- 0 - while: { i < slot } do: { - prog add: (inst: "LDC" #[0]) - i <- i + 1 - } - prologue_end <- prog makeLabel: fname . "_real" - prog add: (inst: "LDF" #[prologue_end]) - prog add: (inst: "TRAP" #[slot]) - prog setLabel: prologue_end - locsyms - } else: { argsyms } - - foreach: (fun expressions) :idx expr { - compileExpr: expr syms: fsyms - } - prog add: (inst: "RTN" #[]) + compileLambda: fname fun syms: syms } print: prog } else: {