implemented undocumented '.liftLocals' feature

This commit is contained in:
Andreas Rumpf
2017-11-02 10:42:11 +01:00
parent 31619c2a83
commit bd19b5f4d3
5 changed files with 35 additions and 7 deletions

View File

@@ -182,8 +182,9 @@ proc addField*(obj: PType; s: PSym) =
field.position = sonsLen(obj.n)
addSon(obj.n, newSymNode(field))
proc addUniqueField*(obj: PType; s: PSym) =
if lookupInRecord(obj.n, s.id) == nil:
proc addUniqueField*(obj: PType; s: PSym): PSym {.discardable.} =
result = lookupInRecord(obj.n, s.id)
if result == nil:
var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info)
field.id = -s.id
let t = skipIntLit(s.typ)
@@ -191,6 +192,7 @@ proc addUniqueField*(obj: PType; s: PSym) =
assert t.kind != tyStmt
field.position = sonsLen(obj.n)
addSon(obj.n, newSymNode(field))
result = field
proc newDotExpr(obj, b: PSym): PNode =
result = newNodeI(nkDotExpr, obj.info)

View File

@@ -25,7 +25,7 @@ const
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
wOverride, wConstructor, wExportNims, wUsed}
wOverride, wConstructor, wExportNims, wUsed, wLiftLocals}
converterPragmas* = procPragmas
methodPragmas* = procPragmas+{wBase}-{wImportCpp}
templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
@@ -70,6 +70,14 @@ const
wThread, wRaises, wLocks, wTags, wGcSafe}
allRoutinePragmas* = methodPragmas + iteratorPragmas + lambdaPragmas
proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode =
let p = procAst[pragmasPos]
if p.kind == nkEmpty: return nil
for it in p:
if it.kind == nkExprColonExpr and it[0].kind == nkIdent and
it[0].ident.id == ord(name):
return it[1]
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
# implementation
@@ -978,6 +986,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
noVal(it)
if sym == nil: invalidPragma(it)
else: sym.flags.incl sfUsed
of wLiftLocals: discard
else: invalidPragma(it)
else: invalidPragma(it)

View File

@@ -21,7 +21,7 @@
import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
idents, renderer, types, passes, semfold, magicsys, cgmeth, rodread,
lambdalifting, sempass2, lowerings, lookups, destroyer
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals
type
PTransNode* = distinct PNode
@@ -978,6 +978,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode =
liftDefer(c, result)
#result = liftLambdas(prc, result)
when useEffectSystem: trackProc(prc, result)
liftLocalsIfRequested(prc)
if c.needsDestroyPass and newDestructors:
result = injectDestructorCalls(prc, result)
incl(result.flags, nfTransf)

View File

@@ -66,7 +66,7 @@ type
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
wAsmNoStackFrame,
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
wPartial, wExplain,
wPartial, wExplain, wLiftLocals,
wAuto, wBool, wCatch, wChar, wClass,
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
@@ -152,7 +152,7 @@ const
"computedgoto", "injectstmt", "experimental",
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
"guard", "locks", "partial", "explain",
"guard", "locks", "partial", "explain", "liftlocals",
"auto", "bool", "catch", "char", "class",
"const_cast", "default", "delete", "double",

View File

@@ -1,6 +1,8 @@
discard """
output: '''(foo: 38, other: string here)
43'''
43
100
90'''
"""
type
@@ -17,3 +19,17 @@ proc my(f: Foo) =
var g: Foo
new(g)
my(g)
type
FooTask {.partial.} = ref object of RootObj
proc foo(t: FooTask) {.liftLocals: t.} =
var x = 90
if true:
var x = 10
while x < 100:
inc x
echo x
echo x
foo(FooTask())