diff options
-rwxr-xr-x | compiler/semtypes.nim | 25 | ||||
-rwxr-xr-x | doc/manual.txt | 33 | ||||
-rw-r--r-- | tests/accept/run/teventemitter.nim | 10 | ||||
-rwxr-xr-x | todo.txt | 6 | ||||
-rwxr-xr-x | web/news.txt | 1 |
5 files changed, 52 insertions, 23 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 30b81d254..5d4515cd9 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -217,9 +217,6 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = addSon(result, typ) proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = - var - elem: PType - isConcrete: bool if s.typ == nil or s.typ.kind != tyGenericBody: GlobalError(n.info, errCannotInstantiateX, s.name.s) result = newOrPrevType(tyGenericInvokation, prev, c) @@ -227,9 +224,9 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if sonsLen(n) != sonsLen(s.typ): GlobalError(n.info, errWrongNumberOfArguments) addSon(result, s.typ) - isConcrete = true # iterate over arguments: + var isConcrete = true # iterate over arguments: for i in countup(1, sonsLen(n)-1): - elem = semTypeNode(c, n.sons[i], nil) + var elem = semTypeNode(c, n.sons[i], nil) if elem.kind == tyGenericParam: isConcrete = false addSon(result, elem) if isConcrete: @@ -542,26 +539,26 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, result = newOrPrevType(tyProc, prev, c) result.callConv = lastOptionEntry(c).defaultCC result.n = newNodeI(nkFormalParams, n.info) - if (genericParams != nil) and (sonsLen(genericParams) == 0): + if genericParams != nil and sonsLen(genericParams) == 0: cl = initIntSet() addSon(result, nil) # return type res = newNodeI(nkType, n.info) addSon(result.n, res) var check = initIntSet() var counter = 0 - for i in countup(1, sonsLen(n) - 1): + for i in countup(1, sonsLen(n)-1): var a = n.sons[i] if a.kind != nkIdentDefs: IllFormedAst(a) checkMinSonsLen(a, 3) var length = sonsLen(a) - if a.sons[length - 2].kind != nkEmpty: - typ = paramType(c, a.sons[length - 2], genericParams, cl) + if a.sons[length-2].kind != nkEmpty: + typ = paramType(c, a.sons[length-2], genericParams, cl) else: typ = nil - if a.sons[length - 1].kind != nkEmpty: - def = semExprWithType(c, a.sons[length - 1]) + if a.sons[length-1].kind != nkEmpty: + def = semExprWithType(c, a.sons[length-1]) # check type compability between def.typ and typ: - if typ == nil: + if typ == nil: typ = def.typ elif def != nil: # and def.typ != nil and def.typ.kind != tyNone: @@ -571,7 +568,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, else: def = ast.emptyNode if skipTypes(typ, {tyGenericInst}).kind == tyEmpty: continue - for j in countup(0, length - 3): + for j in countup(0, length-3): var arg = newSymS(skParam, a.sons[j], c) arg.typ = typ arg.position = counter @@ -647,7 +644,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = prev.id = s.typ.id result = prev of nkSym: - if (n.sym.kind == skType) and (n.sym.typ != nil): + if n.sym.kind == skType and n.sym.typ != nil: var t = n.sym.typ if prev == nil: result = t diff --git a/doc/manual.txt b/doc/manual.txt index 9d967158d..bdb5f2298 100755 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -2067,6 +2067,37 @@ 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 + 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 = + 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]) Overloading of the subscript operator @@ -2340,7 +2371,7 @@ Type constraints type parameter. Only the specified types are valid for instantiation: .. code-block:: nimrod - proc onlyIntOrString[T: int|string](x, y: T): T = ... + proc onlyIntOrString[T: int|string](x, y: T): T = nil onlyIntOrString(45, 66) # valid onlyIntOrString(56.0, 0.0) # type mismatch diff --git a/tests/accept/run/teventemitter.nim b/tests/accept/run/teventemitter.nim index 763f41943..68970b967 100644 --- a/tests/accept/run/teventemitter.nim +++ b/tests/accept/run/teventemitter.nim @@ -5,16 +5,18 @@ type type TEventEmitter = object of TObject events*: TTable[string, TDoublyLinkedList[proc(e: TEventArgs)]] + +proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) = + for func in nodes(emitter.events[event]): + func.value(args) #call function with args. + proc on*(emitter: var TEventEmitter, event: string, func: proc(e: TEventArgs)) = if not hasKey(emitter.events, event): var list: TDoublyLinkedList[proc(e: TEventArgs)] add(emitter.events,event,list) #if not, add it. #append(emitter.events[event], func) #adds the function to the event's list. I get a error here too. - -proc emit*(emitter: TEventEmitter, event: string, args: TEventArgs) = - for func in nodes(emitter.events[event]): - func.value(args) #call function with args. + proc initEmitter(emitter: TEventEmitter) = emitter.events = initTable[string, TDoublyLinkedList[proc(e: TEventArgs)]]() diff --git a/todo.txt b/todo.txt index e781e772a..bca290b34 100755 --- a/todo.txt +++ b/todo.txt @@ -2,9 +2,7 @@ Version 0.8.14 ============== - fix serious bug that keeps teventemitter from compiling -- ``var T`` as a return type: - * add ``modGet`` for generics - * documentation +- ``var T`` as a return type: add ``modGet`` for generics - optional indentation for 'case' statement - make threadvar efficient again on linux after testing - test the sort implementation again @@ -73,7 +71,7 @@ Library Low priority ------------ -- ``when validCode(proc())`` for generic code +- ``with proc `+`(x, y: T): T`` for generic code - find a way for easy constructors and destructors; (destructors are much more important than constructors) - code generated for type information is wasteful diff --git a/web/news.txt b/web/news.txt index b6776bbb2..d899c52cc 100755 --- a/web/news.txt +++ b/web/news.txt @@ -41,6 +41,7 @@ Language Additions - Added new ``is`` and ``of`` operators. - The built-in type ``void`` can be used to denote the absense of any type. This is only needed in generic contexts. +- Return types may be of the type ``var T`` to return an l-value. Compiler Additions |