summary refs log tree commit diff stats
path: root/nim/semstmts.pas
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2009-06-24 17:13:22 +0200
committerAndreas Rumpf <rumpf_a@web.de>2009-06-24 17:13:22 +0200
commit300430fbba28b408f7ac86ca46b03d9d50839399 (patch)
treeb8a84f8efdccda7bfa909b3db911d9e2b9a4b39b /nim/semstmts.pas
parent36818817bd61594ea6d106328bb8df0f5a25cfc4 (diff)
downloadNim-300430fbba28b408f7ac86ca46b03d9d50839399.tar.gz
overload resolution for proc vars
Diffstat (limited to 'nim/semstmts.pas')
-rw-r--r--nim/semstmts.pas41
1 files changed, 34 insertions, 7 deletions
diff --git a/nim/semstmts.pas b/nim/semstmts.pas
index c8b942df8..686ff775d 100644
--- a/nim/semstmts.pas
+++ b/nim/semstmts.pas
@@ -257,7 +257,7 @@ begin
       addSon(result, newIdentNode(getIdent(id.s+'='), n.info));
       addSon(result, semExpr(c, a.sons[0]));
       addSon(result, semExpr(c, n.sons[1]));
-      result := semDirectCall(c, result);
+      result := semDirectCallAnalyseEffects(c, result);
       if result <> nil then begin
         fixAbstractType(c, result);
         analyseIfAddressTakenInCall(c, result);
@@ -277,7 +277,7 @@ begin
         addSonIfNotNil(result, semExpr(c, a.sons[1].sons[0]));
         addSonIfNotNil(result, semExpr(c, a.sons[1].sons[1]));
         addSon(result, semExpr(c, n.sons[1]));
-        result := semDirectCall(c, result);
+        result := semDirectCallAnalyseEffects(c, result);
         if result <> nil then begin
           fixAbstractType(c, result);
           analyseIfAddressTakenInCall(c, result);
@@ -289,7 +289,7 @@ begin
         addSon(result, semExpr(c, a.sons[0]));
         addSon(result, semExpr(c, a.sons[1]));
         addSon(result, semExpr(c, n.sons[1]));
-        result := semDirectCall(c, result);
+        result := semDirectCallAnalyseEffects(c, result);
         if result <> nil then begin
           fixAbstractType(c, result);
           analyseIfAddressTakenInCall(c, result);
@@ -322,7 +322,7 @@ begin
   result := n;
   checkSonsLen(n, 1);
   if not (c.p.owner.kind in [skConverter, skProc, skMacro]) then
-    liMessage(n.info, errReturnNotAllowedHere);
+    liMessage(n.info, errXNotAllowedHere, '''return''');
   if (n.sons[0] <> nil) then begin
     n.sons[0] := SemExprWithType(c, n.sons[0]);
     // check for type compatibility:
@@ -624,9 +624,28 @@ begin
   end
 end;
 
-function resolveGenericParams(c: PContext; n: PNode): PNode;
+function resolveGenericParams(c: PContext; n: PNode; 
+                              withinBind: bool = false): PNode;
+var
+  i: int;
+  s: PSym;
 begin
-  result := n;
+  if n = nil then begin result := nil; exit end;
+  case n.kind of
+    nkIdent: begin
+      if not withinBind then 
+        result := n
+      else
+        result := symChoice(c, n, lookup(c, n))
+    end;
+    nkSym..nkNilLit: result := n;
+    nkBind: result := resolveGenericParams(c, n.sons[0], true);
+    else begin
+      result := n;
+      for i := 0 to sonsLen(n)-1 do
+        result.sons[i] := resolveGenericParams(c, n.sons[i], withinBind);
+    end
+  end
 end;
 
 function SemTypeSection(c: PContext; n: PNode): PNode;
@@ -682,7 +701,7 @@ begin
       addSon(s.typ, nil);
       // process the type body for symbol lookup of generic params
       // we can use the same algorithm as for template parameters:
-      a.sons[2] := resolveTemplateParams(c, a.sons[2]);
+      a.sons[2] := resolveTemplateParams(c, a.sons[2], false);
       s.ast := a;
       if s.typ.containerID <> 0 then
         InternalError(a.info, 'semTypeSection: containerID');
@@ -754,6 +773,13 @@ begin
   n.sons[codePos] := newSymNode(b);
 end;
 
+procedure sideEffectsCheck(c: PContext; s: PSym);
+begin
+  if [sfNoSideEffect, sfSideEffect] * s.flags = 
+     [sfNoSideEffect, sfSideEffect] then 
+    liMessage(s.info, errXhasSideEffects, s.name.s);
+end;
+
 function semIterator(c: PContext; n: PNode): PNode;
 var
   s: PSym;
@@ -972,6 +998,7 @@ begin
     else if sfBorrow in s.flags then 
       semBorrow(c, n, s);
   end;
+  sideEffectsCheck(c, s);
   closeScope(c.tab); // close scope for parameters
   popOwner();
   c.p := oldP; // restore