This commit is contained in:
Araq
2014-03-23 17:48:10 +01:00
parent 3a34a8880c
commit 5920edf6e4
6 changed files with 102 additions and 33 deletions

View File

@@ -11,7 +11,7 @@
import
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
idents, renderer, types, magicsys, rodread
idents, renderer, types, magicsys, rodread, lowerings
discard """
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[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 =
result = newSym(skVar, getIdent(envName), o.fn, e.attachedNode.info)
incl(result.flags, sfShadowed)

52
compiler/lowerings.nim Normal file
View 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))

View File

@@ -20,10 +20,7 @@
import
intsets, strutils, lists, options, ast, astalgo, trees, treetab, msgs, os,
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
lambdalifting, sempass2
const
genPrefix* = ":tmp" # prefix for generated names
lambdalifting, sempass2, lowerings
# implementation
@@ -240,13 +237,6 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
discard c.contSyms.pop()
else:
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) =
# XXX: BUG: what if `n` is an expression with side-effects?

View File

@@ -486,6 +486,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
regs[ra].intVal = regs[rb].intVal + regs[rc].intVal
of opcAddImmInt:
decodeBImm(rkInt)
#message(c.debug[pc], warnUser, "came here")
#debug regs[rb].node
regs[ra].intVal = regs[rb].intVal + imm
of opcSubInt:
decodeBC(rkInt)

View File

@@ -11,7 +11,7 @@
import
unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
trees, intsets, rodread, magicsys, options
trees, intsets, rodread, magicsys, options, lowerings
from os import splitFile
@@ -636,11 +636,16 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
c.genAddSubInt(n, dest, opcAddInt)
of mInc, mDec:
unused(n, dest)
# XXX generates inefficient code for globals
var d = c.genx(n.sons[1]).TDest
c.genAddSubInt(n, d, if m == mInc: opcAddInt else: opcSubInt)
let opc = if m == mInc: opcAddInt else: opcSubInt
let d = c.genx(n.sons[1])
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.freeTemp(d.TRegister)
c.freeTemp(d)
of mOrd, mChr, mArrToSeq: c.gen(n.sons[1], dest)
of mNew, mNewFinalize:
unused(n, dest)
@@ -1006,6 +1011,10 @@ proc isOwnedBy(a, b: PSym): bool =
if a == b: return true
a = a.owner
proc getOwner(c: PCtx): PSym =
result = c.prc.sym
if result.isNil: result = c.module
proc checkCanEval(c: PCtx; n: PNode) =
# we need to ensure that we don't evaluate 'x' here:
# 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 b = genField(n.sons[1])
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)
c.gABC(n, opcLdObj, cc, a, b)
c.gABC(n, opcNodeToReg, dest, cc)
@@ -1228,16 +1237,10 @@ proc genVarSection(c: PCtx; n: PNode) =
if a.kind == nkCommentStmt: continue
#assert(a.sons[0].kind == nkSym) can happen for transformed vars
if a.kind == nkVarTuple:
let tmp = c.genx(a.lastSon)
for i in 0 .. a.len-3:
setSlot(c, a[i].sym)
# v = t[i]
var v: TDest = -1
checkCanEval(c, a[i])
genRdVar(c, a[i], v, {gfAddrOf})
c.gABC(n, opcWrObj, v, tmp, i)
# XXX globals?
c.freeTemp(tmp)
c.gen(lowerTupleUnpacking(a, c.getOwner))
elif a.sons[0].kind == nkSym:
let s = a.sons[0].sym
checkCanEval(c, a.sons[0])
@@ -1581,7 +1584,7 @@ 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 == "foo":
#if s.name.s == "tupleUnpack":
# echo renderTree(body)
# c.echoCode(result)
c.prc = oldPrc

View 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