diff options
author | Araq <rumpf_a@web.de> | 2011-08-10 01:16:32 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-08-10 01:16:32 +0200 |
commit | d5dd4669df9827920e7e9f1864171c09ac15fbb2 (patch) | |
tree | 4b96b78dc0015d95da14c9b1553116958d160402 | |
parent | 72e7a98543e711164574664b0f280637fce28f89 (diff) | |
download | Nim-d5dd4669df9827920e7e9f1864171c09ac15fbb2.tar.gz |
further tests for var T result type; ttables test now fails :-(
-rwxr-xr-x | compiler/semstmts.nim | 3 | ||||
-rwxr-xr-x | doc/manual.txt | 320 | ||||
-rwxr-xr-x | tests/accept/run/ttables.nim | 3 | ||||
-rwxr-xr-x | todo.txt | 2 |
4 files changed, 167 insertions, 161 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index e88fed51a..86d5b0f26 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -178,12 +178,11 @@ proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) = if e.kind == tyVar: if n.sons[0].kind == nkPar: n.sons[0].sons[i] = takeImplicitAddr(c, n.sons[0].sons[i]) - elif n.sons[0].kind == nkHiddenSubConv and + elif n.sons[0].kind in {nkHiddenStdConv, nkHiddenSubConv} and n.sons[0].sons[1].kind == nkPar: var a = n.sons[0].sons[1] a.sons[i] = takeImplicitAddr(c, a.sons[i]) else: - debug n.sons[0] localError(n.sons[0].info, errXExpected, "tuple constructor") else: nil diff --git a/doc/manual.txt b/doc/manual.txt index bdb5f2298..50e94940a 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -1188,45 +1188,45 @@ currency. This can be solved with templates_. DefineCurrency(TDollar, int) DefineCurrency(TEuro, int) - + Void type ~~~~~~~~~ -The `void`:idx: type denotes the absense of any type. Parameters of -type ``void`` are treated as non-existent, a result ``void`` type means that -the procedure does not return a value: - -.. code-block:: nimrod - proc nothing(x, y: void): void = - echo "ha" - - nothing() # writes "ha" to stdout - -The ``void`` type is particularly useful for generic code: - -.. code-block:: nimrod - proc callProc[T](p: proc (x: T), x: T) = - when T is void: - p() - else: - p(x) - - proc intProc(x: int) = nil - proc emptyProc() = nil - - callProc[int](intProc, 12) - callProc[void](emptyProc) - -However, a ``void`` type cannot be inferred in generic code: - -.. code-block:: nimrod - callProc(emptyProc) - # Error: type mismatch: got (proc ()) - # but expected one of: - # callProc(p: proc (T), x: T) - -The ``void`` type is only valid for parameters and return types; other symbols -cannot have the type ``void``. +The `void`:idx: type denotes the absense of any type. Parameters of +type ``void`` are treated as non-existent, a result ``void`` type means that +the procedure does not return a value: + +.. code-block:: nimrod + proc nothing(x, y: void): void = + echo "ha" + + nothing() # writes "ha" to stdout + +The ``void`` type is particularly useful for generic code: + +.. code-block:: nimrod + proc callProc[T](p: proc (x: T), x: T) = + when T is void: + p() + else: + p(x) + + proc intProc(x: int) = nil + proc emptyProc() = nil + + callProc[int](intProc, 12) + callProc[void](emptyProc) + +However, a ``void`` type cannot be inferred in generic code: + +.. code-block:: nimrod + callProc(emptyProc) + # Error: type mismatch: got (proc ()) + # but expected one of: + # callProc(p: proc (T), x: T) + +The ``void`` type is only valid for parameters and return types; other symbols +cannot have the type ``void``. Type relations @@ -1249,7 +1249,7 @@ algorithm (in pseudo-code) determines type equality: incl(s, (a,b)) if a.kind == b.kind: case a.kind - of int, intXX, float, floatXX, char, string, cstring, pointer, + of int, intXX, float, floatXX, char, string, cstring, pointer, bool, nil, void: # leaf type: kinds identical; nothing more to check result = true @@ -2067,37 +2067,40 @@ One can use `tuple unpacking`:idx: to access the tuple's fields: var (x, y) = divmod(8, 5) # tuple unpacking assert x == 1 assert y == 3 - - + + Var return type ~~~~~~~~~~~~~~~ - -A proc, converter or iterator may return a ``var`` type which means that the -returned value is an l-value and can be modified by the caller: - -.. code-block:: nimrod + +A proc, converter or iterator may return a ``var`` type which means that the +returned value is an l-value and can be modified by the caller: + +.. code-block:: nimrod var g = 0 - - proc WriteAccessToG(): var int = - result = g - - WriteAccessToG() = 6 - assert g == 6 - -It is a compile time error if the implicitely introduced pointer could be -used to access a location beyond its lifetime: - -.. code-block:: nimrod - proc WriteAccessToG(): var int = + + proc WriteAccessToG(): var int = + result = g + + WriteAccessToG() = 6 + assert g == 6 + +It is a compile time error if the implicitely introduced pointer could be +used to access a location beyond its lifetime: + +.. code-block:: nimrod + proc WriteAccessToG(): var int = var g = 0 - result = g # Error! - -For iterators, a component of a tuple return type can have a ``var`` type too: - -.. code-block:: nimrod - iterator modPairs(a: var seq[string]): tuple[key: int, val: var string] = - for i in 0..a.high: - yield (i, a[i]) + result = g # Error! + +For iterators, a component of a tuple return type can have a ``var`` type too: + +.. code-block:: nimrod + iterator mpairs(a: var seq[string]): tuple[key: int, val: var string] = + for i in 0..a.high: + yield (i, a[i]) + +In the standard library every name of a routine that returns a ``var`` type +starts with the prefix ``m`` per convention. Overloading of the subscript operator @@ -2331,105 +2334,106 @@ Example: add(root, newNode("hallo")) # instantiates generic procs ``newNode`` and add(root, newNode("world")) # ``add`` for str in inorder(root): + writeln(stdout, str) `Generics`:idx: are Nimrod's means to parametrize procs, iterators or types with `type parameters`:idx:. Depending on context, the brackets are used either to introduce type parameters or to instantiate a generic proc, iterator or type. - - -Is operator -~~~~~~~~~~~ - -The `is`:idx: operator checks for type equivalence at compile time. It is -therefore very useful for type specialization within generic code: - -.. code-block:: nimrod - type - TTable[TKey, TValue] = object - keys: seq[TKey] - values: seq[TValue] - when not (TKey is string): # nil value for strings used for optimization - deletedKeys: seq[bool] - - -Type operator -~~~~~~~~~~~~~ - -The `type`:idx: (in many other languages called `typeof`:idx:) operator can -be used to get the type of an expression: - -.. code-block:: nimrod - var x = 0 - var y: type(x) # y has type int - - -Type constraints -~~~~~~~~~~~~~~~~ - -`Type constraints`:idx: can be used to restrict the instantiation of a generic -type parameter. Only the specified types are valid for instantiation: - -.. code-block:: nimrod - proc onlyIntOrString[T: int|string](x, y: T): T = nil - - onlyIntOrString(45, 66) # valid - onlyIntOrString(56.0, 0.0) # type mismatch - - -Apart from ordinary types, type constraints can also be of the -following *type classes*: - -================== =================================================== -type class matches -================== =================================================== -``object`` any object type -``tuple`` any tuple type -``enum`` any enumeration -``proc`` any proc type -``ref`` any ``ref`` type -``ptr`` any ``ptr`` type -``var`` any ``var`` type -``distinct`` any distinct type -``array`` any array type -``set`` any set type -``seq`` any seq type -================== =================================================== - -The following example is taken directly from the system module: - -.. code-block:: nimrod - proc `==`*[T: tuple](x, y: T): bool = - ## generic ``==`` operator for tuples that is lifted from the components - ## of `x` and `y`. - for a, b in fields(x, y): - if a != b: return false - return true - - -Symbol lookup in generics -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Symbols in generics are looked up in two different contexts: Both the context -at definition and the context at instantiation are considered for any symbol -occuring in a generic: - -.. code-block:: nimrod - type - TIndex = distinct int - - proc `==` (a, b: TIndex): bool {.borrow.} - - var a = (0, 0.TIndex) - var b = (0, 0.TIndex) - - echo a == b # works! - -In the example the generic ``==`` for tuples uses the ``==`` operators of the -tuple's components. However, the ``==`` for the ``TIndex`` type is -defined *after* the ``==`` for tuples; yet the example compiles as the -instantiation takes the currently defined symbols into account too. - + + +Is operator +~~~~~~~~~~~ + +The `is`:idx: operator checks for type equivalence at compile time. It is +therefore very useful for type specialization within generic code: + +.. code-block:: nimrod + type + TTable[TKey, TValue] = object + keys: seq[TKey] + values: seq[TValue] + when not (TKey is string): # nil value for strings used for optimization + deletedKeys: seq[bool] + + +Type operator +~~~~~~~~~~~~~ + +The `type`:idx: (in many other languages called `typeof`:idx:) operator can +be used to get the type of an expression: + +.. code-block:: nimrod + var x = 0 + var y: type(x) # y has type int + + +Type constraints +~~~~~~~~~~~~~~~~ + +`Type constraints`:idx: can be used to restrict the instantiation of a generic +type parameter. Only the specified types are valid for instantiation: + +.. code-block:: nimrod + proc onlyIntOrString[T: int|string](x, y: T): T = nil + + onlyIntOrString(45, 66) # valid + onlyIntOrString(56.0, 0.0) # type mismatch + + +Apart from ordinary types, type constraints can also be of the +following *type classes*: + +================== =================================================== +type class matches +================== =================================================== +``object`` any object type +``tuple`` any tuple type +``enum`` any enumeration +``proc`` any proc type +``ref`` any ``ref`` type +``ptr`` any ``ptr`` type +``var`` any ``var`` type +``distinct`` any distinct type +``array`` any array type +``set`` any set type +``seq`` any seq type +================== =================================================== + +The following example is taken directly from the system module: + +.. code-block:: nimrod + proc `==`*[T: tuple](x, y: T): bool = + ## generic ``==`` operator for tuples that is lifted from the components + ## of `x` and `y`. + for a, b in fields(x, y): + if a != b: return false + return true + + +Symbol lookup in generics +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Symbols in generics are looked up in two different contexts: Both the context +at definition and the context at instantiation are considered for any symbol +occuring in a generic: + +.. code-block:: nimrod + type + TIndex = distinct int + + proc `==` (a, b: TIndex): bool {.borrow.} + + var a = (0, 0.TIndex) + var b = (0, 0.TIndex) + + echo a == b # works! + +In the example the generic ``==`` for tuples uses the ``==`` operators of the +tuple's components. However, the ``==`` for the ``TIndex`` type is +defined *after* the ``==`` for tuples; yet the example compiles as the +instantiation takes the currently defined symbols into account too. + Templates --------- diff --git a/tests/accept/run/ttables.nim b/tests/accept/run/ttables.nim index b492059d7..b82badccb 100755 --- a/tests/accept/run/ttables.nim +++ b/tests/accept/run/ttables.nim @@ -60,6 +60,9 @@ block orderedTableTest1: assert val == data[i][1] inc(i) + for key, val in mpairs(t): val = 99 + for val in mvalues(t): assert val == 99 + block countTableTest1: var s = data.toTable var t = initCountTable[string]() diff --git a/todo.txt b/todo.txt index eb8b783a1..08fe20285 100755 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,7 @@ Version 0.8.14 ============== -- test ``m*`` for generics; document 'm' convention +- test ``m*`` for generics - optional indentation for 'case' statement - make threadvar efficient again on linux after testing - test the sort implementation again |