Skip to content

Commit 105a061

Browse files
committed
implemented procCall builtin
1 parent d456b88 commit 105a061

File tree

11 files changed

+63
-52
lines changed

11 files changed

+63
-52
lines changed

compiler/ast.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,8 +566,8 @@ type
566566
mBool, mChar, mString, mCstring,
567567
mPointer, mEmptySet, mIntSetBaseType, mNil, mExpr, mStmt, mTypeDesc,
568568
mVoidType, mPNimrodNode, mShared, mGuarded, mLock, mSpawn, mDeepCopy,
569-
mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor,
570-
mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mAppType,
569+
mIsMainModule, mCompileDate, mCompileTime, mProcCall,
570+
mCpuEndian, mHostOS, mHostCPU, mAppType,
571571
mNaN, mInf, mNegInf,
572572
mCompileOption, mCompileOptionArg,
573573
mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, mNKind,

compiler/nversion.nim

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212

1313
const
1414
MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets?
15-
VersionMajor* = 0
16-
VersionMinor* = 10
17-
VersionPatch* = 1
18-
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
19-
15+
VersionAsString* = system.NimVersion
2016
RodFileVersion* = "1215" # modify this if the rod-format changes!
2117

compiler/semexprs.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,10 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
16491649
else:
16501650
result.typ = result[1].typ
16511651
result.add instantiateCreateFlowVarCall(c, result[1].typ, n.info).newSymNode
1652+
of mProcCall:
1653+
result = setMs(n, s)
1654+
result.sons[1] = semExpr(c, n.sons[1])
1655+
result.typ = n[1].typ
16521656
else: result = semDirectOp(c, n, flags)
16531657

16541658
proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =

compiler/semfold.nim

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -613,10 +613,6 @@ proc getConstExpr(m: PSym, n: PNode): PNode =
613613
of mIsMainModule: result = newIntNodeT(ord(sfMainModule in m.flags), n)
614614
of mCompileDate: result = newStrNodeT(times.getDateStr(), n)
615615
of mCompileTime: result = newStrNodeT(times.getClockStr(), n)
616-
of mNimrodVersion: result = newStrNodeT(VersionAsString, n)
617-
of mNimrodMajor: result = newIntNodeT(VersionMajor, n)
618-
of mNimrodMinor: result = newIntNodeT(VersionMinor, n)
619-
of mNimrodPatch: result = newIntNodeT(VersionPatch, n)
620616
of mCpuEndian: result = newIntNodeT(ord(CPU[targetCPU].endian), n)
621617
of mHostOS: result = newStrNodeT(toLower(platform.OS[targetOS].name), n)
622618
of mHostCPU: result = newStrNodeT(platform.CPU[targetCPU].name.toLower, n)

compiler/semmagic.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
130130
of mShallowCopy: result = semShallowCopy(c, n, flags)
131131
of mNBindSym: result = semBindSym(c, n)
132132
of mLocals: result = semLocals(c, n)
133+
of mProcCall:
134+
result = n
135+
result.typ = n[1].typ
133136
else: result = n

compiler/transf.nim

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -582,15 +582,15 @@ proc getMergeOp(n: PNode): PSym =
582582
else: discard
583583

584584
proc flattenTreeAux(d, a: PNode, op: PSym) =
585-
var op2 = getMergeOp(a)
585+
let op2 = getMergeOp(a)
586586
if op2 != nil and
587587
(op2.id == op.id or op.magic != mNone and op2.magic == op.magic):
588588
for i in countup(1, sonsLen(a)-1): flattenTreeAux(d, a.sons[i], op)
589589
else:
590590
addSon(d, copyTree(a))
591591

592592
proc flattenTree(root: PNode): PNode =
593-
var op = getMergeOp(root)
593+
let op = getMergeOp(root)
594594
if op != nil:
595595
result = copyNode(root)
596596
addSon(result, copyTree(root.sons[0]))
@@ -600,8 +600,9 @@ proc flattenTree(root: PNode): PNode =
600600

