fixes #404
This commit is contained in:
parent
3a34a8880c
commit
5920edf6e4
6 changed files with 102 additions and 33 deletions
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
|
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
|
||||||
idents, renderer, types, magicsys, rodread
|
idents, renderer, types, magicsys, rodread, lowerings
|
||||||
|
|
||||||
discard """
|
discard """
|
||||||
The basic approach is that captured vars need to be put on the heap and
|
The basic approach is that captured vars need to be put on the heap and
|
||||||
|
|
@ -536,13 +536,6 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
|
||||||
result.sons[0] = le
|
result.sons[0] = le
|
||||||
result.sons[1] = ri
|
result.sons[1] = ri
|
||||||
|
|
||||||
proc addVar*(father, v: PNode) =
|
|
||||||
var vpart = newNodeI(nkIdentDefs, v.info)
|
|
||||||
addSon(vpart, v)
|
|
||||||
addSon(vpart, ast.emptyNode)
|
|
||||||
addSon(vpart, ast.emptyNode)
|
|
||||||
addSon(father, vpart)
|
|
||||||
|
|
||||||
proc newClosureCreationVar(o: POuterContext; e: PEnv): PSym =
|
proc newClosureCreationVar(o: POuterContext; e: PEnv): PSym =
|
||||||
result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info)
|
result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info)
|
||||||
incl(result.flags, sfShadowed)
|
incl(result.flags, sfShadowed)
|
||||||
|
|
|
||||||
52
compiler/lowerings.nim
Normal file
52
compiler/lowerings.nim
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The Nimrod Compiler
|
||||||
|
# (c) Copyright 2014 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module implements common simple lowerings.
|
||||||
|
|
||||||
|
const
|
||||||
|
genPrefix* = ":tmp" # prefix for generated names
|
||||||
|
|
||||||
|
import ast, types, idents, magicsys
|
||||||
|
|
||||||
|
proc newTupleAccess*(tup: PNode, i: int): PNode =
|
||||||
|
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
|
||||||
|
abstractInst).sons[i])
|
||||||
|
addSon(result, copyTree(tup))
|
||||||
|
var lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt))
|
||||||
|
lit.intVal = i
|
||||||
|
addSon(result, lit)
|
||||||
|
|
||||||
|
proc addVar*(father, v: PNode) =
|
||||||
|
var vpart = newNodeI(nkIdentDefs, v.info, 3)
|
||||||
|
vpart.sons[0] = v
|
||||||
|
vpart.sons[1] = ast.emptyNode
|
||||||
|
vpart.sons[2] = ast.emptyNode
|
||||||
|
addSon(father, vpart)
|
||||||
|
|
||||||
|
proc newAsgnStmt(le, ri: PNode): PNode =
|
||||||
|
result = newNodeI(nkAsgn, le.info, 2)
|
||||||
|
result.sons[0] = le
|
||||||
|
result.sons[1] = ri
|
||||||
|
|
||||||
|
proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode =
|
||||||
|
assert n.kind == nkVarTuple
|
||||||
|
let value = n.lastSon
|
||||||
|
result = newNodeI(nkStmtList, n.info)
|
||||||
|
|
||||||
|
var temp = newSym(skTemp, getIdent(genPrefix), owner, value.info)
|
||||||
|
temp.typ = skipTypes(value.typ, abstractInst)
|
||||||
|
incl(temp.flags, sfFromGeneric)
|
||||||
|
|
||||||
|
var v = newNodeI(nkVarSection, value.info)
|
||||||
|
v.addVar(newSymNode(temp))
|
||||||
|
result.add(v)
|
||||||
|
|
||||||
|
result.add newAsgnStmt(newSymNode(temp), value)
|
||||||
|
for i in 0 .. n.len-3:
|
||||||
|
result.add newAsgnStmt(n.sons[i], newTupleAccess(value, i))
|
||||||
|
|
@ -20,10 +20,7 @@
|
||||||
import
|
import
|
||||||
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
|
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
|
||||||
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
|
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
|
||||||
lambdalifting, sempass2
|
lambdalifting, sempass2, lowerings
|
||||||
|
|
||||||
const
|
|
||||||
genPrefix* = ":tmp" # prefix for generated names
|
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
@ -241,13 +238,6 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
|
||||||
else:
|
else:
|
||||||
result = transform(c, n)
|
result = transform(c, n)
|
||||||
|
|
||||||
proc newTupleAccess(tup: PNode, i: int): PNode =
|
|
||||||
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i])
|
|
||||||
addSon(result, copyTree(tup))
|
|
||||||
var lit = newNodeIT(nkIntLit, tup.info, getSysType(tyInt))
|
|
||||||
lit.intVal = i
|
|
||||||
addSon(result, lit)
|
|
||||||
|
|
||||||
proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) =
|
proc unpackTuple(c: PTransf, n: PNode, father: PTransNode) =
|
||||||
# XXX: BUG: what if `n` is an expression with side-effects?
|
# XXX: BUG: what if `n` is an expression with side-effects?
|
||||||
for i in countup(0, sonsLen(c.transCon.forStmt) - 3):
|
for i in countup(0, sonsLen(c.transCon.forStmt) - 3):
|
||||||
|
|
|
||||||
|
|
@ -486,6 +486,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
regs[ra].intVal = regs[rb].intVal + regs[rc].intVal
|
regs[ra].intVal = regs[rb].intVal + regs[rc].intVal
|
||||||
of opcAddImmInt:
|
of opcAddImmInt:
|
||||||
decodeBImm(rkInt)
|
decodeBImm(rkInt)
|
||||||
|
#message(c.debug[pc], warnUser, "came here")
|
||||||
|
#debug regs[rb].node
|
||||||
regs[ra].intVal = regs[rb].intVal + imm
|
regs[ra].intVal = regs[rb].intVal + imm
|
||||||
of opcSubInt:
|
of opcSubInt:
|
||||||
decodeBC(rkInt)
|
decodeBC(rkInt)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
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, lowerings
|
||||||
|
|
||||||
from os import splitFile
|
from os import splitFile
|
||||||
|
|
||||||
|
|
@ -636,11 +636,16 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
c.genAddSubInt(n, dest, opcAddInt)
|
c.genAddSubInt(n, dest, opcAddInt)
|
||||||
of mInc, mDec:
|
of mInc, mDec:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
# XXX generates inefficient code for globals
|
let opc = if m == mInc: opcAddInt else: opcSubInt
|
||||||
var d = c.genx(n.sons[1]).TDest
|
let d = c.genx(n.sons[1])
|
||||||
c.genAddSubInt(n, d, if m == mInc: opcAddInt else: opcSubInt)
|
if n.sons[2].isInt8Lit:
|
||||||
|
c.gABI(n, succ(opc), d, d, n.sons[2].intVal)
|
||||||
|
else:
|
||||||
|
let tmp = c.genx(n.sons[2])
|
||||||
|
c.gABC(n, opc, d, d, tmp)
|
||||||
|
c.freeTemp(tmp)
|
||||||
c.genAsgnPatch(n.sons[1], d)
|
c.genAsgnPatch(n.sons[1], d)
|
||||||
c.freeTemp(d.TRegister)
|
c.freeTemp(d)
|
||||||
of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest)
|
of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest)
|
||||||
of mNew, mNewFinalize:
|
of mNew, mNewFinalize:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
|
|
@ -1006,6 +1011,10 @@ proc isOwnedBy(a, b: PSym): bool =
|
||||||
if a == b: return true
|
if a == b: return true
|
||||||
a = a.owner
|
a = a.owner
|
||||||
|
|
||||||
|
proc getOwner(c: PCtx): PSym =
|
||||||
|
result = c.prc.sym
|
||||||
|
if result.isNil: result = c.module
|
||||||
|
|
||||||
proc checkCanEval(c: PCtx; n: PNode) =
|
proc checkCanEval(c: PCtx; n: PNode) =
|
||||||
# we need to ensure that we don't evaluate 'x' here:
|
# we need to ensure that we don't evaluate 'x' here:
|
||||||
# proc foo() = var x ...
|
# proc foo() = var x ...
|
||||||
|
|
@ -1148,7 +1157,7 @@ proc genObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||||
let a = c.genx(n.sons[0], flags)
|
let a = c.genx(n.sons[0], flags)
|
||||||
let b = genField(n.sons[1])
|
let b = genField(n.sons[1])
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
if gfAddrOf notin flags and fitsRegister(n.typ):
|
if gfAddrOf notin flags and fitsRegister(n.typ.skipTypes({tyVar})):
|
||||||
var cc = c.getTemp(n.typ)
|
var cc = c.getTemp(n.typ)
|
||||||
c.gABC(n, opcLdObj, cc, a, b)
|
c.gABC(n, opcLdObj, cc, a, b)
|
||||||
c.gABC(n, opcNodeToReg, dest, cc)
|
c.gABC(n, opcNodeToReg, dest, cc)
|
||||||
|
|
@ -1228,16 +1237,10 @@ proc genVarSection(c: PCtx; n: PNode) =
|
||||||
if a.kind == nkCommentStmt: continue
|
if a.kind == nkCommentStmt: continue
|
||||||
#assert(a.sons[0].kind == nkSym) can happen for transformed vars
|
#assert(a.sons[0].kind == nkSym) can happen for transformed vars
|
||||||
if a.kind == nkVarTuple:
|
if a.kind == nkVarTuple:
|
||||||
let tmp = c.genx(a.lastSon)
|
|
||||||
for i in 0 .. a.len-3:
|
for i in 0 .. a.len-3:
|
||||||
setSlot(c, a[i].sym)
|
setSlot(c, a[i].sym)
|
||||||
# v = t[i]
|
|
||||||
var v: TDest = -1
|
|
||||||
checkCanEval(c, a[i])
|
checkCanEval(c, a[i])
|
||||||
genRdVar(c, a[i], v, {gfAddrOf})
|
c.gen(lowerTupleUnpacking(a, c.getOwner))
|
||||||
c.gABC(n, opcWrObj, v, tmp, i)
|
|
||||||
# XXX globals?
|
|
||||||
c.freeTemp(tmp)
|
|
||||||
elif a.sons[0].kind == nkSym:
|
elif a.sons[0].kind == nkSym:
|
||||||
let s = a.sons[0].sym
|
let s = a.sons[0].sym
|
||||||
checkCanEval(c, a.sons[0])
|
checkCanEval(c, a.sons[0])
|
||||||
|
|
@ -1581,7 +1584,7 @@ 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 == "foo":
|
#if s.name.s == "tupleUnpack":
|
||||||
# echo renderTree(body)
|
# echo renderTree(body)
|
||||||
# c.echoCode(result)
|
# c.echoCode(result)
|
||||||
c.prc = oldPrc
|
c.prc = oldPrc
|
||||||
|
|
|
||||||
29
tests/vm/tcompiletimetable.nim
Normal file
29
tests/vm/tcompiletimetable.nim
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
discard """
|
||||||
|
msg: '''2
|
||||||
|
3
|
||||||
|
4:2
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #404
|
||||||
|
|
||||||
|
import macros, tables
|
||||||
|
|
||||||
|
var ZOOT{.compileTime.} = initTable[int, int](2)
|
||||||
|
var iii {.compiletime.} = 1
|
||||||
|
|
||||||
|
macro x:stmt=
|
||||||
|
zoot[iii] = iii*2
|
||||||
|
inc iii
|
||||||
|
echo iii
|
||||||
|
|
||||||
|
x
|
||||||
|
x
|
||||||
|
|
||||||
|
|
||||||
|
macro tupleUnpack: stmt =
|
||||||
|
var (y,z) = (4, 2)
|
||||||
|
echo y, ":", z
|
||||||
|
|
||||||
|
tupleUnpack
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue