summary refs log tree commit diff stats
path: root/compiler/semexprs.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/semexprs.nim')
-rwxr-xr-xcompiler/semexprs.nim28
1 files changed, 24 insertions, 4 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 8a42a7090..89789f269 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -706,11 +706,10 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode =
   # and check 'arg' for semantics again:
   addSon(result, semExpr(c, arg))
 
-proc semExprNoType(c: PContext, n: PNode): PNode =
+proc discardCheck(result: PNode) =
   proc ImplicitelyDiscardable(n: PNode): bool {.inline.} =
     result = isCallExpr(n) and n.sons[0].kind == nkSym and 
              sfDiscardable in n.sons[0].sym.flags
-  result = semExpr(c, n, {efWantStmt})
   if result.typ != nil and result.typ.kind notin {tyStmt, tyEmpty}:
     if result.kind == nkNilLit:
       # XXX too much work and fixing would break bootstrapping:
@@ -718,7 +717,11 @@ proc semExprNoType(c: PContext, n: PNode): PNode =
       result.typ = nil
     elif not ImplicitelyDiscardable(result) and result.typ.kind != tyError and
         gCmd != cmdInteractive:
-      localError(n.info, errDiscardValue)
+      localError(result.info, errDiscardValue)
+
+proc semExprNoType(c: PContext, n: PNode): PNode =
+  result = semExpr(c, n, {efWantStmt})
+  discardCheck(result)
   
 proc isTypeExpr(n: PNode): bool = 
   case n.kind
@@ -1061,11 +1064,28 @@ proc SemReturn(c: PContext, n: PNode): PNode =
       addSon(a, n.sons[0])
       n.sons[0] = semAsgn(c, a)
       # optimize away ``result = result``:
-      if n[0][1].kind == nkSym and n[0][1].sym.kind == skResult: 
+      if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym: 
         n.sons[0] = ast.emptyNode
     else:
       LocalError(n.info, errNoReturnTypeDeclared)
 
+proc semProcBody(c: PContext, n: PNode): PNode =
+  openScope(c.tab)
+  result = semExpr(c, n)
+  if c.p.resultSym != nil and not isEmptyType(result.typ):
+    # transform ``expr`` to ``result = expr``, but not if the expr is already
+    # ``result``:
+    if result.kind == nkSym and result.sym == c.p.resultSym: 
+      nil
+    else:
+      var a = newNodeI(nkAsgn, n.info, 2)
+      a.sons[0] = newSymNode(c.p.resultSym)
+      a.sons[1] = result
+      result = semAsgn(c, a)
+  else:
+    discardCheck(result)
+  closeScope(c.tab)
+
 proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) =
   var t = skipTypes(restype, {tyGenericInst})
   case t.kind