From 751232dc7cf81607ecd788f7f057222236f24b4d Mon Sep 17 00:00:00 2001 From: Araq Date: Sun, 19 Apr 2015 02:42:40 +0200 Subject: implements .goto support for variables --- compiler/ast.nim | 1 + 1 file changed, 1 insertion(+) (limited to 'compiler/ast.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index 6bfaad527..55923b54c 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -296,6 +296,7 @@ const sfCompileToCpp* = sfInfixCall # compile the module as C++ code sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code sfExperimental* = sfOverriden # module uses the .experimental switch + sfGoto* = sfOverriden # var is used for 'goto' code generation const # getting ready for the future expr/stmt merge -- cgit 1.4.1-2-gfad0 From e55f5d1fd4111c2112ef9139d776b23dd7a45497 Mon Sep 17 00:00:00 2001 From: Araq Date: Mon, 20 Apr 2015 21:25:49 +0200 Subject: fixes #2505, fixes #1853, fixes #2522 --- compiler/ast.nim | 4 +++- compiler/semdata.nim | 3 +++ compiler/semexprs.nim | 2 +- compiler/semtypes.nim | 4 ++-- compiler/semtypinst.nim | 4 +++- compiler/sigmatch.nim | 4 +++- tests/cpp/get_subsystem.nim | 22 ---------------------- tests/cpp/tget_subsystem.nim | 23 +++++++++++++++++++++++ tests/cpp/tvector_iterator.nim | 19 +++++++++++++++++++ tests/cpp/vector_iterator.nim | 19 ------------------- tests/macros/typesapi2.nim | 4 ++-- tests/types/tisopr.nim | 41 +++++++++++++++++++++++++++++++++++++++-- 12 files changed, 98 insertions(+), 51 deletions(-) delete mode 100644 tests/cpp/get_subsystem.nim create mode 100644 tests/cpp/tget_subsystem.nim create mode 100644 tests/cpp/tvector_iterator.nim delete mode 100644 tests/cpp/vector_iterator.nim (limited to 'compiler/ast.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index 4e22af287..1b14a8f79 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1171,7 +1171,9 @@ proc newType*(kind: TTypeKind, owner: PSym): PType = result.lockLevel = UnspecifiedLockLevel when debugIds: registerId(result) - #if result.id < 2000: + #if result.id == 92231: + # echo "KNID ", kind + # writeStackTrace() # messageOut(typeKindToStr[kind] & ' has id: ' & toString(result.id)) proc mergeLoc(a: var TLoc, b: TLoc) = diff --git a/compiler/semdata.nim b/compiler/semdata.nim index cf7a52ff5..1c2720006 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -247,6 +247,7 @@ proc makeAndType*(c: PContext, t1, t2: PType): PType = propagateToOwner(result, t1) propagateToOwner(result, t2) result.flags.incl((t1.flags + t2.flags) * {tfHasStatic}) + result.flags.incl tfHasMeta proc makeOrType*(c: PContext, t1, t2: PType): PType = result = newTypeS(tyOr, c) @@ -254,12 +255,14 @@ proc makeOrType*(c: PContext, t1, t2: PType): PType = propagateToOwner(result, t1) propagateToOwner(result, t2) result.flags.incl((t1.flags + t2.flags) * {tfHasStatic}) + result.flags.incl tfHasMeta proc makeNotType*(c: PContext, t1: PType): PType = result = newTypeS(tyNot, c) result.sons = @[t1] propagateToOwner(result, t1) result.flags.incl(t1.flags * {tfHasStatic}) + result.flags.incl tfHasMeta proc nMinusOne*(n: PNode): PNode = result = newNode(nkCall, n.info, @[ diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index c5bfbfa92..eb8d0c561 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -389,7 +389,7 @@ proc isOpImpl(c: PContext, n: PNode): PNode = maybeLiftType(t2, c, n.info) var m: TCandidate initCandidate(c, m, t2) - let match = typeRel(m, t2, t1) != isNone + let match = typeRel(m, t2, t1) >= isSubtype # isNone result = newIntNode(nkIntLit, ord(match)) result.typ = n.typ diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 4a45da2f9..9e36341bb 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -834,7 +834,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, cp.kind = tyUserTypeClassInst return addImplicitGeneric(cp) - for i in 1 .. (paramType.sons.len - 2): + for i in 1 .. paramType.len-2: var lifted = liftingWalk(paramType.sons[i]) if lifted != nil: paramType.sons[i] = lifted @@ -847,7 +847,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.shouldHaveMeta of tyGenericInvocation: - for i in 1 .. - static T* getSubsystem() { return new T; } -}; - -""".} - -type Input {.importcpp: "System::Input".} = object -proc getSubsystem*[T](): ptr T {.importcpp: "SystemManager::getSubsystem<'*0>()".} - -let input: ptr Input = getSubsystem[Input]() - diff --git a/tests/cpp/tget_subsystem.nim b/tests/cpp/tget_subsystem.nim new file mode 100644 index 000000000..461914739 --- /dev/null +++ b/tests/cpp/tget_subsystem.nim @@ -0,0 +1,23 @@ +discard """ + cmd: "nim cpp $file" +""" + +{.emit: """ + +namespace System { + struct Input {}; +} + +struct SystemManager { + template + static T* getSubsystem() { return new T; } +}; + +""".} + +type Input {.importcpp: "System::Input".} = object +proc getSubsystem*[T](): ptr T {. + importcpp: "SystemManager::getSubsystem<'*0>()", nodecl.} + +let input: ptr Input = getSubsystem[Input]() + diff --git a/tests/cpp/tvector_iterator.nim b/tests/cpp/tvector_iterator.nim new file mode 100644 index 000000000..cb5ab33af --- /dev/null +++ b/tests/cpp/tvector_iterator.nim @@ -0,0 +1,19 @@ +discard """ + cmd: "nim cpp $file" +""" + +{.emit: """ + +template +struct Vector { + struct Iterator {}; +}; + +""".} + +type + Vector {.importcpp: "Vector".} [T] = object + VectorIterator {.importcpp: "Vector<'0>::Iterator".} [T] = object + +var x: VectorIterator[void] + diff --git a/tests/cpp/vector_iterator.nim b/tests/cpp/vector_iterator.nim deleted file mode 100644 index cb5ab33af..000000000 --- a/tests/cpp/vector_iterator.nim +++ /dev/null @@ -1,19 +0,0 @@ -discard """ - cmd: "nim cpp $file" -""" - -{.emit: """ - -template -struct Vector { - struct Iterator {}; -}; - -""".} - -type - Vector {.importcpp: "Vector".} [T] = object - VectorIterator {.importcpp: "Vector<'0>::Iterator".} [T] = object - -var x: VectorIterator[void] - diff --git a/tests/macros/typesapi2.nim b/tests/macros/typesapi2.nim index 016295ba4..2e59d2154 100644 --- a/tests/macros/typesapi2.nim +++ b/tests/macros/typesapi2.nim @@ -1,4 +1,4 @@ -# tests to see if a symbol returned from macros.getType() can +# tests to see if a symbol returned from macros.getType() can # be used as a type import macros @@ -20,7 +20,7 @@ static: assert iii is TestFN proc foo11 : testTypesym(void) = echo "HI!" -static: assert foo11 is proc():void +static: assert foo11 is (proc():void {.nimcall.}) var sss: testTypesym(seq[int]) static: assert sss is seq[int] diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim index 8b7fe4e46..b9acfa5fb 100644 --- a/tests/types/tisopr.nim +++ b/tests/types/tisopr.nim @@ -1,5 +1,11 @@ discard """ - output: '''true true false yes''' + output: '''true true false yes +false +false +false +true +true +no''' """ proc IsVoid[T](): string = @@ -28,7 +34,7 @@ no s.items is iterator: float yes s.items is iterator: TNumber no s.items is iterator: object -type +type Iter[T] = iterator: T yes s.items is Iter[TNumber] @@ -51,3 +57,34 @@ yes Foo[4, int] is Bar[int] no Foo[4, int] is Baz[4] yes Foo[4, float] is Baz[4] + +# bug #2505 + +echo(8'i8 is int32) + +# bug #1853 +type SeqOrSet[E] = seq[E] or set[E] +type SeqOfInt = seq[int] +type SeqOrSetOfInt = SeqOrSet[int] + +# This prints "false", which seems less correct that (1) printing "true" or (2) +# raising a compiler error. +echo seq is SeqOrSet + +# This prints "false", as expected. +echo seq is SeqOrSetOfInt + +# This prints "true", as expected. +echo SeqOfInt is SeqOrSet + +# This causes an internal error (filename: compiler/semtypes.nim, line: 685). +echo SeqOfInt is SeqOrSetOfInt + +# bug #2522 +proc test[T](x: T) = + when T is typedesc: + echo "yes" + else: + echo "no" + +test(7) -- cgit 1.4.1-2-gfad0 From aacaa8f171cdddcf6051f9864a53a2d9e2dd3601 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 21 Apr 2015 11:55:55 +0200 Subject: cleaned up some magics to make room for new magics; added '..<' and '..^' templates --- compiler/ast.nim | 10 +++++----- compiler/ccgexprs.nim | 3 --- compiler/guards.nim | 4 ++-- compiler/jsgen.nim | 6 ------ compiler/vmgen.nim | 4 ++-- lib/system.nim | 16 +++++++++++++--- todo.txt | 1 + 7 files changed, 23 insertions(+), 21 deletions(-) (limited to 'compiler/ast.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index 1b14a8f79..8556977a1 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1,7 +1,7 @@ # # # The Nim Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -542,7 +542,7 @@ type mAddF64, mSubF64, mMulF64, mDivF64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, - mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64, + mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinF64, mMaxF64, mAddU, mSubU, mMulU, mDivU, mModU, mEqI, mLeI, mLtI, @@ -551,7 +551,7 @@ type mEqEnum, mLeEnum, mLtEnum, mEqCh, mLeCh, mLtCh, mEqB, mLeB, mLtB, mEqRef, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor, mEqProc, mUnaryMinusI, mUnaryMinusI64, mAbsI, mAbsI64, mNot, - mUnaryPlusI, mBitnotI, mUnaryPlusI64, + mUnaryPlusI, mBitnotI, mBitnotI64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64, mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64, mToU8, mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt, mToBiggestInt, mCharToStr, mBoolToStr, @@ -594,7 +594,7 @@ const mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64, mDivI64, mModI64, mAddF64, mSubF64, mMulF64, mDivF64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, - mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64, + mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinF64, mMaxF64, mAddU, mSubU, mMulU, mDivU, mModU, mEqI, mLeI, mLtI, @@ -603,7 +603,7 @@ const mEqEnum, mLeEnum, mLtEnum, mEqCh, mLeCh, mLtCh, mEqB, mLeB, mLtB, mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor, mUnaryMinusI, mUnaryMinusI64, mAbsI, mAbsI64, mNot, - mUnaryPlusI, mBitnotI, mUnaryPlusI64, + mUnaryPlusI, mBitnotI, mBitnotI64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64, mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64, mToU8, mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt, mToBiggestInt, mCharToStr, mBoolToStr, diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index a468de6e5..54fd3cffd 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -566,8 +566,6 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = "($4)($1 & $2)", # BitandI64 "($4)($1 | $2)", # BitorI64 "($4)($1 ^ $2)", # BitxorI64 - "(($1 <= $2) ? $1 : $2)", # MinI64 - "(($1 >= $2) ? $1 : $2)", # MaxI64 "(($1 <= $2) ? $1 : $2)", # MinF64 "(($1 >= $2) ? $1 : $2)", # MaxF64 "($4)((NU$3)($1) + (NU$3)($2))", # AddU @@ -640,7 +638,6 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = unArithTab: array[mNot..mToBiggestInt, string] = ["!($1)", # Not "$1", # UnaryPlusI "($3)((NU$2) ~($1))", # BitnotI - "$1", # UnaryPlusI64 "($3)((NU$2) ~($1))", # BitnotI64 "$1", # UnaryPlusF64 "-($1)", # UnaryMinusF64 diff --git a/compiler/guards.nim b/compiler/guards.nim index cedd2be2b..1217bc6f1 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -34,8 +34,8 @@ const someMul = {mMulI, mMulI64, mMulF64} someDiv = {mDivI, mDivI64, mDivF64} someMod = {mModI, mModI64} - someMax = {mMaxI, mMaxI64, mMaxF64} - someMin = {mMinI, mMinI64, mMinF64} + someMax = {mMaxI, mMaxF64} + someMin = {mMinI, mMinF64} proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit} proc isLocation(n: PNode): bool = not n.isValue diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index c3f01774e..ce578bc52 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -281,8 +281,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "($1 & $2)", "($1 & $2)"], # BitandI64 ["", "", "($1 | $2)", "($1 | $2)"], # BitorI64 ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI64 - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI64 - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI64 ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 ["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU @@ -326,7 +324,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "!($1)", "!($1)"], # Not ["", "", "+($1)", "+($1)"], # UnaryPlusI ["", "", "~($1)", "~($1)"], # BitnotI - ["", "", "+($1)", "+($1)"], # UnaryPlusI64 ["", "", "~($1)", "~($1)"], # BitnotI64 ["", "", "+($1)", "+($1)"], # UnaryPlusF64 ["", "", "-($1)", "-($1)"], # UnaryMinusF64 @@ -383,8 +380,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "($1 & $2)", "($1 & $2)"], # BitandI64 ["", "", "($1 | $2)", "($1 | $2)"], # BitorI64 ["", "", "($1 ^ $2)", "($1 ^ $2)"], # BitxorI64 - ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinI64 - ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxI64 ["nimMin", "nimMin", "nimMin($1, $2)", "nimMin($1, $2)"], # MinF64 ["nimMax", "nimMax", "nimMax($1, $2)", "nimMax($1, $2)"], # MaxF64 ["addU", "addU", "addU($1, $2)", "addU($1, $2)"], # addU @@ -428,7 +423,6 @@ const # magic checked op; magic unchecked op; checked op; unchecked op ["", "", "not ($1)", "not ($1)"], # Not ["", "", "+($1)", "+($1)"], # UnaryPlusI ["", "", "~($1)", "~($1)"], # BitnotI - ["", "", "+($1)", "+($1)"], # UnaryPlusI64 ["", "", "~($1)", "~($1)"], # BitnotI64 ["", "", "+($1)", "+($1)"], # UnaryPlusF64 ["", "", "-($1)", "-($1)"], # UnaryMinusF64 diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 4526687c9..f1cbe70b6 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -791,7 +791,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = genUnaryABC(c, n, dest, opcUnaryMinusInt) genNarrow(c, n, dest) of mUnaryMinusF64: genUnaryABC(c, n, dest, opcUnaryMinusFloat) - of mUnaryPlusI, mUnaryPlusI64, mUnaryPlusF64: gen(c, n.sons[1], dest) + of mUnaryPlusI, mUnaryPlusF64: gen(c, n.sons[1], dest) of mBitnotI, mBitnotI64: genUnaryABC(c, n, dest, opcBitnotInt) genNarrowU(c, n, dest) @@ -1008,7 +1008,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = if dest < 0: dest = c.getTemp(n.typ) c.gABC(n, opcCallSite, dest) of mNGenSym: genBinaryABC(c, n, dest, opcGenSym) - of mMinI, mMaxI, mMinI64, mMaxI64, mAbsF64, mMinF64, mMaxF64, mAbsI, + of mMinI, mMaxI, mAbsF64, mMinF64, mMaxF64, mAbsI, mAbsI64, mDotDot: c.genCall(n, dest) of mExpandToAst: diff --git a/lib/system.nim b/lib/system.nim index ac6c3a38f..25475c75b 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -663,7 +663,7 @@ proc `+` *(x: int): int {.magic: "UnaryPlusI", noSideEffect.} proc `+` *(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect.} proc `+` *(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect.} proc `+` *(x: int32): int32 {.magic: "UnaryPlusI", noSideEffect.} -proc `+` *(x: int64): int64 {.magic: "UnaryPlusI64", noSideEffect.} +proc `+` *(x: int64): int64 {.magic: "UnaryPlusI", noSideEffect.} ## Unary `+` operator for an integer. Has no effect. proc `-` *(x: int): int {.magic: "UnaryMinusI", noSideEffect.} @@ -1638,7 +1638,7 @@ proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.} = if x <= y: x else: y proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} = if x <= y: x else: y -proc min*(x, y: int64): int64 {.magic: "MinI64", noSideEffect.} = +proc min*(x, y: int64): int64 {.magic: "MinI", noSideEffect.} = ## The minimum value of two integers. if x <= y: x else: y @@ -1656,7 +1656,7 @@ proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.} = if y <= x: x else: y proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} = if y <= x: x else: y -proc max*(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.} = +proc max*(x, y: int64): int64 {.magic: "MaxI", noSideEffect.} = ## The maximum value of two integers. if y <= x: x else: y @@ -3256,4 +3256,14 @@ proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} = ## overloaded ``[]`` or ``[]=`` accessors. discard +template `..^`*(a, b: expr): expr = + ## a shortcut for '.. ^' to avoid the common gotcha that a space between + ## '..' and '^' is required. + a .. ^b + +template `..<`*(a, b: expr): expr = + ## a shortcut for '.. <' to avoid the common gotcha that a space between + ## '..' and '<' is required. + a .. Date: Wed, 22 Apr 2015 11:49:41 +0200 Subject: added '..^' and '..<' operators; 'nil' is allowed for 'len'; added plugin system to the compiler --- compiler/ast.nim | 10 ++++++---- compiler/ccgexprs.nim | 17 +++++++++++------ compiler/guards.nim | 3 ++- compiler/plugins.nim | 43 +++++++++++++++++++++++++++++++++++++++++++ compiler/sem.nim | 2 +- compiler/semfold.nim | 5 +++-- compiler/semmagic.nim | 7 +++++++ compiler/vmgen.nim | 4 ++-- lib/system.nim | 5 +++++ todo.txt | 7 +++++-- 10 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 compiler/plugins.nim (limited to 'compiler/ast.nim') diff --git a/compiler/ast.nim b/compiler/ast.nim index 8556977a1..3798410e8 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -530,12 +530,13 @@ type TMagic* = enum # symbols that require compiler magic: mNone, mDefined, mDefinedInScope, mCompiles, - mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof, + mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf, mAddr, mTypeOf, mRoof, mPlugin, mEcho, mShallowCopy, mSlurp, mStaticExec, mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst, mUnaryLt, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray, - mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref, - mGCunref, + mLengthStr, mLengthArray, mLengthSeq, mXLenStr, mXLenSeq, + mIncl, mExcl, mCard, mChr, + mGCref, mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64, mDivI64, mModI64, mSucc, mPred, @@ -590,7 +591,8 @@ type const ctfeWhitelist* = {mNone, mUnaryLt, mSucc, mPred, mInc, mDec, mOrd, mLengthOpenArray, - mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, + mLengthStr, mLengthArray, mLengthSeq, mXLenStr, mXLenSeq, + mIncl, mExcl, mCard, mChr, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64, mDivI64, mModI64, mAddF64, mSubF64, mMulF64, mDivF64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 54fd3cffd..93a9dd65d 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1352,15 +1352,15 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) = else: unaryExpr(p, e, d, "$1Len0") of tyCString: useStringh(p.module) - if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)") - else: unaryExpr(p, e, d, "strlen($1)") + if op == mHigh: unaryExpr(p, e, d, "($1 ? (strlen($1)-1) : -1)") + else: unaryExpr(p, e, d, "($1 ? strlen($1) : 0)") of tyString, tySequence: if not p.module.compileToCpp: - if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)") - else: unaryExpr(p, e, d, "$1->Sup.len") + if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->Sup.len-1) : -1)") + else: unaryExpr(p, e, d, "($1 ? $1->Sup.len : 0)") else: - if op == mHigh: unaryExpr(p, e, d, "($1->len-1)") - else: unaryExpr(p, e, d, "$1->len") + if op == mHigh: unaryExpr(p, e, d, "($1 ? ($1->len-1) : -1)") + else: unaryExpr(p, e, d, "($1 ? $1->len : 0)") of tyArray, tyArrayConstr: # YYY: length(sideeffect) is optimized away incorrectly? if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ))) @@ -1721,6 +1721,11 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mOrd: genOrd(p, e, d) of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray: genArrayLen(p, e, d, op) + of mXLenStr, mXLenSeq: + if not p.module.compileToCpp: + unaryExpr(p, e, d, "($1->Sup.len-1)") + else: + unaryExpr(p, e, d, "$1->len") of mGCref: unaryStmt(p, e, d, "#nimGCref($1);$n") of mGCunref: unaryStmt(p, e, d, "#nimGCunref($1);$n") of mSetLengthStr: genSetLengthStr(p, e, d) diff --git a/compiler/guards.nim b/compiler/guards.nim index 1217bc6f1..dc2b24add 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -22,7 +22,8 @@ const someLt = {mLtI, mLtI64, mLtF64, mLtU, mLtU64, mLtEnum, mLtCh, mLtB, mLtPtr, mLtStr} - someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq} + someLen = {mLengthOpenArray, mLengthStr, mLengthArray, mLengthSeq, + mXLenStr, mXLenSeq} someIn = {mInRange, mInSet} diff --git a/compiler/plugins.nim b/compiler/plugins.nim new file mode 100644 index 000000000..1c9b7b77b --- /dev/null +++ b/compiler/plugins.nim @@ -0,0 +1,43 @@ +# +# +# The Nim Compiler +# (c) Copyright 2015 Andreas Rumpf +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +## Plugin support for the Nim compiler. Right now there are no plugins and they +## need to be build with the compiler, no DLL support. + +import ast, semdata, idents + +type + Transformation* = proc (c: PContext; n: PNode): PNode {.nimcall.} + Plugin = ref object + fn, module, package: PIdent + t: Transformation + next: Plugin + +proc pluginMatches(p: Plugin; s: PSym): bool = + if s.name.id != p.fn.id: return false + let module = s.owner + if module == nil or module.kind != skModule or + module.name.id != p.module.id: return false + let package = module.owner + if package == nil or package.kind != skPackage or + package.name.id != p.package.id: return false + return true + +var head: Plugin + +proc getPlugin*(fn: PSym): Transformation = + var it = head + while it != nil: + if pluginMatches(it, fn): return it.t + it = it.next + +proc registerPlugin*(package, module, fn: string; t: Transformation) = + let oldHead = head + head = Plugin(fn: getIdent(fn), module: getIdent(module), + package: getIdent(package), t: t, next: oldHead) diff --git a/compiler/sem.nim b/compiler/sem.nim index 7eabaf491..965556a36 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -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 + semparallel, lowerings, plugins when defined(nimfix): import nimfix.prettybase diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 29e5d8aa2..0150a3405 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -286,9 +286,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of mNot: result = newIntNodeT(1 - getInt(a), n) of mCard: result = newIntNodeT(nimsets.cardSet(a), n) of mBitnotI, mBitnotI64: result = newIntNodeT(not getInt(a), n) - of mLengthStr: result = newIntNodeT(len(getStr(a)), n) + of mLengthStr, mXLenStr: result = newIntNodeT(len(getStr(a)), n) of mLengthArray: result = newIntNodeT(lengthOrd(a.typ), n) - of mLengthSeq, mLengthOpenArray: result = newIntNodeT(sonsLen(a), n) # BUGFIX + of mLengthSeq, mLengthOpenArray, mXLenSeq: + result = newIntNodeT(sonsLen(a), n) # BUGFIX of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away of mToFloat, mToBiggestFloat: result = newFloatNodeT(toFloat(int(getInt(a))), n) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index de7700be6..f15a55832 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -196,4 +196,11 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, result.add newSymNode(createMagic("-", mSubI), n.info) result.add lenExprB result.add n.sons[1] + of mPlugin: + let plugin = getPlugin(n[0].sym) + if plugin.isNil: + localError(n.info, "cannot find plugin " & n[0].sym.name.s) + result = n + else: + result = plugin(c, n) else: result = n diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index f1cbe70b6..b354061a9 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -742,9 +742,9 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = c.gABC(n, opcNewStr, dest, tmp) c.freeTemp(tmp) # XXX buggy - of mLengthOpenArray, mLengthArray, mLengthSeq: + of mLengthOpenArray, mLengthArray, mLengthSeq, mXLenSeq: genUnaryABI(c, n, dest, opcLenSeq) - of mLengthStr: + of mLengthStr, mXLenStr: genUnaryABI(c, n, dest, opcLenStr) of mIncl, mExcl: unused(n, dest) diff --git a/lib/system.nim b/lib/system.nim index 25475c75b..3e8c17324 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3266,4 +3266,9 @@ template `..<`*(a, b: expr): expr = ## '..' and '<' is required. a ..