summary refs log tree commit diff stats
path: root/compiler/evals.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-01-02 01:17:53 +0100
committerAraq <rumpf_a@web.de>2013-01-02 01:17:53 +0100
commit88a441ea8ea25f7a298a1279e0fb89274e2c544d (patch)
treecf6ccfc296c2a3df40b2790d0eea1af25c4b1de2 /compiler/evals.nim
parent23b90eaa3aab87a5c34cca4cb13a19611beed084 (diff)
downloadNim-88a441ea8ea25f7a298a1279e0fb89274e2c544d.tar.gz
next steps for FFI at compile time
Diffstat (limited to 'compiler/evals.nim')
-rwxr-xr-xcompiler/evals.nim23
1 files changed, 15 insertions, 8 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim
index f0a09fff3..5623f7955 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -77,6 +77,7 @@ proc newEvalContext*(module: PSym, filename: string,
   new(result)
   result.module = module
   result.mode = mode
+  result.features = {allowFFI}
   initIdNodeTable(result.globals)
 
 proc pushStackFrame*(c: PEvalContext, t: PStackFrame) {.inline.} = 
@@ -90,7 +91,7 @@ proc popStackFrame*(c: PEvalContext) {.inline.} =
 proc evalMacroCall*(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode
 proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode
 
-proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode = 
+proc raiseCannotEval(c: PEvalContext, info: TLineInfo): PNode =
   result = newNodeI(nkExceptBranch, info)
   # creating a nkExceptBranch without sons 
   # means that it could not be evaluated
@@ -351,7 +352,7 @@ proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
         result = copyTree(result)
     else:
       when hasFFI:
-        if sfImportc in s.flags:
+        if sfImportc in s.flags and allowFFI in c.features:
           result = importcSymbol(s)
           IdNodeTablePut(c.globals, s, result)
           return result
@@ -398,7 +399,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
   if n.typ != nil: d.params[0] = getNullValue(n.typ, n.info)
   
   when hasFFI:
-    if sfImportc in prc.sym.flags:
+    if sfImportc in prc.sym.flags and allowFFI in c.features:
       var newCall = newNodeI(nkCall, n.info, n.len)
       newCall.sons[0] = evalGlobalVar(c, prc.sym, {})
       for i in 1 .. <n.len:
@@ -549,7 +550,8 @@ proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
   of skConst: result = s.ast
   of skEnumField: result = newIntNodeT(s.position, n)
   else: result = nil
-  const mask = when hasFFI: {sfForward} else: {sfImportc, sfForward}
+  let mask = if hasFFI and allowFFI in c.features: {sfForward}
+             else: {sfImportc, sfForward}
   if result == nil or mask * s.flags != {}:
     result = raiseCannotEval(c, n.info)
 
@@ -650,9 +652,13 @@ proc evalConv(c: PEvalContext, n: PNode): PNode =
 
 proc evalCast(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
   if allowCast in c.features:
-    # XXX we need better checking here and the new pack/unpack stuff should
-    # be useful for some casts too:
-    result = evalConv(c, n)
+    when hasFFI:
+      result = evalAux(c, n.sons[1], {efLValue})
+      if isSpecial(result): return
+      InternalAssert result.typ != nil
+      result = fficast(result, n.typ)
+    else:
+      result = evalConv(c, n)
   else:
     result = raiseCannotEval(c, n.info)
 
@@ -1429,7 +1435,7 @@ proc eval*(c: PEvalContext, n: PNode): PNode =
     if sonsLen(result) >= 1: 
       stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
     else:
-      stackTrace(c, n, errCannotInterpretNodeX, renderTree(n))
+      stackTrace(c, result, errCannotInterpretNodeX, renderTree(n))
 
 proc evalConstExprAux(module: PSym, e: PNode, mode: TEvalMode): PNode = 
   var p = newEvalContext(module, "", mode)
@@ -1474,6 +1480,7 @@ proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
 
 proc myOpen(module: PSym, filename: string): PPassContext = 
   var c = newEvalContext(module, filename, emRepl)
+  c.features = {allowCast, allowFFI, allowInfiniteLoops}
   pushStackFrame(c, newStackFrame())
   result = c