diff options
author | Araq <rumpf_a@web.de> | 2014-02-01 23:58:20 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2014-02-01 23:58:20 +0100 |
commit | 0b8f68def0130ca381c2b2f16cc9b62918e32301 (patch) | |
tree | 587097ee9a12669bf0359d4d3da75fc7160c9947 /compiler/vmgen.nim | |
parent | 31f3034c3a93a7f056863db51ede65d2ebf66db6 (diff) | |
download | Nim-0b8f68def0130ca381c2b2f16cc9b62918e32301.tar.gz |
tstringinterp almost working
Diffstat (limited to 'compiler/vmgen.nim')
-rw-r--r-- | compiler/vmgen.nim | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index a41e60e7d..ff479b74a 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -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 |