added missing file
This commit is contained in:
parent
bd19b5f4d3
commit
1ec0686d04
1 changed files with 68 additions and 0 deletions
68
compiler/liftlocals.nim
Normal file
68
compiler/liftlocals.nim
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The Nim Compiler
|
||||||
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module implements the '.liftLocals' pragma.
|
||||||
|
|
||||||
|
import
|
||||||
|
intsets, strutils, options, ast, astalgo, msgs,
|
||||||
|
idents, renderer, types, lowerings
|
||||||
|
|
||||||
|
from pragmas import getPragmaVal
|
||||||
|
from wordrecg import wLiftLocals
|
||||||
|
|
||||||
|
type
|
||||||
|
Ctx = object
|
||||||
|
partialParam: PSym
|
||||||
|
objType: PType
|
||||||
|
|
||||||
|
proc interestingVar(s: PSym): bool {.inline.} =
|
||||||
|
result = s.kind in {skVar, skLet, skTemp, skForVar, skResult} and
|
||||||
|
sfGlobal notin s.flags
|
||||||
|
|
||||||
|
proc lookupOrAdd(c: var Ctx; s: PSym; info: TLineInfo): PNode =
|
||||||
|
let field = addUniqueField(c.objType, s)
|
||||||
|
var deref = newNodeI(nkHiddenDeref, info)
|
||||||
|
deref.typ = c.objType
|
||||||
|
add(deref, newSymNode(c.partialParam, info))
|
||||||
|
result = newNodeI(nkDotExpr, info)
|
||||||
|
add(result, deref)
|
||||||
|
add(result, newSymNode(field))
|
||||||
|
result.typ = field.typ
|
||||||
|
|
||||||
|
proc liftLocals(n: PNode; i: int; c: var Ctx) =
|
||||||
|
let it = n[i]
|
||||||
|
case it.kind
|
||||||
|
of nkSym:
|
||||||
|
if interestingVar(it.sym):
|
||||||
|
n[i] = lookupOrAdd(c, it.sym, it.info)
|
||||||
|
of procDefs, nkTypeSection: discard
|
||||||
|
else:
|
||||||
|
for i in 0 ..< it.safeLen:
|
||||||
|
liftLocals(it, i, c)
|
||||||
|
|
||||||
|
proc lookupParam(params, dest: PNode): PSym =
|
||||||
|
if dest.kind != nkIdent: return nil
|
||||||
|
for i in 1 ..< params.len:
|
||||||
|
if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id:
|
||||||
|
return params[i].sym
|
||||||
|
|
||||||
|
proc liftLocalsIfRequested*(prc: PSym) =
|
||||||
|
let liftDest = getPragmaVal(prc.ast, wLiftLocals)
|
||||||
|
if liftDest == nil: return
|
||||||
|
let partialParam = lookupParam(prc.typ.n, liftDest)
|
||||||
|
if partialParam.isNil:
|
||||||
|
localError(liftDest.info, "'$1' is not a parameter of '$2'" %
|
||||||
|
[$liftDest, prc.name.s])
|
||||||
|
return
|
||||||
|
let objType = partialParam.typ.skipTypes(abstractPtrs)
|
||||||
|
if objType.kind != tyObject or tfPartial notin objType.flags:
|
||||||
|
localError(liftDest.info, "parameter '$1' is not a pointer to a partial object" % $liftDest)
|
||||||
|
return
|
||||||
|
var c = Ctx(partialParam: partialParam, objType: objType)
|
||||||
|
liftLocals(prc.ast, bodyPos, c)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue