summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2014-04-06 16:55:16 +0300
committerZahary Karadjov <zahary@gmail.com>2014-04-06 16:55:28 +0300
commitf6f5c9e9e6c27ba466c239509fec9d77a772b7ec (patch)
tree708dc8270dad5effa8d994e2581b75084c870a79 /compiler
parent4d2f1396cb1074fc843069fb456c468c0abd6b35 (diff)
downloadNim-f6f5c9e9e6c27ba466c239509fec9d77a772b7ec.tar.gz
propagate semExpr flags in macro/template expansion
Diffstat (limited to 'compiler')
-rw-r--r--compiler/sem.nim19
-rw-r--r--compiler/semdata.nim2
-rw-r--r--compiler/semexprs.nim17
-rw-r--r--compiler/semgnrc.nim8
-rw-r--r--compiler/semtempl.nim4
5 files changed, 27 insertions, 23 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index c35cff027..b34972219 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -161,12 +161,13 @@ proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} =
     localError(typ.n.info, errXisNoType, typeToString(typ))
 
 proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym
-proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode
 proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode
 proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode
 proc isOpImpl(c: PContext, n: PNode): PNode
+proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
+                     flags: TExprFlags = {}): PNode
 proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
-                  semCheck: bool = true): PNode
+                  flags: TExprFlags = {}): PNode
 
 proc symFromType(t: PType, info: TLineInfo): PSym =
   if t.sym != nil: return t.sym
@@ -265,7 +266,8 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
 
 include hlo, seminst, semcall
 
-proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = 
+proc semAfterMacroCall(c: PContext, n: PNode, s: PSym,
+                       flags: TExprFlags): PNode =
   inc(evalTemplateCounter)
   if evalTemplateCounter > 100:
     globalError(s.info, errTemplateInstantiationTooNested)
@@ -281,7 +283,7 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
       # BUGFIX: we cannot expect a type here, because module aliases would not 
       # work then (see the ``tmodulealias`` test)
       # semExprWithType(c, result)
-      result = semExpr(c, result)
+      result = semExpr(c, result, flags)
     of tyStmt:
       result = semStmt(c, result)
     of tyTypeDesc:
@@ -290,14 +292,14 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
       result.typ = makeTypeDesc(c, typ)
       #result = symNodeFromType(c, typ, n.info)
     else:
-      result = semExpr(c, result)
+      result = semExpr(c, result, flags)
       result = fitNode(c, s.typ.sons[0], result)
       #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
   dec(evalTemplateCounter)
   c.friendModule = oldFriend
 
-proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, 
-                  semCheck: bool = true): PNode = 
+proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
+                  flags: TExprFlags = {}): PNode =
   markUsed(n, sym)
   if sym == c.p.owner:
     globalError(n.info, errRecursiveDependencyX, sym.name.s)
@@ -306,7 +308,8 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
   #  c.evalContext = c.createEvalContext(emStatic)
 
   result = evalMacroCall(c.module, n, nOrig, sym)
-  if semCheck: result = semAfterMacroCall(c, result, sym)
+  if efNoSemCheck notin flags:
+    result = semAfterMacroCall(c, result, sym, flags)
 
 proc forceBool(c: PContext, n: PNode): PNode = 
   result = fitNode(c, getSysType(tyBool), n)
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index b46d83a92..4cb5ad38c 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -42,7 +42,7 @@ type
 
   TExprFlag* = enum 
     efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType,
-    efAllowDestructor, efWantValue, efOperand
+    efAllowDestructor, efWantValue, efOperand, efNoSemCheck
   TExprFlags* = set[TExprFlag]
 
   PContext* = ref TContext
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 6743768a2..9b3b2d73e 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -10,11 +10,12 @@
 # this module does the semantic checking for expressions
 # included from sem.nim
 
-proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode = 
+proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
+                     flags: TExprFlags = {}): PNode =
   markUsed(n, s)
   pushInfoContext(n.info)
   result = evalTemplate(n, s, getCurrOwner())
