implemented undocumented '.liftLocals' feature
This commit is contained in:
parent
31619c2a83
commit
bd19b5f4d3
5 changed files with 35 additions and 7 deletions
|
|
@ -182,8 +182,9 @@ proc addField*(obj: PType; s: PSym) =
|
||||||
field.position = sonsLen(obj.n)
|
field.position = sonsLen(obj.n)
|
||||||
addSon(obj.n, newSymNode(field))
|
addSon(obj.n, newSymNode(field))
|
||||||
|
|
||||||
proc addUniqueField*(obj: PType; s: PSym) =
|
proc addUniqueField*(obj: PType; s: PSym): PSym {.discardable.} =
|
||||||
if lookupInRecord(obj.n, s.id) == nil:
|
result = lookupInRecord(obj.n, s.id)
|
||||||
|
if result == nil:
|
||||||
var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info)
|
var field = newSym(skField, getIdent(s.name.s & $obj.n.len), s.owner, s.info)
|
||||||
field.id = -s.id
|
field.id = -s.id
|
||||||
let t = skipIntLit(s.typ)
|
let t = skipIntLit(s.typ)
|
||||||
|
|
@ -191,6 +192,7 @@ proc addUniqueField*(obj: PType; s: PSym) =
|
||||||
assert t.kind != tyStmt
|
assert t.kind != tyStmt
|
||||||
field.position = sonsLen(obj.n)
|
field.position = sonsLen(obj.n)
|
||||||
addSon(obj.n, newSymNode(field))
|
addSon(obj.n, newSymNode(field))
|
||||||
|
result = field
|
||||||
|
|
||||||
proc newDotExpr(obj, b: PSym): PNode =
|
proc newDotExpr(obj, b: PSym): PNode =
|
||||||
result = newNodeI(nkDotExpr, obj.info)
|
result = newNodeI(nkDotExpr, obj.info)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const
|
||||||
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
||||||
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
wAsmNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
||||||
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe,
|
||||||
wOverride, wConstructor, wExportNims, wUsed}
|
wOverride, wConstructor, wExportNims, wUsed, wLiftLocals}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas+{wBase}-{wImportCpp}
|
methodPragmas* = procPragmas+{wBase}-{wImportCpp}
|
||||||
templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
|
templatePragmas* = {wImmediate, wDeprecated, wError, wGensym, wInject, wDirty,
|
||||||
|
|
@ -70,6 +70,14 @@ const
|
||||||
wThread, wRaises, wLocks, wTags, wGcSafe}
|
wThread, wRaises, wLocks, wTags, wGcSafe}
|
||||||
allRoutinePragmas* = methodPragmas + iteratorPragmas + lambdaPragmas
|
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)
|
proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords)
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
|
|
@ -978,6 +986,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
noVal(it)
|
noVal(it)
|
||||||
if sym == nil: invalidPragma(it)
|
if sym == nil: invalidPragma(it)
|
||||||
else: sym.flags.incl sfUsed
|
else: sym.flags.incl sfUsed
|
||||||
|
of wLiftLocals: discard
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
import
|
import
|
||||||
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, os,
|
intsets, strutils, 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, lowerings, lookups, destroyer
|
lambdalifting, sempass2, lowerings, lookups, destroyer, liftlocals
|
||||||
|
|
||||||
type
|
type
|
||||||
PTransNode* = distinct PNode
|
PTransNode* = distinct PNode
|
||||||
|
|
@ -978,6 +978,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode =
|
||||||
liftDefer(c, result)
|
liftDefer(c, result)
|
||||||
#result = liftLambdas(prc, result)
|
#result = liftLambdas(prc, result)
|
||||||
when useEffectSystem: trackProc(prc, result)
|
when useEffectSystem: trackProc(prc, result)
|
||||||
|
liftLocalsIfRequested(prc)
|
||||||
if c.needsDestroyPass and newDestructors:
|
if c.needsDestroyPass and newDestructors:
|
||||||
result = injectDestructorCalls(prc, result)
|
result = injectDestructorCalls(prc, result)
|
||||||
incl(result.flags, nfTransf)
|
incl(result.flags, nfTransf)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ type
|
||||||
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
|
||||||
wAsmNoStackFrame,
|
wAsmNoStackFrame,
|
||||||
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
|
wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
|
||||||
wPartial, wExplain,
|
wPartial, wExplain, wLiftLocals,
|
||||||
|
|
||||||
wAuto, wBool, wCatch, wChar, wClass,
|
wAuto, wBool, wCatch, wChar, wClass,
|
||||||
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
|
wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
|
||||||
|
|
@ -152,7 +152,7 @@ const
|
||||||
"computedgoto", "injectstmt", "experimental",
|
"computedgoto", "injectstmt", "experimental",
|
||||||
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
"write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
|
||||||
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
|
"asmnostackframe", "implicitstatic", "global", "codegendecl", "unchecked",
|
||||||
"guard", "locks", "partial", "explain",
|
"guard", "locks", "partial", "explain", "liftlocals",
|
||||||
|
|
||||||
"auto", "bool", "catch", "char", "class",
|
"auto", "bool", "catch", "char", "class",
|
||||||
"const_cast", "default", "delete", "double",
|
"const_cast", "default", "delete", "double",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''(foo: 38, other: string here)
|
output: '''(foo: 38, other: string here)
|
||||||
43'''
|
43
|
||||||
|
100
|
||||||
|
90'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -17,3 +19,17 @@ proc my(f: Foo) =
|
||||||
var g: Foo
|
var g: Foo
|
||||||
new(g)
|
new(g)
|
||||||
my(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())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue