mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 02:12:11 +00:00
computed goto now works; some progress on the new VM
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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)
|
||||
|
||||
7
todo.txt
7
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
|
||||
|
||||
Reference in New Issue
Block a user