601601
proc transformCall(c: PTransf, n: PNode): PTransNode =
602602
var n = flattenTree(n)
603-
var op = getMergeOp(n)
604-
if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3):
603+
let op = getMergeOp(n)
604+
let magic = getMagic(n)
605+
if op != nil and op.magic != mNone and n.len >= 3:
605606
result = newTransNode(nkCall, n, 0)
606607
add(result, transform(c, n.sons[0]))
607608
var j = 1
@@ -616,9 +617,12 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
616617
inc(j)
617618
add(result, a.PTransNode)
618619
if len(result) == 2: result = result[1]
619-
elif getMagic(n) == mNBindSym:
620+
elif magic == mNBindSym:
620621
# for bindSym(myconst) we MUST NOT perform constant folding:
621622
result = n.PTransNode
623+
elif magic == mProcCall:
624+
# but do not change to its dispatcher:
625+
result = transformSons(c, n[1])
622626
else:
623627
let s = transformSons(c, n).PNode
624628
# bugfix: check after 'transformSons' if it's still a method call:

doc/manual/procs.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ the best match for the arguments. Example:
1616

1717
.. code-block:: nim
1818

19-
proc toLower(c: Char): Char = # toLower for characters
19+
proc toLower(c: char): char = # toLower for characters
2020
if c in {'A'..'Z'}:
2121
result = chr(ord(c) + (ord('a') - ord('A')))
2222
else:
@@ -150,8 +150,8 @@ means ``echo f 1, f 2`` is parsed as ``echo(f(1), f(2))`` and not as
150150
more argument in this case:
151151

152152
.. code-block:: nim
153-
proc optarg(x:int, y:int = 0):int = x + y
154-
proc singlearg(x:int):int = 20*x
153+
proc optarg(x: int, y: int = 0): int = x + y
154+
proc singlearg(x: int): int = 20*x
155155

156156
echo optarg 1, " ", singlearg 2 # prints "1 40"
157157

@@ -237,7 +237,7 @@ The following builtin procs cannot be overloaded for reasons of implementation
237237
simplicity (they require specialized semantic checking)::
238238

239239
declared, defined, definedInScope, compiles, low, high, sizeOf,
240-
is, of, shallowCopy, getAst, astToStr, spawn
240+
is, of, shallowCopy, getAst, astToStr, spawn, procCall
241241

242242
Thus they act more like keywords than like ordinary identifiers; unlike a
243243
keyword however, a redefinition may `shadow`:idx: the definition in

