tstringinterp almost working

This commit is contained in:
Araq
2014-02-01 23:58:20 +01:00
parent 31f3034c3a
commit 0b8f68def0
3 changed files with 72 additions and 40 deletions

View File

@@ -337,7 +337,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
asgnRef(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
of opcWrGlobal:
asgnComplex(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
of opcLdArr:
of opcLdArr, opcLdArrRef:
# a = b[c]
let rb = instr.regB
let rc = instr.regC
@@ -348,7 +348,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
assert regs[rb].kind != nkMetaNode
let src = regs[rb]
if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len:
asgnComplex(regs[ra], src.sons[idx])
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])
else:
stackTrace(c, tos, pc, errIndexOutOfBounds)
of opcLdStrIdx:
@@ -379,9 +383,15 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
# a = b.c
let rb = instr.regB
let rc = instr.regC
# XXX this creates a wrong alias
#Message(c.debug[pc], warnUser, $regs[rb].safeLen & " " & $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:
# a.b = c
let rb = instr.regB

View File

@@ -34,9 +34,11 @@ type
opcAsgnComplex,
opcLdArr, # a = b[c]
opcLdArrRef,
opcWrArr, # a[b] = c
opcWrArrRef,
opcLdObj, # a = b.c
opcLdObjRef,
opcWrObj, # a.b = c
opcWrObjRef,
opcAddr,

View File

@@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2013 Andreas Rumpf
# (c) Copyright 2014 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -13,9 +13,18 @@ import
unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
trees, intsets, rodread, magicsys, options
from os import splitFile
when hasFFI:
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) =
# first iteration: compute all necessary labels:
var jumpTargets = initIntSet()
@@ -44,7 +53,7 @@ proc codeListing(c: PCtx, result: var string, start=0) =
else:
result.addf("\t$#\tr$#, $#", ($opc).substr(3), x.regA, x.regBx-wordExcess)
result.add("\t#")
result.add(toFileLine(c.debug[i]))
result.add(debugInfo(c.debug[i]))
result.add("\n")
inc i
@@ -190,20 +199,20 @@ template withBlock(labl: PSym; body: stmt) {.immediate, dirty.} =
body
popBlock(c, oldLen)
proc gen(c: PCtx; n: PNode; dest: var TDest)
proc gen(c: PCtx; n: PNode; dest: TRegister) =
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {})
proc gen(c: PCtx; n: PNode; dest: TRegister; flags: TGenFlags = {}) =
var d: TDest = dest
gen(c, n, d)
gen(c, n, d, flags)
internalAssert d == dest
proc gen(c: PCtx; n: PNode) =
proc gen(c: PCtx; n: PNode; flags: TGenFlags = {}) =
var tmp: TDest = -1
gen(c, n, tmp)
gen(c, n, tmp, flags)
#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
gen(c, n, tmp)
gen(c, n, tmp, flags)
internalAssert tmp >= 0
result = TRegister(tmp)
@@ -477,8 +486,8 @@ proc genNew(c: PCtx; n: PNode) =
proc genNewSeq(c: PCtx; n: PNode) =
let dest = if needsAsgnPatch(n.sons[1]): c.getTemp(n.sons[1].typ)
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])
c.gABx(n, opcNewSeq, dest, c.genType(n.sons[1].typ.skipTypes(abstractVar)))
c.gABx(n, opcNewSeq, tmp, 0)
c.freeTemp(tmp)
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.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) =
let tmp = c.genx(n.sons[1])
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)
of mAppendStrCh:
unused(n, dest)
genBinaryStmt(c, n, opcAddStrCh)
genBinaryStmtVar(c, n, opcAddStrCh)
of mAppendStrStr:
unused(n, dest)
genBinaryStmt(c, n, opcAddStrStr)
genBinaryStmtVar(c, n, opcAddStrStr)
of mAppendSeqElem:
unused(n, dest)
genBinaryStmt(c, n, opcAddSeqElem)
genBinaryStmtVar(c, n, opcAddSeqElem)
of mParseExprToAst:
genUnaryABC(c, n, dest, opcParseExprToAst)
of mParseStmtToAst:
@@ -890,12 +907,14 @@ proc skipDeref(n: PNode): PNode =
else:
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
let flags = if opc == opcAddr: flags+{gfAddrOf} else: flags
if unneededIndirection(n.sons[0]):
gen(c, n.sons[0], dest)
gen(c, n.sons[0], dest, flags)
else:
let tmp = c.genx(n.sons[0])
let tmp = c.genx(n.sons[0], flags)
if dest < 0: dest = c.getTemp(n.typ)
gABC(c, n, opc, dest, tmp)
c.freeTemp(tmp)
@@ -1026,26 +1045,27 @@ proc genRdVar(c: PCtx; n: PNode; dest: var TDest) =
cannotEval(n)
#InternalError(n.info, s.name.s & " " & $s.position)
proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode) =
let a = c.genx(n.sons[0])
let b = c.genx(n.sons[1])
proc genAccess(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
flags: TGenFlags) =
let a = c.genx(n.sons[0], flags)
let b = c.genx(n.sons[1], {})
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(b)
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest) =
genAccess(c, n, dest, opcLdObj)
proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
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!
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}:
genAccess(c, n, dest, opcLdStrIdx)
genAccess(c, n, dest, opcLdStrIdx, {})
else:
genAccess(c, n, dest, opcLdArr)
genAccess(c, n, dest, opcLdArr, flags)
proc getNullValue*(typ: PType, info: TLineInfo): 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 gen(c: PCtx; n: PNode; dest: var TDest) =
proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
case n.kind
of nkSym:
let s = n.sym
@@ -1271,11 +1291,11 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
of nkAsgn, nkFastAsgn:
unused(n, dest)
genAsgn(c, n.sons[0], n.sons[1], n.kind == nkAsgn)
of nkDotExpr: genObjAccess(c, n, dest)
of nkCheckedFieldExpr: genCheckedObjAccess(c, n, dest)
of nkBracketExpr: genArrAccess(c, n, dest)
of nkDerefExpr, nkHiddenDeref: genAddrDeref(c, n, dest, opcDeref)
of nkAddr, nkHiddenAddr: genAddrDeref(c, n, dest, opcAddr)
of nkDotExpr: genObjAccess(c, n, dest, flags)
of nkCheckedFieldExpr: genCheckedObjAccess(c, n, dest, flags)
of nkBracketExpr: genArrAccess(c, n, dest, flags)
of nkDerefExpr, nkHiddenDeref: genAddrDeref(c, n, dest, opcDeref, flags)
of nkAddr, nkHiddenAddr: genAddrDeref(c, n, dest, opcAddr, flags)
of nkWhenStmt, nkIfStmt, nkIfExpr: genIf(c, n, dest)
of nkCaseStmt: genCase(c, n, dest)
of nkWhileStmt:
@@ -1298,7 +1318,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
of nkStmtListExpr:
let L = n.len-1
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:
unused(n, dest)
gen(c, n.sons[0])
@@ -1460,9 +1480,9 @@ proc genProc(c: PCtx; s: PSym): int =
c.gABC(body, opcEof, eofInstr.regA)
c.optimizeJumps(result)
s.offset = c.prc.maxSlots
#if s.name.s == "rawGet":
# c.echoCode(result)
# echo renderTree(body)
if s.name.s == "concatStyleInterpolation":
c.echoCode(result)
echo renderTree(body)
c.prc = oldPrc
else:
c.prc.maxSlots = s.offset