summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/semtypes.nim25
-rwxr-xr-xdoc/manual.txt33
-rw-r--r--tests/accept/run/teventemitter.nim10
-rwxr-xr-xtodo.txt6
-rwxr-xr-xweb/news.txt1
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