diff options
-rw-r--r-- | compiler/ast.nim | 4 | ||||
-rw-r--r-- | compiler/nversion.nim | 6 | ||||
-rw-r--r-- | compiler/semexprs.nim | 4 | ||||
-rw-r--r-- | compiler/semfold.nim | 4 | ||||
-rw-r--r-- | compiler/semmagic.nim | 3 | ||||
-rw-r--r-- | compiler/transf.nim | 14 | ||||
-rw-r--r-- | doc/manual/procs.txt | 8 | ||||
-rw-r--r-- | lib/system.nim | 48 | ||||
-rw-r--r-- | tests/method/tmultim2.nim | 21 | ||||
-rw-r--r-- | todo.txt | 1 | ||||
-rw-r--r-- | web/news.txt | 2 |
11 files changed, 63 insertions, 52 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index ec309ba1a..62f2d105f 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -566,8 +566,8 @@ type mBool, mChar, mString, mCstring, mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc, mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy, - mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, - mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType, + mIsMainModule, mCompileDate, mCompileTime, mProcCall, + mCpuEndian, mHostOS, mHostCPU, mAppType, mNaN, mInf, mNegInf, mCompileOption, mCompileOptionArg, mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind, diff --git a/compiler/nversion.nim b/compiler/nversion.nim index 910ebfb59..8dc4b90b2 100644 --- a/compiler/nversion.nim +++ b/compiler/nversion.nim @@ -12,10 +12,6 @@ const MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets? - VersionMajor* = 0 - VersionMinor* = 10 - VersionPatch* = 1 - VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch - + VersionAsString* = system.NimVersion RodFileVersion* = "1215" # modify this if the rod-format changes! diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 544d59491..3ca80a9b1 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1649,6 +1649,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = else: result.typ = result[1].typ result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode + of mProcCall: + result = setMs(n, s) + result.sons[1] = semExpr(c, n.sons[1]) + result.typ = n[1].typ else: result = semDirectOp(c, n, flags) proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 1e92fb832..c7ae42548 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -613,10 +613,6 @@ proc getConstExpr(m: PSym, n: PNode): PNode = of mIsMainModule: result = newIntNodeT(ord(sfMainModule in m.flags), n) of mCompileDate: result = newStrNodeT(times.getDateStr(), n) of mCompileTime: result = newStrNodeT(times.getClockStr(), n) - of mNimrodVersion: result = newStrNodeT(VersionAsString, n) - of mNimrodMajor: result = newIntNodeT(VersionMajor, n) - of mNimrodMinor: result = newIntNodeT(VersionMinor, n) - of mNimrodPatch: result = newIntNodeT(VersionPatch, n) of mCpuEndian: result = newIntNodeT(ord(CPU[targetCPU].endian), n) of mHostOS: result = newStrNodeT(toLower(platform.OS[targetOS].name), n) of mHostCPU: result = newStrNodeT(platform.CPU[targetCPU].name.toLower, n) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index a72a6ab7d..d6c420955 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -130,4 +130,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, 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 else: result = n diff --git a/compiler/transf.nim b/compiler/transf.nim index 6196512ba..3409acb74 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -582,7 +582,7 @@ proc getMergeOp(n: PNode): PSym = else: discard proc flattenTreeAux(d, a: PNode, op: PSym) = - var op2 = getMergeOp(a) + let op2 = getMergeOp(a) if op2 != nil and (op2.id == op.id or op.magic != mNone and op2.magic == op.magic): for i in countup(1, sonsLen(a)-1): flattenTreeAux(d, a.sons[i], op) @@ -590,7 +590,7 @@ proc flattenTreeAux(d, a: PNode, op: PSym) = addSon(d, copyTree(a)) proc flattenTree(root: PNode): PNode = - var op = getMergeOp(root) + let op = getMergeOp(root) if op != nil: result = copyNode(root) addSon(result, copyTree(root.sons[0])) @@ -600,8 +600,9 @@ proc flattenTree(root: PNode): PNode = proc transformCall(c: PTransf, n: PNode): PTransNode = var n = flattenTree(n) - var op = getMergeOp(n) - if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3): + let op = getMergeOp(n) + let magic = getMagic(n) + if op != nil and op.magic != mNone and n.len >= 3: result = newTransNode(nkCall, n, 0) add(result, transform(c, n.sons[0])) var j = 1 @@ -616,9 +617,12 @@ proc transformCall(c: PTransf, n: PNode): PTransNode = inc(j) add(result, a.PTransNode) if len(result) == 2: result = result[1] - elif getMagic(n) == mNBindSym: + elif magic == mNBindSym: # for bindSym(myconst) we MUST NOT perform constant folding: result = n.PTransNode + elif magic == mProcCall: + # but do not change to its dispatcher: + result = transformSons(c, n[1]) else: let s = transformSons(c, n).PNode # bugfix: check after 'transformSons' if it's still a method call: diff --git a/doc/manual/procs.txt b/doc/manual/procs.txt index f48203c3b..d048615eb 100644 --- a/doc/manual/procs.txt +++ b/doc/manual/procs.txt @@ -16,7 +16,7 @@ the best match for the arguments. Example: .. code-block:: nim - proc toLower(c: Char): Char = # toLower for characters + proc toLower(c: char): char = # toLower for characters if c in {'A'..'Z'}: result = chr(ord(c) + (ord('a') - ord('A'))) else: @@ -150,8 +150,8 @@ means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as more argument in this case: .. code-block:: nim - proc optarg(x:int, y:int = 0):int = x + y - proc singlearg(x:int):int = 20*x + proc optarg(x: int, y: int = 0): int = x + y + proc singlearg(x: int): int = 20*x echo optarg 1, " ", singlearg 2 # prints "1 40" @@ -237,7 +237,7 @@ The following builtin procs cannot be overloaded for reasons of implementation simplicity (they require specialized semantic checking):: declared, defined, definedInScope, compiles, low, high, sizeOf, - is, of, shallowCopy, getAst, astToStr, spawn + is, of, shallowCopy, getAst, astToStr, spawn, procCall Thus they act more like keywords than like ordinary identifiers; unlike a keyword however, a redefinition may `shadow`:idx: the definition in diff --git a/lib/system.nim b/lib/system.nim index 460762efc..269dbb1e0 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1016,22 +1016,6 @@ const ## is the time of compilation as a string of the form ## ``HH:MM:SS``. This works thanks to compiler magic. - NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0" - ## is the version of Nim as a string. - ## This works thanks to compiler magic. - - NimMajor* {.magic: "NimrodMajor"}: int = 0 - ## is the major number of Nim's version. - ## This works thanks to compiler magic. - - NimMinor* {.magic: "NimrodMinor"}: int = 0 - ## is the minor number of Nim's version. - ## This works thanks to compiler magic. - - NimPatch* {.magic: "NimrodPatch"}: int = 0 - ## is the patch number of Nim's version. - ## This works thanks to compiler magic. - cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian ## is the endianness of the target CPU. This is a valuable piece of ## information for low-level code only. This works thanks to compiler @@ -1048,9 +1032,6 @@ const seqShallowFlag = low(int) -{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, - NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} - proc compileOption*(option: string): bool {. magic: "CompileOption", noSideEffect.} ## can be used to determine an on|off compile-time option. Example: @@ -1470,11 +1451,11 @@ template `>%` *(x, y: expr): expr {.immediate.} = y <% x ## treats `x` and `y` as unsigned and compares them. ## Returns true iff ``unsigned(x) > unsigned(y)``. -proc `$` *(x: int): string {.magic: "IntToStr", noSideEffect.} +proc `$`*(x: int): string {.magic: "IntToStr", noSideEffect.} ## The stringify operator for an integer argument. Returns `x` ## converted to a decimal string. -proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.} +proc `$`*(x: int64): string {.magic: "Int64ToStr", noSideEffect.} ## The stringify operator for an integer argument. Returns `x` ## converted to a decimal string. @@ -1529,6 +1510,20 @@ const ## that you cannot compare a floating point value to this value ## and expect a reasonable result - use the `classify` procedure ## in the module ``math`` for checking for NaN. + NimMajor*: int = 0 + ## is the major number of Nim's version. + + NimMinor*: int = 10 + ## is the minor number of Nim's version. + + NimPatch*: int = 1 + ## is the patch number of Nim's version. + + NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch + ## is the version of Nim as a string. + +{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion, + NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].} # GC interface: @@ -3104,7 +3099,7 @@ proc locals*(): RootObj {.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 + ## the official signature says, the return type is not ``RootObj`` but a ## tuple of a structure that depends on the current scope. Example: ## ## .. code-block:: nim @@ -3132,4 +3127,13 @@ when hostOS != "standalone" and not defined(NimrodVM) and not defined(JS): include "system/deepcopy" +proc procCall*(x: expr) {.magic: "ProcCall".} = + ## special magic to prohibit dynamic binding for `method`:idx: calls. + ## This is similar to `super`:idx: in ordinary OO languages. + ## + ## .. code-block:: nim + ## # 'someMethod' will be resolved fully statically: + ## procCall someMethod(a, b) + discard + {.pop.} #{.push warning[GcMem]: off.} diff --git a/tests/method/tmultim2.nim b/tests/method/tmultim2.nim index 75f652137..c5fb568a0 100644 --- a/tests/method/tmultim2.nim +++ b/tests/method/tmultim2.nim @@ -1,6 +1,9 @@ discard """ file: "tmultim2.nim" - output: "collide: unit, thing collide: unit, thing collide: thing, unit" + output: '''collide: unit, thing +collide: unit, thing +collide: thing, unit +collide: thing, thing''' """ # Test multi methods @@ -12,25 +15,25 @@ type a, b: int method collide(a, b: TThing) {.inline.} = - quit "to override!" + echo "collide: thing, thing" method collide(a: TThing, b: TUnit) {.inline.} = - write stdout, "collide: thing, unit " + echo "collide: thing, unit" method collide(a: TUnit, b: TThing) {.inline.} = - write stdout, "collide: unit, thing " + echo "collide: unit, thing" proc test(a, b: TThing) {.inline.} = collide(a, b) +proc staticCollide(a, b: TThing) {.inline.} = + procCall collide(a, b) + + var a: TThing b, c: TUnit collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing! test(b, c) collide(a, b) -#OUT collide: unit, thing collide: unit, thing collide: thing, unit - - - - +staticCollide(a, b) diff --git a/todo.txt b/todo.txt index a6ea31560..41db0b72f 100644 --- a/todo.txt +++ b/todo.txt @@ -2,7 +2,6 @@ version 0.10 ============ - make nimble part of the distribution -- implement 'procCall' - split idetools into separate tool - split docgen into separate tool diff --git a/web/news.txt b/web/news.txt index 0c3cedf35..fd9ac77c2 100644 --- a/web/news.txt +++ b/web/news.txt @@ -36,6 +36,8 @@ News lock levels and object field ``guards``. - The ``parallel`` statement has been implemented. - ``deepCopy`` has been added to the language. + - The builtin ``procCall`` can be used to get ``super``-like functionality + for multi methods. Compiler Additions |