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

View file

@ -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
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 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
@ -240,13 +237,6 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
discard c.contSyms.pop() discard c.contSyms.pop()
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?

View file

@ -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)

View file

@ -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

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