diff options
-rw-r--r-- | compiler/ast.nim | 28 | ||||
-rw-r--r-- | compiler/semexprs.nim | 3 | ||||
-rw-r--r-- | compiler/semmagic.nim | 30 | ||||
-rw-r--r-- | lib/system.nim | 7 | ||||
-rw-r--r-- | tests/run/tlocals.nim | 11 | ||||
-rw-r--r-- | todo.txt | 2 | ||||
-rw-r--r-- | web/news.txt | 1 |
7 files changed, 64 insertions, 18 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 5d420c6d2..b59c93950 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -455,12 +455,12 @@ type mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr, mAnd, mOr, mEqStr, mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT, - mConTArr, mConTT, mSlice, + mConTArr, mConTT, mSlice, mFields, mFieldPairs, mOmpParFor, - mAppendStrCh, mAppendStrStr, mAppendSeqElem, - mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, - mIsPartOf, mAstToStr, mRand, - mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, + mAppendStrCh, mAppendStrStr, mAppendSeqElem, + mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, + mIsPartOf, mAstToStr, mRand, + mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mNewStringOfCap, mReset, mArray, mOpenArray, mRange, mSet, mSeq, mVarargs, @@ -469,18 +469,18 @@ type mUInt, mUInt8, mUInt16, mUInt32, mUInt64, mFloat, mFloat32, mFloat64, mFloat128, mBool, mChar, mString, mCstring, - mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, + mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mVoidType, mPNimrodNode, - mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, - mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType, - mNaN, mInf, mNegInf, + mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, + mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType, + mNaN, mInf, mNegInf, mCompileOption, mCompileOptionArg, - mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind, - mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal, + mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind, + mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal, mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNLineInfo, - mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr, - mNBindSym, mNCallSite, - mEqIdent, mEqNimrodNode, mNHint, mNWarning, mNError, + mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr, + mNBindSym, mLocals, mNCallSite, + mEqIdent, mEqNimrodNode, mNHint, mNWarning, mNError, mInstantiationInfo, mGetTypeInfo # things that we can evaluate safely at compile time, even if not asked for it: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2cc0de371..7d5fdc4f2 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -25,7 +25,8 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: #raiseRecoverableError("") result = errorNode(c, n) - if result.typ != nil: + if result.typ != nil: + # XXX tyGenericInst here? if result.typ.kind == tyVar: result = newDeref(result) else: LocalError(n.info, errExprXHasNoType, diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 119e1ef19..31eb7a9d5 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2013 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -73,6 +73,33 @@ 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 i in countdown(c.tab.tos-1, ModuleTablePos+1): + for it in items(c.tab.stack[i]): + # 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, 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 magicsAfterOverloadResolution(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -86,5 +113,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mOrd: result = semOrd(c, n) of mShallowCopy: result = semShallowCopy(c, n, flags) of mNBindSym: result = semBindSym(c, n) + of mLocals: result = semLocals(c, n) else: result = n diff --git a/lib/system.nim b/lib/system.nim index 5bcd7b02d..08de426c4 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2548,3 +2548,10 @@ proc safeAdd*(x: var string, y: string) = if x == nil: x = y else: x.add(y) +proc locals*(): TObject {.magic: "Locals", 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 + ## the official signature says, the return type is not ``TObject`` but a + ## tuple of a structure that depends on the current scope. + nil diff --git a/tests/run/tlocals.nim b/tests/run/tlocals.nim new file mode 100644 index 000000000..94a34139b --- /dev/null +++ b/tests/run/tlocals.nim @@ -0,0 +1,11 @@ +discard """ + output: "(x: string here, a: 1, b: 3)" +""" + +proc simple[T](a, b: T) = + var + x = "string here" + echo locals() + +simple(1, 3) + diff --git a/todo.txt b/todo.txt index d159728e3..9b1082a81 100644 --- a/todo.txt +++ b/todo.txt @@ -13,7 +13,6 @@ version 0.9.2 - acyclic vs prunable; introduce GC hints - CGEN: ``restrict`` pragma + backend support; computed goto support - document NimMain and check whether it works for threading -- implement ``system.locals`` magic iterator Bugs @@ -27,7 +26,6 @@ Bugs - aporia.nim(968, 5) Error: ambiguous identifier: 'DELETE' -- use a qualifier - blocks can "export" an identifier but the CCG generates {} for them ... -- JS gen: fix exception handling - osproc execProcesses can deadlock if all processes fail (as experienced in c++ mode) - bootstrapping does not work in C++ mode diff --git a/web/news.txt b/web/news.txt index 7bd0e4f4f..2add6aefa 100644 --- a/web/news.txt +++ b/web/news.txt @@ -24,6 +24,7 @@ Library Additions - There is a new experimental mark&sweep GC which can be faster (or much slower) than the default GC. Enable with ``--gc:markAndSweep``. - Added ``system.onRaise`` to support a condition system. +- Added ``system.locals`` that provides access to a proc's locals. - Added ``macros.quote`` for AST quasi-quoting. - Added ``system.unsafeNew`` to support hacky variable length objects. - ``system.fields`` and ``system.fieldPairs`` support ``object`` too; they |