tstringinterp almost working

This commit is contained in:
Araq 2014-02-01 23:58:20 +01:00
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]) 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

View file

@ -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,

View file

@ -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