mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-14 15:23:27 +00:00
tstringinterp almost working
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user