summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-11-28 02:43:41 +0100
committerAraq <rumpf_a@web.de>2014-11-28 02:43:41 +0100
commit105a0616a9da7c9c85adfa488a1db42eb17daafb (patch)
tree06142dcf57ce1fdfc5adcc5d389a3146dd9c228b
parentd456b882b16c44d7862682fd5e898868d5171ac5 (diff)
downloadNim-105a0616a9da7c9c85adfa488a1db42eb17daafb.tar.gz
implemented procCall builtin
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/nversion.nim6
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/semfold.nim4
-rw-r--r--compiler/semmagic.nim3
-rw-r--r--compiler/transf.nim14
-rw-r--r--doc/manual/procs.txt8
-rw-r--r--lib/system.nim48
-rw-r--r--tests/method/tmultim2.nim21
-rw-r--r--todo.txt1
-rw-r--r--web/news.txt2
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