tstringinterp almost working
This commit is contained in:
parent
31f3034c3a
commit
0b8f68def0
3 changed files with 72 additions and 40 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue