summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-05-18 15:59:44 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-05-18 15:59:44 +0200
commitf86ca02960bfe853e19e38b008981c0469588828 (patch)
treea7b2178546b28871e86aad840faef8208c9678b9 /compiler
parenta4e2b0c1538134ebf105b669da13db13b5356998 (diff)
downloadNim-f86ca02960bfe853e19e38b008981c0469588828.tar.gz
make semantic checking free of globals
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semdata.nim2
-rw-r--r--compiler/semexprs.nim4
-rw-r--r--compiler/semstmts.nim24
3 files changed, 15 insertions, 15 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 392f00c01..e88f19768 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -75,6 +75,7 @@ type
 
   PContext* = ref TContext
   TContext* = object of TPassContext # a context represents a module
+    enforceVoidContext*: PType
     module*: PSym              # the module sym belonging to the context
     currentScope*: PScope      # current scope
     importTable*: PScope       # scope for all imported symbols
@@ -212,6 +213,7 @@ proc newOptionEntry*(conf: ConfigRef): POptionEntry =
 
 proc newContext*(graph: ModuleGraph; module: PSym; cache: IdentCache): PContext =
   new(result)
+  result.enforceVoidContext = PType(kind: tyStmt)
   result.ambiguousSymbols = initIntSet()
   result.optionStack = @[]
   result.libs = @[]
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index d323f3c0e..64a5861e2 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -58,7 +58,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
     # do not produce another redundant error message:
     #raiseRecoverableError("")
     result = errorNode(c, n)
-  if result.typ == nil or result.typ == enforceVoidContext:
+  if result.typ == nil or result.typ == c.enforceVoidContext:
     localError(c.config, n.info, errExprXHasNoType %
                 renderTree(result, {renderNoComments}))
     result.typ = errorType(c)
@@ -1450,7 +1450,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
       rhs = semExprWithType(c, n.sons[1],
         if lhsIsResult: {efAllowDestructor} else: {})
     if lhsIsResult:
-      n.typ = enforceVoidContext
+      n.typ = c.enforceVoidContext
       if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ):
         var rhsTyp = rhs.typ
         if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass:
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 1cb06c75f..c0dc47b6f 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -36,8 +36,6 @@ const
   errRecursiveDependencyX = "recursive dependency: '$1'"
   errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1"
 
-var enforceVoidContext = PType(kind: tyStmt) # XXX global variable here
-
 proc semDiscard(c: PContext, n: PNode): PNode =
   result = n
   checkSonsLen(n, 1, c.config)
@@ -87,8 +85,8 @@ proc semWhile(c: PContext, n: PNode): PNode =
   n.sons[1] = semStmt(c, n.sons[1])
   dec(c.p.nestedLoopCounter)
   closeScope(c)
-  if n.sons[1].typ == enforceVoidContext:
-    result.typ = enforceVoidContext
+  if n.sons[1].typ == c.enforceVoidContext:
+    result.typ = c.enforceVoidContext
 
 proc toCover(c: PContext, t: PType): BiggestInt =
   var t2 = skipTypes(t, abstractVarRange-{tyTypeDesc})
@@ -173,7 +171,7 @@ proc semIf(c: PContext, n: PNode): PNode =
     for it in n: discardCheck(c, it.lastSon)
     result.kind = nkIfStmt
     # propagate any enforced VoidContext:
-    if typ == enforceVoidContext: result.typ = enforceVoidContext
+    if typ == c.enforceVoidContext: result.typ = c.enforceVoidContext
   else:
     for it in n:
       let j = it.len-1
@@ -238,8 +236,8 @@ proc semCase(c: PContext, n: PNode): PNode =
   if isEmptyType(typ) or typ.kind in {tyNil, tyExpr} or not hasElse:
     for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
     # propagate any enforced VoidContext:
-    if typ == enforceVoidContext:
-      result.typ = enforceVoidContext
+    if typ == c.enforceVoidContext:
+      result.typ = c.enforceVoidContext
   else:
     for i in 1..n.len-1:
       var it = n.sons[i]
@@ -318,8 +316,8 @@ proc semTry(c: PContext, n: PNode): PNode =
   if isEmptyType(typ) or typ.kind in {tyNil, tyExpr}:
     discardCheck(c, n.sons[0])
     for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon)
-    if typ == enforceVoidContext:
-      result.typ = enforceVoidContext
+    if typ == c.enforceVoidContext:
+      result.typ = c.enforceVoidContext
   else:
     if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon)
     n.sons[0] = fitNode(c, typ, n.sons[0], n.sons[0].info)
@@ -746,8 +744,8 @@ proc semFor(c: PContext, n: PNode): PNode =
   else:
     result = semForVars(c, n)
   # propagate any enforced VoidContext:
-  if n.sons[length-1].typ == enforceVoidContext:
-    result.typ = enforceVoidContext
+  if n.sons[length-1].typ == c.enforceVoidContext:
+    result.typ = c.enforceVoidContext
   closeScope(c)
 
 proc semRaise(c: PContext, n: PNode): PNode =
@@ -1834,9 +1832,9 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
           localError(c.config, result.info, "concept predicate failed")
       of tyUnknown: continue
       else: discard
-    if n.sons[i].typ == enforceVoidContext: #or usesResult(n.sons[i]):
+    if n.sons[i].typ == c.enforceVoidContext: #or usesResult(n.sons[i]):
       voidContext = true
-      n.typ = enforceVoidContext
+      n.typ = c.enforceVoidContext
     if i == last and (length == 1 or efWantValue in flags):
       n.typ = n.sons[i].typ
       if not isEmptyType(n.typ): n.kind = nkStmtListExpr