system.locals is now a plugin for education
This commit is contained in:
parent
c8bebe92e2
commit
0c947f31ba
8 changed files with 62 additions and 36 deletions
|
|
@ -15,6 +15,10 @@ const
|
||||||
import ast, astalgo, types, idents, magicsys, msgs, options
|
import ast, astalgo, types, idents, magicsys, msgs, options
|
||||||
from trees import getMagic
|
from trees import getMagic
|
||||||
|
|
||||||
|
proc newDeref*(n: PNode): PNode {.inline.} =
|
||||||
|
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
|
||||||
|
addSon(result, n)
|
||||||
|
|
||||||
proc newTupleAccess*(tup: PNode, i: int): PNode =
|
proc newTupleAccess*(tup: PNode, i: int): PNode =
|
||||||
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
|
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
|
||||||
abstractInst).sons[i])
|
abstractInst).sons[i])
|
||||||
|
|
|
||||||
13
compiler/plugins/active.nim
Normal file
13
compiler/plugins/active.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The Nim Compiler
|
||||||
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## Include file that imports all plugins that are active.
|
||||||
|
|
||||||
|
import
|
||||||
|
locals.locals
|
||||||
42
compiler/plugins/locals/locals.nim
Normal file
42
compiler/plugins/locals/locals.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The Nim Compiler
|
||||||
|
# (c) Copyright 2015 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## The builtin 'system.locals' implemented as a plugin.
|
||||||
|
|
||||||
|
import plugins, ast, astalgo, magicsys, lookups, semdata, lowerings
|
||||||
|
|
||||||
|
proc semLocals(c: PContext, n: PNode): PNode =
|
||||||
|
var counter = 0
|
||||||
|
var tupleType = newTypeS(tyTuple, c)
|
||||||
|
result = newNodeIT(nkPar, n.info, tupleType)
|
||||||
|
tupleType.n = newNodeI(nkRecList, n.info)
|
||||||
|
# for now we skip openarrays ...
|
||||||
|
for scope in walkScopes(c.currentScope):
|
||||||
|
if scope == c.topLevelScope: break
|
||||||
|
for it in items(scope.symbols):
|
||||||
|
# XXX parameters' owners are wrong for generics; this caused some pain
|
||||||
|
# for closures too; we should finally fix it.
|
||||||
|
#if it.owner != c.p.owner: return result
|
||||||
|
if it.kind in skLocalVars and
|
||||||
|
it.typ.skipTypes({tyGenericInst, tyVar}).kind notin
|
||||||
|
{tyVarargs, tyOpenArray, tyTypeDesc, tyStatic, tyExpr, tyStmt, tyEmpty}:
|
||||||
|
|
||||||
|
var field = newSym(skField, it.name, getCurrOwner(), n.info)
|
||||||
|
field.typ = it.typ.skipTypes({tyGenericInst, tyVar})
|
||||||
|
field.position = counter
|
||||||
|
inc(counter)
|
||||||
|
|
||||||
|
addSon(tupleType.n, newSymNode(field))
|
||||||
|
addSonSkipIntLit(tupleType, field.typ)
|
||||||
|
|
||||||
|
var a = newSymNode(it, result.info)
|
||||||
|
if it.typ.skipTypes({tyGenericInst}).kind == tyVar: a = newDeref(a)
|
||||||
|
result.add(a)
|
||||||
|
|
||||||
|
registerPlugin("stdlib", "system", "locals", semLocals)
|
||||||
|
|
@ -16,7 +16,7 @@ import
|
||||||
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
|
||||||
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
||||||
evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
|
evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
|
||||||
semparallel, lowerings, plugins
|
semparallel, lowerings, plugins, plugins.active
|
||||||
|
|
||||||
when defined(nimfix):
|
when defined(nimfix):
|
||||||
import nimfix.prettybase
|
import nimfix.prettybase
|
||||||
|
|
|
||||||
|
|
@ -101,34 +101,6 @@ proc semBindSym(c: PContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
localError(n.sons[1].info, errUndeclaredIdentifier, sl.strVal)
|
localError(n.sons[1].info, errUndeclaredIdentifier, sl.strVal)
|
||||||
|
|
||||||
proc semLocals(c: PContext, n: PNode): PNode =
|
|
||||||
var counter = 0
|
|
||||||
var tupleType = newTypeS(tyTuple, c)
|
|
||||||
result = newNodeIT(nkPar, n.info, tupleType)
|
|
||||||
tupleType.n = newNodeI(nkRecList, n.info)
|
|
||||||
# for now we skip openarrays ...
|
|
||||||
for scope in walkScopes(c.currentScope):
|
|
||||||
if scope == c.topLevelScope: break
|
|
||||||
for it in items(scope.symbols):
|
|
||||||
# XXX parameters' owners are wrong for generics; this caused some pain
|
|
||||||
# for closures too; we should finally fix it.
|
|
||||||
#if it.owner != c.p.owner: return result
|
|
||||||
if it.kind in skLocalVars and
|
|
||||||
it.typ.skipTypes({tyGenericInst, tyVar}).kind notin
|
|
||||||
{tyVarargs, tyOpenArray, tyTypeDesc, tyStatic, tyExpr, tyStmt, tyEmpty}:
|
|
||||||
|
|
||||||
var field = newSym(skField, it.name, getCurrOwner(), n.info)
|
|
||||||
field.typ = it.typ.skipTypes({tyGenericInst, tyVar})
|
|
||||||
field.position = counter
|
|
||||||
inc(counter)
|
|
||||||
|
|
||||||
addSon(tupleType.n, newSymNode(field))
|
|
||||||
addSonSkipIntLit(tupleType, field.typ)
|
|
||||||
|
|
||||||
var a = newSymNode(it, result.info)
|
|
||||||
if it.typ.skipTypes({tyGenericInst}).kind == tyVar: a = newDeref(a)
|
|
||||||
result.add(a)
|
|
||||||
|
|
||||||
proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode
|
proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||||
|
|
||||||
proc isStrangeArray(t: PType): bool =
|
proc isStrangeArray(t: PType): bool =
|
||||||
|
|
@ -161,7 +133,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
of mHigh, mLow: result = semLowHigh(c, n, n[0].sym.magic)
|
of mHigh, mLow: result = semLowHigh(c, n, n[0].sym.magic)
|
||||||
of mShallowCopy: result = semShallowCopy(c, n, flags)
|
of mShallowCopy: result = semShallowCopy(c, n, flags)
|
||||||
of mNBindSym: result = semBindSym(c, n)
|
of mNBindSym: result = semBindSym(c, n)
|
||||||
of mLocals: result = semLocals(c, n)
|
|
||||||
of mProcCall:
|
of mProcCall:
|
||||||
result = n
|
result = n
|
||||||
result.typ = n[1].typ
|
result.typ = n[1].typ
|
||||||
|
|
|
||||||
|
|
@ -102,10 +102,6 @@ proc semDestructorCheck(c: PContext, n: PNode, flags: TExprFlags) {.inline.} =
|
||||||
c.p.owner.kind notin {skTemplate, skMacro}:
|
c.p.owner.kind notin {skTemplate, skMacro}:
|
||||||
localError(n.info, errGenerated, "value expected, but got a type")
|
localError(n.info, errGenerated, "value expected, but got a type")
|
||||||
|
|
||||||
proc newDeref(n: PNode): PNode {.inline.} =
|
|
||||||
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
|
|
||||||
addSon(result, n)
|
|
||||||
|
|
||||||
proc semExprBranch(c: PContext, n: PNode): PNode =
|
proc semExprBranch(c: PContext, n: PNode): PNode =
|
||||||
result = semExpr(c, n)
|
result = semExpr(c, n)
|
||||||
if result.typ != nil:
|
if result.typ != nil:
|
||||||
|
|
|
||||||
|
|
@ -3207,7 +3207,7 @@ when hostOS != "standalone":
|
||||||
if x == nil: x = y
|
if x == nil: x = y
|
||||||
else: x.add(y)
|
else: x.add(y)
|
||||||
|
|
||||||
proc locals*(): RootObj {.magic: "Locals", noSideEffect.} =
|
proc locals*(): RootObj {.magic: "Plugin", noSideEffect.} =
|
||||||
## generates a tuple constructor expression listing all the local variables
|
## generates a tuple constructor expression listing all the local variables
|
||||||
## in the current scope. This is quite fast as it does not rely
|
## in the current scope. This is quite fast as it does not rely
|
||||||
## on any debug or runtime information. Note that in constrast to what
|
## on any debug or runtime information. Note that in constrast to what
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue