summary refs log tree commit diff stats
path: root/compiler/sem.nim
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-08-25 18:11:05 +0300
committerZahary Karadjov <zahary@gmail.com>2013-08-25 18:11:28 +0300
commit89086a8e19292ad986baa808ff42ccad32bf2636 (patch)
treedba214f1beaeac5556f33cccbb3a476aca94cae5 /compiler/sem.nim
parent6378fbd66ef9ff85510bf0583610bfc84dc6528f (diff)
downloadNim-89086a8e19292ad986baa808ff42ccad32bf2636.tar.gz
prevent eval crashes due to PContext-dependent ops not being available in evalConstExpr
Diffstat (limited to 'compiler/sem.nim')
-rw-r--r--compiler/sem.nim65
1 files changed, 35 insertions, 30 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim
index c411d8ac4..71951dd3f 100644
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -132,14 +132,42 @@ 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 semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, 
-                  semCheck: bool = 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 semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
+                  semCheck: bool = true): PNode
+
+proc symFromType(t: PType, info: TLineInfo): PSym =
+  if t.sym != nil: return t.sym
+  result = newSym(skType, getIdent"AnonType", t.owner, info)
+  result.flags.incl sfAnon
+  result.typ = t
+
+proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode =
+  result = newSymNode(symFromType(t, info), info)
+  result.typ = makeTypeDesc(c, t)
+
+proc createEvalContext(c: PContext, mode: TEvalMode): PEvalContext =
+  result = newEvalContext(c.module, mode)
+  result.getType = proc (n: PNode): PNode =
+    var e = tryExpr(c, n)
+    if e == nil:
+      result = symNodeFromType(c, errorType(c), n.info)
+    elif e.typ == nil:
+      result = newSymNode(getSysSym"void")
+    else:
+      result = symNodeFromType(c, e.typ, n.info)
+
+  result.handleIsOperator = proc (n: PNode): PNode =
+    result = IsOpImpl(c, n)
+
+proc evalConstExpr(c: PContext, module: PSym, e: PNode): PNode = 
+  result = evalConstExprAux(c.createEvalContext(emConst), module, nil, e)
+
+proc evalStaticExpr(c: PContext, module: PSym, e: PNode, prc: PSym): PNode = 
+  result = evalConstExprAux(c.createEvalContext(emStatic), module, prc, e)
 
 proc semConstExpr(c: PContext, n: PNode): PNode =
   var e = semExprWithType(c, n)
@@ -148,7 +176,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
     return n
   result = getConstExpr(c.module, e)
   if result == nil:
-    result = evalConstExpr(c.module, e)
+    result = evalConstExpr(c, c.module, e)
     if result == nil or result.kind == nkEmpty:
       if e.info != n.info:
         pushInfoContext(n.info)
@@ -161,16 +189,6 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
 
 include hlo, seminst, semcall
 
-proc symFromType(t: PType, info: TLineInfo): PSym =
-  if t.sym != nil: return t.sym
-  result = newSym(skType, getIdent"AnonType", t.owner, info)
-  result.flags.incl sfAnon
-  result.typ = t
-
-proc symNodeFromType(c: PContext, t: PType, info: TLineInfo): PNode =
-  result = newSymNode(symFromType(t, info), info)
-  result.typ = makeTypeDesc(c, t)
-
 proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode = 
   inc(evalTemplateCounter)
   if evalTemplateCounter > 100:
@@ -198,8 +216,6 @@ proc semAfterMacroCall(c: PContext, n: PNode, s: PSym): PNode =
       #GlobalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
   dec(evalTemplateCounter)
 
-proc IsOpImpl(c: PContext, n: PNode): PNode
-
 proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, 
                   semCheck: bool = true): PNode = 
   markUsed(n, sym)
@@ -207,18 +223,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
     GlobalError(n.info, errRecursiveDependencyX, sym.name.s)
 
   if c.evalContext == nil:
-    c.evalContext = newEvalContext(c.module, emStatic)
-    c.evalContext.getType = proc (n: PNode): PNode =
-      var e = tryExpr(c, n)
-      if e == nil:
-        result = symNodeFromType(c, errorType(c), n.info)
-      elif e.typ == nil:
-        result = newSymNode(getSysSym"void")
-      else:
-        result = symNodeFromType(c, e.typ, n.info)
-
-    c.evalContext.handleIsOperator = proc (n: PNode): PNode =
-      result = IsOpImpl(c, n)
+    c.evalContext = c.createEvalContext(emStatic)
 
   result = evalMacroCall(c.evalContext, n, nOrig, sym)
   if semCheck: result = semAfterMacroCall(c, result, sym)