-  if semCheck: result = semAfterMacroCall(c, result, s)
+  if efNoSemCheck notin flags: result = semAfterMacroCall(c, result, s, flags)
   popInfoContext()
 
 proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
@@ -95,8 +96,8 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
       else: result = newSymNode(s, n.info)
     else:
       result = newSymNode(s, n.info)
-  of skMacro: result = semMacroExpr(c, n, n, s)
-  of skTemplate: result = semTemplateExpr(c, n, s)
+  of skMacro: result = semMacroExpr(c, n, n, s, flags)
+  of skTemplate: result = semTemplateExpr(c, n, s, flags)
   of skVar, skLet, skResult, skParam, skForVar:
     markUsed(n, s)
     # if a proc accesses a global variable, it is not side effect free:
@@ -793,8 +794,8 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
   result = n
   let callee = result.sons[0].sym
   case callee.kind
-  of skMacro: result = semMacroExpr(c, result, orig, callee)
-  of skTemplate: result = semTemplateExpr(c, result, callee)
+  of skMacro: result = semMacroExpr(c, result, orig, callee, flags)
+  of skTemplate: result = semTemplateExpr(c, result, callee, flags)
   else:
     semFinishOperands(c, result)
     activate(c, result)
@@ -1966,13 +1967,13 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
           result = semDirectOp(c, n, flags)
         else:
           var p = fixImmediateParams(n)
-          result = semMacroExpr(c, p, p, s)
+          result = semMacroExpr(c, p, p, s, flags)
       of skTemplate:
         if sfImmediate notin s.flags:
           result = semDirectOp(c, n, flags)
         else:
           var p = fixImmediateParams(n)
-          result = semTemplateExpr(c, p, s)
+          result = semTemplateExpr(c, p, s, flags)
       of skType:
         # XXX think about this more (``set`` procs)
         if n.len == 2:
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index ffc1a43b2..da4a2a132 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -47,12 +47,12 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
   of skTemplate:
     if macroToExpand(s):
       let n = fixImmediateParams(n)
-      result = semTemplateExpr(c, n, s, false)
+      result = semTemplateExpr(c, n, s, {efNoSemCheck})
     else:
       result = symChoice(c, n, s, scOpen)
   of skMacro: 
     if macroToExpand(s):
-      result = semMacroExpr(c, n, n, s, false)
+      result = semMacroExpr(c, n, n, s, {efNoSemCheck})
     else:
       result = symChoice(c, n, s, scOpen)
   of skGenericParam: 
@@ -126,14 +126,14 @@ proc semGenericStmt(c: PContext, n: PNode,
       case s.kind
       of skMacro:
         if macroToExpand(s):
-          result = semMacroExpr(c, n, n, s, false)
+          result = semMacroExpr(c, n, n, s, {efNoSemCheck})
         else:
           n.sons[0] = symChoice(c, n.sons[0], s, scOption)
           result = n
       of skTemplate: 
         if macroToExpand(s):
           let n = fixImmediateParams(n)
-          result = semTemplateExpr(c, n, s, false)
+          result = semTemplateExpr(c, n, s, {efNoSemCheck})
         else:
           n.sons[0] = symChoice(c, n.sons[0], s, scOption)
           result = n
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 1432b76f0..ad34eea65 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -539,7 +539,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
       elif contains(c.toBind, s.id):
         result = symChoice(c.c, n, s, scClosed)
       elif templToExpand(s):
-        result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
+        result = semPatternBody(c, semTemplateExpr(c.c, n, s, {efNoSemCheck}))
       else:
         discard
         # we keep the ident unbound for matching instantiated symbols and
@@ -584,7 +584,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
       if s.owner == c.owner and s.kind == skParam: discard
       elif contains(c.toBind, s.id): discard
       elif templToExpand(s):
-        return semPatternBody(c, semTemplateExpr(c.c, n, s, false))
+        return semPatternBody(c, semTemplateExpr(c.c, n, s, {efNoSemCheck}))
     
     if n.kind == nkInfix and n.sons[0].kind == nkIdent:
       # we interpret `*` and `|` only as pattern operators if they occur in