system.locals is now a plugin for education

This commit is contained in:
Araq
2015-04-24 02:08:06 +02:00
parent c8bebe92e2
commit 0c947f31ba
8 changed files with 62 additions and 36 deletions

View File

@@ -15,6 +15,10 @@ const
import ast, astalgo, types, idents, magicsys, msgs, options
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 =
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
abstractInst).sons[i])

View 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

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

View File

@@ -16,7 +16,7 @@ import
procfind, lookups, rodread, pragmas, passes, semdata, semtypinst, sigmatch,
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
evaltempl, patterns, parampatterns, sempass2, nimfix.pretty, semmacrosanity,
semparallel, lowerings, plugins
semparallel, lowerings, plugins, plugins.active
when defined(nimfix):
import nimfix.prettybase

View File

@@ -101,34 +101,6 @@ proc semBindSym(c: PContext, n: PNode): PNode =
else:
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 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 mShallowCopy: result = semShallowCopy(c, n, flags)
of mNBindSym: result = semBindSym(c, n)
of mLocals: result = semLocals(c, n)
of mProcCall:
result = n
result.typ = n[1].typ

View File

@@ -102,10 +102,6 @@ proc semDestructorCheck(c: PContext, n: PNode, flags: TExprFlags) {.inline.} =
c.p.owner.kind notin {skTemplate, skMacro}:
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 =
result = semExpr(c, n)
if result.typ != nil:

View File

@@ -10,7 +10,7 @@
# Unforunately this cannot be a module yet:
#import vmdeps, vm
from math import sqrt, ln, log10, log2, exp, round, arccos, arcsin,
arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
arctan, arctan2, cos, cosh, hypot, sinh, sin, tan, tanh, pow, trunc,
floor, ceil, fmod
from os import getEnv, existsEnv, dirExists, fileExists

View File

@@ -3207,7 +3207,7 @@ when hostOS != "standalone":
if x == nil: x = 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
## 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