summary refs log tree commit diff stats
path: root/nim/sem.pas
diff options
context:
space:
mode:
Diffstat (limited to 'nim/sem.pas')
-rw-r--r--nim/sem.pas63
1 files changed, 54 insertions, 9 deletions
diff --git a/nim/sem.pas b/nim/sem.pas
index 48a967d35..d57af7be6 100644
--- a/nim/sem.pas
+++ b/nim/sem.pas
@@ -21,7 +21,7 @@ uses
   extccomp, nmath, magicsys, nversion, nimsets, pnimsyn, ntime, backends;
 
 const
-  genPrefix = '::'+''; // prefix for generated names
+  genPrefix = '::'; // prefix for generated names
 
 type
   TOptionEntry = object(lists.TListEntry)
@@ -48,6 +48,7 @@ type
     owner: PSym;        // current owner
     forStmt: PNode;    // current for stmt
     next: PTransCon;
+    params: TNodeSeq;  // parameters passed to the proc
   end;
 
   PContext = ^TContext;
@@ -65,6 +66,7 @@ type
     b: PBackend;
     p: PProcCon; // procedure context
     transCon: PTransCon; // top of a TransCon stack
+    lastException: PNode; // last exception
     importModule: function (const filename: string; backend: PBackend): PSym;
     includeFile: function (const filename: string): PNode;
   end;
@@ -87,6 +89,7 @@ begin
   fillChar(result^, sizeof(result^), 0);
 {@emit}
   initIdNodeTable(result.mapping);
+{@emit result.params := [];}
 end;
 
 procedure pushTransCon(c: PContext; t: PTransCon);
@@ -140,13 +143,26 @@ begin
   append(result.optionStack, newOptionEntry());
   result.module := nil;
   result.generics := newNode(nkStmtList);
+{@emit result.converters := [];}
+end;
+
+procedure addConverter(c: PContext; conv: PSym);
+var
+  i, L: int;
+begin
+  L := length(c.converters);
+  for i := 0 to L-1 do
+    if c.converters[i].id = conv.id then exit;
+  setLength(c.converters, L+1);
+  c.converters[L] := conv;
 end;
 
 // -------------------- embedded debugger ------------------------------------
 
 procedure embeddedDbg(c: PContext; n: PNode);
 begin
-  {@discard} inCheckpoint(n.info)
+  if optVerbose in gGlobalOptions then liMessage(n.info, hintProcessing);
+  //{@discard} inCheckpoint(n.info)
 end;
 
 // ---------------------------------------------------------------------------
@@ -207,10 +223,13 @@ var
 begin
   x := n;
   if x.kind = nkAccQuoted then x := x.sons[0];
-  if x.kind = nkIdent then result := x.ident
-  else begin
-    liMessage(n.info, errIdentifierExpected);
-    result := nil
+  case x.kind of
+    nkIdent: result := x.ident;
+    nkSym: result := x.sym.name;
+    else begin
+      liMessage(n.info, errIdentifierExpected, renderTree(n));
+      result := nil
+    end
   end
 end;
 
@@ -251,6 +270,13 @@ begin
   addSon(result, baseType);
 end;
 
+function makeVarType(c: PContext; baseType: PType): PType;
+begin
+  assert(baseType <> nil);
+  result := newTypeS(tyVar, c);
+  addSon(result, baseType);
+end;
+
 {$include 'lookup.pas'}
 
 function semIdentVis(c: PContext; kind: TSymKind; n: PNode;
@@ -261,10 +287,15 @@ function semIdentWithPragma(c: PContext; kind: TSymKind;
 
 function semStmt(c: PContext; n: PNode): PNode; forward;
 function semStmtScope(c: PContext; n: PNode): PNode; forward;
+
+type
+  TExprFlag = (efAllowType, efLValue);
+  TExprFlags = set of TExprFlag;
+
 function semExpr(c: PContext; n: PNode;
-                 typeAllowed: bool = false): PNode; forward;
+                 flags: TExprFlags = {@set}[]): PNode; forward;
 function semExprWithType(c: PContext; n: PNode;
-                         typeAllowed: bool): PNode; forward;
+                         flags: TExprFlags = {@set}[]): PNode; forward;
 function semLambda(c: PContext; n: PNode): PNode; forward;
 function semTypeNode(c: PContext; n: PNode; prev: PType): PType; forward;
 
@@ -275,6 +306,11 @@ function getConstExpr(c: PContext; n: PNode): PNode; forward;
   // evaluates the constant expression or returns nil if it is no constant
   // expression
 
+function eval(c: PContext; n: PNode): PNode; forward;
+// eval never returns nil! This simplifies the code a lot and
+// makes it faster too.
+
+
 {$include 'semtempl.pas'}
 {$include 'instgen.pas'}
 {$include 'sigmatch.pas'}
@@ -303,6 +339,11 @@ begin
   if (n = nil) or (sonsLen(n) <> len) then illFormedAst(n);
 end;
 
+procedure checkMinSonsLen(n: PNode; len: int);
+begin
+  if (n = nil) or (sonsLen(n) < len) then illFormedAst(n);
+end;
+
 procedure typeMismatch(n: PNode; formal, actual: PType);
 begin
   liMessage(n.Info, errGenerated,
@@ -315,6 +356,7 @@ end;
 {$include 'transf.pas'}
 {$include 'semstmts.pas'}
 {$include 'semfold.pas'}
+{$include 'eval.pas'}
 
 function semp(c: PContext; n: PNode): PNode;
 begin
@@ -329,7 +371,7 @@ begin
   for i := 0 to sonsLen(c.generics)-1 do begin
     assert(c.generics.sons[i].sons[1].kind = nkSym);
     prc := c.generics.sons[i].sons[1].sym;
-    if (prc.kind = skProc) and (prc.magic = mNone) then begin
+    if (prc.kind in [skProc, skConverter]) and (prc.magic = mNone) then begin
       addSon(n, prc.ast);
     end
   end
@@ -350,4 +392,7 @@ begin
   c.p := nil;
 end;
 
+initialization
+  new(emptyNode);
+  emptyNode.kind := nkEmpty;
 end.