lib/system.nim

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,22 +1016,6 @@ const
10161016
## is the time of compilation as a string of the form
10171017
## ``HH:MM:SS``. This works thanks to compiler magic.
10181018
1019-
NimVersion* {.magic: "NimrodVersion"}: string = "0.0.0"
1020-
## is the version of Nim as a string.
1021-
## This works thanks to compiler magic.
1022-
1023-
NimMajor* {.magic: "NimrodMajor"}: int = 0
1024-
## is the major number of Nim's version.
1025-
## This works thanks to compiler magic.
1026-
1027-
NimMinor* {.magic: "NimrodMinor"}: int = 0
1028-
## is the minor number of Nim's version.
1029-
## This works thanks to compiler magic.
1030-
1031-
NimPatch* {.magic: "NimrodPatch"}: int = 0
1032-
## is the patch number of Nim's version.
1033-
## This works thanks to compiler magic.
1034-
10351019
cpuEndian* {.magic: "CpuEndian"}: Endianness = littleEndian
10361020
## is the endianness of the target CPU. This is a valuable piece of
10371021
## information for low-level code only. This works thanks to compiler
@@ -1048,9 +1032,6 @@ const
10481032
10491033
seqShallowFlag = low(int)
10501034
1051-
{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion,
1052-
NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].}
1053-
10541035
proc compileOption*(option: string): bool {.
10551036
magic: "CompileOption", noSideEffect.}
10561037
## can be used to determine an on|off compile-time option. Example:
@@ -1470,11 +1451,11 @@ template `>%` *(x, y: expr): expr {.immediate.} = y <% x
14701451
## treats `x` and `y` as unsigned and compares them.
14711452
## Returns true iff ``unsigned(x) > unsigned(y)``.
14721453
1473-
proc `$` *(x: int): string {.magic: "IntToStr", noSideEffect.}
1454+
proc `$`*(x: int): string {.magic: "IntToStr", noSideEffect.}
14741455
## The stringify operator for an integer argument. Returns `x`
14751456
## converted to a decimal string.
14761457
1477-
proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
1458+
proc `$`*(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
14781459
## The stringify operator for an integer argument. Returns `x`
14791460
## converted to a decimal string.
14801461
@@ -1529,6 +1510,20 @@ const
15291510
## that you cannot compare a floating point value to this value
15301511
## and expect a reasonable result - use the `classify` procedure
15311512
## in the module ``math`` for checking for NaN.
1513+
NimMajor*: int = 0
1514+
## is the major number of Nim's version.
1515+
1516+
NimMinor*: int = 10
1517+
## is the minor number of Nim's version.
1518+
1519+
NimPatch*: int = 1
1520+
## is the patch number of Nim's version.
1521+
1522+
NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
1523+
## is the version of Nim as a string.
1524+
1525+
{.deprecated: [TEndian: Endianness, NimrodVersion: NimVersion,
1526+
NimrodMajor: NimMajor, NimrodMinor: NimMinor, NimrodPatch: NimPatch].}
15321527
15331528
# GC interface:
15341529
@@ -3104,7 +3099,7 @@ proc locals*(): RootObj {.magic: "Locals", noSideEffect.} =
31043099
## generates a tuple constructor expression listing all the local variables
31053100
## in the current scope. This is quite fast as it does not rely
31063101
## on any debug or runtime information. Note that in constrast to what
3107-
## the official signature says, the return type is not ``TObject`` but a
3102+
## the official signature says, the return type is not ``RootObj`` but a
31083103
## tuple of a structure that depends on the current scope. Example:
31093104
##
31103105
## .. code-block:: nim
@@ -3132,4 +3127,13 @@ when hostOS != "standalone" and not defined(NimrodVM) and not defined(JS):
31323127
31333128
include "system/deepcopy"
31343129
3130+
proc procCall*(x: expr) {.magic: "ProcCall".} =
3131+
## special magic to prohibit dynamic binding for `method`:idx: calls.
3132+
## This is similar to `super`:idx: in ordinary OO languages.
3133+
##
3134+
## .. code-block:: nim
3135+
## # 'someMethod' will be resolved fully statically:
3136+
## procCall someMethod(a, b)
3137+
discard
3138+
31353139
{.pop.} #{.push warning[GcMem]: off.}

tests/method/tmultim2.nim

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
discard """
22
file: "tmultim2.nim"
3-
output: "collide: unit, thing collide: unit, thing collide: thing, unit"
3+
output: '''collide: unit, thing
4+
collide: unit, thing
5+
collide: thing, unit
6+
collide: thing, thing'''
47
"""
58
# Test multi methods
69

@@ -12,25 +15,25 @@ type
1215
a, b: int
1316

1417
method collide(a, b: TThing) {.inline.} =
15-
quit "to override!"
18+
echo "collide: thing, thing"
1619

1720
method collide(a: TThing, b: TUnit) {.inline.} =
18-
write stdout, "collide: thing, unit "
21+
echo "collide: thing, unit"
1922

2023
method collide(a: TUnit, b: TThing) {.inline.} =
21-
write stdout, "collide: unit, thing "
24+
echo "collide: unit, thing"
2225

2326
proc test(a, b: TThing) {.inline.} =
2427
collide(a, b)
2528

29+
proc staticCollide(a, b: TThing) {.inline.} =
30+
procCall collide(a, b)
31+
32+
2633
var
2734
a: TThing
2835
b, c: TUnit
2936
collide(b, c) # ambiguous (unit, thing) or (thing, unit)? -> prefer unit, thing!
3037
test(b, c)
3138
collide(a, b)
32-
#OUT collide: unit, thing collide: unit, thing collide: thing, unit
33-
34-
35-
36-
39+
staticCollide(a, b)

todo.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ version 0.10
22
============
33

44
- make nimble part of the distribution
5-
- implement 'procCall'
65
- split idetools into separate tool
76
- split docgen into separate tool
87

web/news.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ News
3636
lock levels and object field ``guards``.
3737
- The ``parallel`` statement has been implemented.
3838
- ``deepCopy`` has been added to the language.
39+
- The builtin ``procCall`` can be used to get ``super``-like functionality
40+
for multi methods.
3941

4042

4143
Compiler Additions

0 commit comments

Comments
 (0)