# HG changeset patch # User Michael Pavone # Date 1406516614 25200 # Node ID d35601d47db17e83436f6498853539b12659a3d5 # Parent a3e4d2833301e87fec045222ec095548250f215e Implement if:else in gqc diff -r a3e4d2833301 -r d35601d47db1 code/gqc.tp --- a/code/gqc.tp Sun Jul 27 19:53:08 2014 -0700 +++ b/code/gqc.tp Sun Jul 27 20:03:34 2014 -0700 @@ -365,6 +365,127 @@ } } + _funHandlers set: "if:else" :args syms { + cond <- (args value) + trueBody <- ((args tail) value) expressions + falseBody <- (((args tail) tail) value) expressions + + if: (cond nodeType) = (ast binary) { + trueLbl <- prog makeLabel: "true" + falseLbl <- prog makeLabel: "false" + endLbl <- prog makeLabel: "end" + + saveTempRegs <- _tempRegs + l <- compileExpr: (cond left) syms: syms + r <- compileExpr: (cond right) syms: syms + _tempRegs <- saveTempRegs + + ok <- true + + if: (cond op) = ">=" { + prog add: (inst: "JLT" #[ + falseLbl + l + r + ]) + } else: { + if: (cond op) = "<=" { + prog add: (inst: "JGT" #[ + falseLbl + l + r + ]) + } else: { + if: (cond op) = "!=" { + prog add: (inst: "JEQ" #[ + falseLbl + l + r + ]) + } else: { + if: (cond op) = ">" { + prog add: (inst: "JGT" #[ + trueLbl + l + r + ]) + prog add: (inst: "MOV" #[ + reg: 8 + falseLbl + ]) + } else: { + if: (cond op) = "<" { + prog add: (inst: "JLT" #[ + trueLbl + l + r + ]) + prog add: (inst: "MOV" #[ + reg: 8 + falseLbl + ]) + } else: { + bodyLbl <- prog makeLabel: "loop_body" + if: (cond op) = "=" { + prog add: (inst: "JEQ" #[ + trueLbl + l + r + ]) + prog add: (inst: "MOV" #[ + reg: 8 + falseLbl + ]) + } else: { + ok <- false + } + } + } + } + } + } + if: ok { + prog setLabel: trueLbl + //TODO: do 2 passes for labels to allow forward references + foreach: trueBody :idx expr { + if: (expr nodeType) = (ast sym) { + //allow using bare symbols to define labels + lbl <- prog makeLabel: (expr name) + prog setLabel: lbl + syms define: (expr name) lbl + } else: { + saveTempRegsExpr <- _tempRegs + v <- compileExpr: expr syms: syms + _tempRegs <- saveTempRegsExpr + } + } + prog add: (inst: "MOV" #[ + reg: 8 + endLbl + ]) + prog setLabel: falseLbl + //TODO: do 2 passes for labels to allow forward references + foreach: falseBody :idx expr { + if: (expr nodeType) = (ast sym) { + //allow using bare symbols to define labels + lbl <- prog makeLabel: (expr name) + prog setLabel: lbl + syms define: (expr name) lbl + } else: { + saveTempRegsExpr <- _tempRegs + v <- compileExpr: expr syms: syms + _tempRegs <- saveTempRegsExpr + } + } + prog setLabel: endLbl + } else: { + error: "Condition parameter to if:else must be a comparison operator expression" + } + } else: { + error: "Condition parameter to if:else must be a comparison operator expression" + } + } + _exprHandlers set: (ast call) :expr syms { tc <- (expr tocall) if: (tc nodeType) = (ast sym) {