tstringinterp almost working
This commit is contained in:
parent
31f3034c3a
commit
0b8f68def0
3 changed files with 72 additions and 40 deletions
|
|
@ -337,7 +337,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
asgnRef(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
|
asgnRef(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
|
||||||
of opcWrGlobal:
|
of opcWrGlobal:
|
||||||
asgnComplex(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
|
asgnComplex(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
|
||||||
of opcLdArr:
|
of opcLdArr, opcLdArrRef:
|
||||||
# a = b[c]
|
# a = b[c]
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
|
|
@ -348,6 +348,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
assert regs[rb].kind != nkMetaNode
|
assert regs[rb].kind != nkMetaNode
|
||||||
let src = regs[rb]
|
let src = regs[rb]
|
||||||
if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len:
|
if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len:
|
||||||
|
if instr.opcode == opcLdArrRef and false:
|
||||||
|
# XXX activate when seqs are fixed
|
||||||
|
asgnRef(regs[ra], src.sons[idx])
|
||||||
|
else:
|
||||||
asgnComplex(regs[ra], src.sons[idx])
|
asgnComplex(regs[ra], src.sons[idx])
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errIndexOutOfBounds)
|
stackTrace(c, tos, pc, errIndexOutOfBounds)
|
||||||
|
|
@ -379,9 +383,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
# a = b.c
|
# a = b.c
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
# XXX this creates a wrong alias
|
|
||||||
#Message(c.debug[pc], warnUser, $regs[rb].safeLen & " " & $rc)
|
#Message(c.debug[pc], warnUser, $regs[rb].safeLen & " " & $rc)
|
||||||
asgnComplex(regs[ra], regs[rb].sons[rc])
|
asgnComplex(regs[ra], regs[rb].sons[rc])
|
||||||
|
of opcLdObjRef:
|
||||||
|
# a = b.c
|
||||||
|
let rb = instr.regB
|
||||||
|
let rc = instr.regC
|
||||||
|
# XXX activate when seqs are fixed
|
||||||
|
asgnComplex(regs[ra], regs[rb].sons[rc])
|
||||||
|
#asgnRef(regs[ra], regs[rb].sons[rc])
|
||||||
of opcWrObj:
|
of opcWrObj:
|
||||||
# a.b = c
|
# a.b = c
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,11 @@ type
|
||||||
opcAsgnComplex,
|
opcAsgnComplex,
|
||||||
|
|
||||||
opcLdArr, # a = b[c]
|
opcLdArr, # a = b[c]
|
||||||
|
opcLdArrRef,
|
||||||
opcWrArr, # a[b] = c
|
opcWrArr, # a[b] = c
|
||||||
opcWrArrRef,
|
opcWrArrRef,
|
||||||
opcLdObj, # a = b.c
|
opcLdObj, # a = b.c
|
||||||
|
opcLdObjRef,
|
||||||
opcWrObj, # a.b = c
|
opcWrObj, # a.b = c
|
||||||
opcWrObjRef,
|
opcWrObjRef,
|
||||||
opcAddr,
|
opcAddr,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2013 Andreas Rumpf
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -13,9 +13,18 @@ import
|
||||||
unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
|
||||||
trees, intsets, rodread, magicsys, options
|
trees, intsets, rodread, magicsys, options
|
||||||
|
|
||||||
|
from os import splitFile
|
||||||
|
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
import evalffi
|
import evalffi
|
||||||
|
|
||||||
|
type
|
||||||
|
TGenFlag = enum gfNone, gfAddrOf
|
||||||
|
TGenFlags = set[TGenFlag]
|
||||||
|
|
||||||
|
proc debugInfo(info: TLineInfo): string =
|
||||||
|
result = info.toFilename.splitFile.name & ":" & $info.line
|
||||||
|
|
||||||
proc codeListing(c: PCtx, result: var string, start=0) =
|
proc codeListing(c: PCtx, result: var string, start=0) =
|
||||||
# first iteration: compute all necessary labels:
|
# first iteration: compute all necessary labels:
|
||||||
var jumpTargets = initIntSet()
|
var jumpTargets = initIntSet()
|
||||||
|
|
@ -44,7 +53,7 @@ proc codeListing(c: PCtx, result: var string, start=0) =
|
||||||
else:
|
else:
|
||||||
result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA, x.regBx-wordExcess)
|
result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA, x.regBx-wordExcess)
|
||||||
result.add("\t#")
|
result.add("\t#")
|
||||||
result.add(toFileLine(c.debug[i]))
|
result.add(debugInfo(c.debug[i]))
|
||||||
result.add("\n")
|
result.add("\n")
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
|
|
@ -190,20 +199,20 @@ template withBlock(labl: PSym; body: stmt) {.immediate, dirty.} =
|
||||||
body
|
body
|
||||||
popBlock(c, oldLen)
|
popBlock(c, oldLen)
|
||||||
|
|
||||||
proc gen(c: PCtx; n: PNode; dest: var TDest)
|
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {})
|
||||||
proc gen(c: PCtx; n: PNode; dest: TRegister) =
|
proc gen(c: PCtx; n: PNode; dest: TRegister; flags: TGenFlags = {}) =
|
||||||
var d: TDest = dest
|
var d: TDest = dest
|
||||||
gen(c, n, d)
|
gen(c, n, d, flags)
|
||||||
internalAssert d == dest
|
internalAssert d == dest
|
||||||
|
|
||||||
proc gen(c: PCtx; n: PNode) =
|
proc gen(c: PCtx; n: PNode; flags: TGenFlags = {}) =
|
||||||
var tmp: TDest = -1
|
var tmp: TDest = -1
|
||||||
gen(c, n, tmp)
|
gen(c, n, tmp, flags)
|
||||||
#if n.typ.isEmptyType: InternalAssert tmp < 0
|
#if n.typ.isEmptyType: InternalAssert tmp < 0
|
||||||
|
|
||||||
proc genx(c: PCtx; n: PNode): TRegister =
|
proc genx(c: PCtx; n: PNode; flags: TGenFlags = {}): TRegister =
|
||||||
var tmp: TDest = -1
|
var tmp: TDest = -1
|
||||||
gen(c, n, tmp)
|
gen(c, n, tmp, flags)
|
||||||
internalAssert tmp >= 0
|
internalAssert tmp >= 0
|
||||||
result = TRegister(tmp)
|
result = TRegister(tmp)
|
||||||
|
|
||||||
|
|
@ -477,8 +486,8 @@ proc genNew(c: PCtx; n: PNode) =
|
||||||
proc genNewSeq(c: PCtx; n: PNode) =
|
proc genNewSeq(c: PCtx; n: PNode) =
|
||||||
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ)
|
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ)
|
||||||
else: c.genx(n.sons[1])
|
else: c.genx(n.sons[1])
|
||||||
c.gABx(n, opcNewSeq, dest, c.genType(n.sons[1].typ.skipTypes(abstractVar)))
|
|
||||||
let tmp = c.genx(n.sons[2])
|
let tmp = c.genx(n.sons[2])
|
||||||
|
c.gABx(n, opcNewSeq, dest, c.genType(n.sons[1].typ.skipTypes(abstractVar)))
|
||||||
c.gABx(n, opcNewSeq, tmp, 0)
|
c.gABx(n, opcNewSeq, tmp, 0)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
c.genAsgnPatch(n.sons[1], dest)
|
c.genAsgnPatch(n.sons[1], dest)
|
||||||
|
|
@ -528,6 +537,14 @@ proc genBinaryStmt(c: PCtx; n: PNode; opc: TOpcode) =
|
||||||
c.gABC(n, opc, dest, tmp, 0)
|
c.gABC(n, opc, dest, tmp, 0)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
|
|
||||||
|
proc genBinaryStmtVar(c: PCtx; n: PNode; opc: TOpcode) =
|
||||||
|
let
|
||||||
|
dest = c.genx(n.sons[1], {gfAddrOf})
|
||||||
|
tmp = c.genx(n.sons[2])
|
||||||
|
c.gABC(n, opc, dest, tmp, 0)
|
||||||
|
#c.genAsgnPatch(n.sons[1], dest)
|
||||||
|
c.freeTemp(tmp)
|
||||||
|
|
||||||
proc genUnaryStmt(c: PCtx; n: PNode; opc: TOpcode) =
|
proc genUnaryStmt(c: PCtx; n: PNode; opc: TOpcode) =
|
||||||
let tmp = c.genx(n.sons[1])
|
let tmp = c.genx(n.sons[1])
|
||||||
c.gABC(n, opc, tmp, 0, 0)
|
c.gABC(n, opc, tmp, 0, 0)
|
||||||
|
|
@ -754,13 +771,13 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
c.freeTempRange(x, n.len-1)
|
c.freeTempRange(x, n.len-1)
|
||||||
of mAppendStrCh:
|
of mAppendStrCh:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
genBinaryStmt(c, n, opcAddStrCh)
|
genBinaryStmtVar(c, n, opcAddStrCh)
|
||||||
of mAppendStrStr:
|
of mAppendStrStr:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
genBinaryStmt(c, n, opcAddStrStr)
|
genBinaryStmtVar(c, n, opcAddStrStr)
|
||||||
of mAppendSeqElem:
|
of mAppendSeqElem:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
genBinaryStmt(c, n, opcAddSeqElem)
|
genBinaryStmtVar(c, n, opcAddSeqElem)
|
||||||
of mParseExprToAst:
|
of mParseExprToAst:
|
||||||
genUnaryABC(c, n, dest, opcParseExprToAst)
|
genUnaryABC(c, n, dest, opcParseExprToAst)
|
||||||
of mParseStmtToAst:
|
of mParseStmtToAst:
|
||||||
|
|
@ -890,12 +907,14 @@ proc skipDeref(n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
||||||
|
flags: TGenFlags) =
|
||||||
# a nop for certain types
|
# a nop for certain types
|
||||||
|
let flags = if opc == opcAddr: flags+{gfAddrOf} else: flags
|
||||||
if unneededIndirection(n.sons[0]):
|
if unneededIndirection(n.sons[0]):
|
||||||
gen(c, n.sons[0], dest)
|
gen(c, n.sons[0], dest, flags)
|
||||||
else:
|
else:
|
||||||
let tmp = c.genx(n.sons[0])
|
let tmp = c.genx(n.sons[0], flags)
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
gABC(c, n, opc, dest, tmp)
|
gABC(c, n, opc, dest, tmp)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
|
|
@ -1026,26 +1045,27 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
cannotEval(n)
|
cannotEval(n)
|
||||||
#InternalError(n.info, s.name.s & " " & $s.position)
|
#InternalError(n.info, s.name.s & " " & $s.position)
|
||||||
|
|
||||||
proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
|
proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
|
||||||
let a = c.genx(n.sons[0])
|
flags: TGenFlags) =
|
||||||
let b = c.genx(n.sons[1])
|
let a = c.genx(n.sons[0], flags)
|
||||||
|
let b = c.genx(n.sons[1], {})
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
c.gABC(n, opc, dest, a, b)
|
c.gABC(n, (if gfAddrOf in flags: succ(opc) else: opc), dest, a, b)
|
||||||
c.freeTemp(a)
|
c.freeTemp(a)
|
||||||
c.freeTemp(b)
|
c.freeTemp(b)
|
||||||
|
|
||||||
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest) =
|
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
genAccess(c, n, dest, opcLdObj)
|
genAccess(c, n, dest, opcLdObj, flags)
|
||||||
|
|
||||||
proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest) =
|
proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
# XXX implement field checks!
|
# XXX implement field checks!
|
||||||
genAccess(c, n.sons[0], dest, opcLdObj)
|
genAccess(c, n.sons[0], dest, opcLdObj, flags)
|
||||||
|
|
||||||
proc genArrAccess(c: PCtx; n: PNode; dest: var TDest) =
|
proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
if n.sons[0].typ.skipTypes(abstractVarRange).kind in {tyString, tyCString}:
|
if n.sons[0].typ.skipTypes(abstractVarRange).kind in {tyString, tyCString}:
|
||||||
genAccess(c, n, dest, opcLdStrIdx)
|
genAccess(c, n, dest, opcLdStrIdx, {})
|
||||||
else:
|
else:
|
||||||
genAccess(c, n, dest, opcLdArr)
|
genAccess(c, n, dest, opcLdArr, flags)
|
||||||
|
|
||||||
proc getNullValue*(typ: PType, info: TLineInfo): PNode
|
proc getNullValue*(typ: PType, info: TLineInfo): PNode
|
||||||
proc getNullValueAux(obj: PNode, result: PNode) =
|
proc getNullValueAux(obj: PNode, result: PNode) =
|
||||||
|
|
@ -1222,7 +1242,7 @@ proc genTupleConstr(c: PCtx, n: PNode, dest: var TDest) =
|
||||||
|
|
||||||
proc genProc*(c: PCtx; s: PSym): int
|
proc genProc*(c: PCtx; s: PSym): int
|
||||||
|
|
||||||
proc gen(c: PCtx; n: PNode; dest: var TDest) =
|
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let s = n.sym
|
let s = n.sym
|
||||||
|
|
@ -1271,11 +1291,11 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
of nkAsgn, nkFastAsgn:
|
of nkAsgn, nkFastAsgn:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn)
|
genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn)
|
||||||
of nkDotExpr: genObjAccess(c, n, dest)
|
of nkDotExpr: genObjAccess(c, n, dest, flags)
|
||||||
of nkCheckedFieldExpr: genCheckedObjAccess(c, n, dest)
|
of nkCheckedFieldExpr: genCheckedObjAccess(c, n, dest, flags)
|
||||||
of nkBracketExpr: genArrAccess(c, n, dest)
|
of nkBracketExpr: genArrAccess(c, n, dest, flags)
|
||||||
of nkDerefExpr, nkHiddenDeref: genAddrDeref(c, n, dest, opcDeref)
|
of nkDerefExpr, nkHiddenDeref: genAddrDeref(c, n, dest, opcDeref, flags)
|
||||||
of nkAddr, nkHiddenAddr: genAddrDeref(c, n, dest, opcAddr)
|
of nkAddr, nkHiddenAddr: genAddrDeref(c, n, dest, opcAddr, flags)
|
||||||
of nkWhenStmt, nkIfStmt, nkIfExpr: genIf(c, n, dest)
|
of nkWhenStmt, nkIfStmt, nkIfExpr: genIf(c, n, dest)
|
||||||
of nkCaseStmt: genCase(c, n, dest)
|
of nkCaseStmt: genCase(c, n, dest)
|
||||||
of nkWhileStmt:
|
of nkWhileStmt:
|
||||||
|
|
@ -1298,7 +1318,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
of nkStmtListExpr:
|
of nkStmtListExpr:
|
||||||
let L = n.len-1
|
let L = n.len-1
|
||||||
for i in 0 .. <L: gen(c, n.sons[i])
|
for i in 0 .. <L: gen(c, n.sons[i])
|
||||||
gen(c, n.sons[L], dest)
|
gen(c, n.sons[L], dest, flags)
|
||||||
of nkDiscardStmt:
|
of nkDiscardStmt:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
gen(c, n.sons[0])
|
gen(c, n.sons[0])
|
||||||
|
|
@ -1460,9 +1480,9 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||||
c.gABC(body, opcEof, eofInstr.regA)
|
c.gABC(body, opcEof, eofInstr.regA)
|
||||||
c.optimizeJumps(result)
|
c.optimizeJumps(result)
|
||||||
s.offset = c.prc.maxSlots
|
s.offset = c.prc.maxSlots
|
||||||
#if s.name.s == "rawGet":
|
if s.name.s == "concatStyleInterpolation":
|
||||||
# c.echoCode(result)
|
c.echoCode(result)
|
||||||
# echo renderTree(body)
|
echo renderTree(body)
|
||||||
c.prc = oldPrc
|
c.prc = oldPrc
|
||||||
else:
|
else:
|
||||||
c.prc.maxSlots = s.offset
|
c.prc.maxSlots = s.offset
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue