diff options
author | Araq <rumpf_a@web.de> | 2013-10-25 13:30:34 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-10-25 13:30:34 +0200 |
commit | 6ea538cec3f2da832873252d0ec3810b9dbfede4 (patch) | |
tree | a5d6e6abd506dbbfca91485137e36c48cd3fba85 | |
parent | ca12bf76f595027076a437f8bf98a1928f1504d4 (diff) | |
download | Nim-6ea538cec3f2da832873252d0ec3810b9dbfede4.tar.gz |
computed goto now works; some progress on the new VM
-rw-r--r-- | compiler/ccgstmts.nim | 19 | ||||
-rw-r--r-- | compiler/vm.nim | 17 | ||||
-rw-r--r-- | compiler/vmdeps.nim | 2 | ||||
-rw-r--r-- | tests/compile/tcomputedgoto.nim | 31 | ||||
-rw-r--r-- | todo.txt | 7 |
5 files changed, 53 insertions, 23 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 75cabf414..d71d65ceb 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -322,8 +322,20 @@ proc genComputedGoto(p: BProc; n: PNode) = gotoArray.appf("&&TMP$#, ", (id+i).toRope) gotoArray.appf("&&TMP$#};$n", (id+arraySize).toRope) line(p, cpsLocals, gotoArray) + + let topBlock = p.blocks.len-1 + let oldBody = p.blocks[topBlock].sections[cpsStmts] + p.blocks[topBlock].sections[cpsStmts] = nil + for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) + let tailB = p.blocks[topBlock].sections[cpsStmts] + + p.blocks[topBlock].sections[cpsStmts] = nil for j in 0 .. casePos-1: genStmts(p, n.sons[j]) + let tailA = p.blocks[topBlock].sections[cpsStmts] + + p.blocks[topBlock].sections[cpsStmts] = oldBody.con(tailA) + let caseStmt = n.sons[casePos] var a: TLoc initLocExpr(p, caseStmt.sons[0], a) @@ -340,8 +352,11 @@ proc genComputedGoto(p: BProc; n: PNode) = let val = getOrdValue(it.sons[j]) lineF(p, cpsStmts, "TMP$#:$n", intLiteral(val+id+1)) genStmts(p, it.lastSon) - for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) - for j in 0 .. casePos-1: genStmts(p, n.sons[j]) + #for j in casePos+1 .. <n.len: genStmts(p, n.sons[j]) # tailB + #for j in 0 .. casePos-1: genStmts(p, n.sons[j]) # tailA + app(p.s(cpsStmts), tailB) + app(p.s(cpsStmts), tailA) + var a: TLoc initLocExpr(p, caseStmt.sons[0], a) lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc) diff --git a/compiler/vm.nim b/compiler/vm.nim index 943324de1..ad390e53c 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -10,8 +10,10 @@ ## This file implements the new evaluation engine for Nimrod code. ## An instruction is 1-2 int32s in memory, it is a register based VM. +import ast except getstr + import - strutils, ast, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned, + strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned, parser, vmdeps, idents, trees, renderer from semfold import leValueConv, ordinalValToString @@ -131,7 +133,7 @@ proc asgnComplex(x, y: PNode) = for i in countup(0, sonsLen(y) - 1): addSon(x, y.sons[i]) template getstr(a: expr): expr = - (if a.kind == nkStrLit: a.strVal else: $chr(int(a.intVal))) + (if a.kind in {nkStrLit..nkTripleStrLit}: a.strVal else: $chr(int(a.intVal))) proc pushSafePoint(f: PStackFrame; pc: int) = if f.safePoints.isNil: f.safePoints = @[] @@ -669,8 +671,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = of opcSetLenStr: decodeB(nkStrLit) regs[ra].strVal.setLen(regs[rb].getOrdValue.int) + of opcOf: + decodeBC(nkIntLit) + regs[ra].intVal = ord(inheritanceDiff(regs[rb].typ, regs[rc].typ) >= 0) of opcSetLenSeq, - opcSwap, opcIsNil, opcOf, + opcSwap, opcIsNil, opcCast, opcReset: internalError(c.debug[pc], "too implement") of opcNBindSym: @@ -868,6 +873,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode = regs[ra].strVal = typ.typeToString(preferExported) inc pc +proc fixType(result, n: PNode) {.inline.} = + # XXX do it deeply for complex values + if result.typ.isNil: result.typ = n.typ + proc execute(c: PCtx, start: int): PNode = var tos = PStackFrame(prc: nil, comesFrom: 0, next: nil) newSeq(tos.slots, c.prc.maxSlots) @@ -885,6 +894,7 @@ proc evalExpr*(c: PCtx, n: PNode): PNode = let start = genExpr(c, n) assert c.code[start].opcode != opcEof result = execute(c, start) + fixType(result, n) # for now we share the 'globals' environment. XXX Coming soon: An API for # storing&loading the 'globals' environment to get what a component system @@ -928,6 +938,7 @@ proc evalConstExprAux(module, prc: PSym, n: PNode, mode: TEvalMode): PNode = newSeq(tos.slots, c.prc.maxSlots) for i in 0 .. <c.prc.maxSlots: tos.slots[i] = newNode(nkEmpty) result = rawExecute(c, start, tos) + fixType(result, n) proc evalConstExpr*(module: PSym, e: PNode): PNode = result = evalConstExprAux(module, nil, e, emConst) diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 2a40276d1..5b1a028b1 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -32,8 +32,8 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym): string = appendToModule(module, newNode(nkIncludeStmt, info, @[ newStrNode(nkStrLit, filename)])) except EIO: - result = "" LocalError(info, errCannotOpenFile, file) + result = "" when false: proc opExpandToAst*(c: PEvalContext, original: PNode): PNode = diff --git a/tests/compile/tcomputedgoto.nim b/tests/compile/tcomputedgoto.nim index 2c3b4bbd4..b21fc07a3 100644 --- a/tests/compile/tcomputedgoto.nim +++ b/tests/compile/tcomputedgoto.nim @@ -1,16 +1,16 @@ discard """ - output: '''yeah A -yeah A -yeah CD -yeah CD -yeah A -yeah CD -yeah CD -yeah A -yeah B -yeah A -yeah A -yeah A''' + output: '''yeah A enumB +yeah A enumB +yeah CD enumD +yeah CD enumE +yeah A enumB +yeah CD enumE +yeah CD enumD +yeah A enumB +yeah B enumC +yeah A enumB +yeah A enumB +yeah A enumB''' """ type @@ -32,13 +32,14 @@ proc vm() = while true: {.computedGoto.} let instr = instructions[pc] + let ra = instr.succ # instr.regA case instr of enumA: - echo "yeah A" + echo "yeah A ", ra of enumC, enumD: - echo "yeah CD" + echo "yeah CD ", ra of enumB: - echo "yeah B" + echo "yeah B ", ra of enumE: break inc(pc) diff --git a/todo.txt b/todo.txt index 647f5e2c1..1dcaa8ff6 100644 --- a/todo.txt +++ b/todo.txt @@ -2,11 +2,12 @@ version 0.9.4 ============= - new VM: + - get rid of nkIntLit..nkUInt64Lit, + nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit? - new VM requires lambda lifting - - codegen for computed goto still wrong - - test and activate the jump optimizer - implement overflow checking - implement the FFI + - test and activate the jump optimizer - make 'bind' default for templates and introduce 'mixin' - special rule for ``[]=`` @@ -20,6 +21,8 @@ version 0.9.4 Bugs ==== +- bug: 'type T = ref T' not recognized as illegal recursion +- bug: type conversions concerning proc types are weird - compilation of niminst takes way too long. looks like a regression - simple closure iterator doesn't work - docgen: sometimes effects are listed twice |