summary refs log tree commit diff stats
path: root/compiler/evals.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2012-12-19 02:22:39 +0100
committerAraq <rumpf_a@web.de>2012-12-19 02:22:39 +0100
commit7148812524d26b89dab7efde2e86d318677b502b (patch)
treeaefb4fe12e0aa08e27cfaeceec2c7594c0564f52 /compiler/evals.nim
parent3be576222a2e2a774570eb408d43c35ab94c5f15 (diff)
downloadNim-7148812524d26b89dab7efde2e86d318677b502b.tar.gz
first steps for FFI support at compile time
Diffstat (limited to 'compiler/evals.nim')
-rwxr-xr-xcompiler/evals.nim96
1 files changed, 58 insertions, 38 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim
index 20d354aaf..535d9aebd 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -18,6 +18,9 @@ import
   msgs, os, condsyms, idents, renderer, types, passes, semfold, transf, 
   parser, ropes, rodread, idgen, osproc, streams, evaltempl
 
+when hasFFI:
+  import evalffi
+
 type 
   PStackFrame* = ref TStackFrame
   TStackFrame*{.final.} = object 
@@ -307,42 +310,6 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
           for i in countup(0, sonsLen(result) - 1): addSon(x, result.sons[i])
   result = emptyNode
 
-proc evalCall(c: PEvalContext, n: PNode): PNode = 
-  var d = newStackFrame()
-  d.call = n
-  var prc = n.sons[0]
-  let isClosure = prc.kind == nkClosure
-  setlen(d.params, sonsLen(n) + ord(isClosure))
-  if isClosure:
-    #debug prc
-    result = evalAux(c, prc.sons[1], {efLValue})
-    if isSpecial(result): return
-    d.params[sonsLen(n)] = result
-    result = evalAux(c, prc.sons[0], {})
-  else:
-    result = evalAux(c, prc, {})
-
-  if isSpecial(result): return 
-  prc = result
-  # bind the actual params to the local parameter of a new binding
-  if prc.kind != nkSym: 
-    InternalError(n.info, "evalCall " & n.renderTree)
-    return
-  d.prc = prc.sym
-  if prc.sym.kind notin {skProc, skConverter, skMacro}:
-    InternalError(n.info, "evalCall")
-    return
-  for i in countup(1, sonsLen(n) - 1): 
-    result = evalAux(c, n.sons[i], {})
-    if isSpecial(result): return 
-    d.params[i] = result
-  if n.typ != nil: d.params[0] = getNullValue(n.typ, n.info)
-  pushStackFrame(c, d)
-  result = evalAux(c, prc.sym.getBody, {})
-  if result.kind == nkExceptBranch: return 
-  if n.typ != nil: result = d.params[0]
-  popStackFrame(c)
-
 proc aliasNeeded(n: PNode, flags: TEvalFlags): bool = 
   result = efLValue in flags or n.typ == nil or 
     n.typ.kind in {tyExpr, tyStmt, tyTypeDesc}
@@ -374,7 +341,14 @@ proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
     else:
       result = s.ast
       if result == nil or result.kind == nkEmpty:
-        result = getNullValue(s.typ, s.info)
+        when hasFFI:
+          # for 'stdin' etc. we need to support 'importc' for variables:
+          if sfImportc in s.flags:
+            result = importcSymbol(s)
+          else:
+            result = getNullValue(s.typ, s.info)
+        else:
+          result = getNullValue(s.typ, s.info)
       else:
         result = evalAux(c, result, {})
         if isSpecial(result): return
@@ -382,6 +356,51 @@ proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
   else:
     result = raiseCannotEval(nil, s.info)
 
+proc evalCall(c: PEvalContext, n: PNode): PNode = 
+  var d = newStackFrame()
+  d.call = n
+  var prc = n.sons[0]
+  let isClosure = prc.kind == nkClosure
+  setlen(d.params, sonsLen(n) + ord(isClosure))
+  if isClosure:
+    #debug prc
+    result = evalAux(c, prc.sons[1], {efLValue})
+    if isSpecial(result): return
+    d.params[sonsLen(n)] = result
+    result = evalAux(c, prc.sons[0], {})
+  else:
+    result = evalAux(c, prc, {})
+
+  if isSpecial(result): return 
+  prc = result
+  # bind the actual params to the local parameter of a new binding
+  if prc.kind != nkSym: 
+    InternalError(n.info, "evalCall " & n.renderTree)
+    return
+  d.prc = prc.sym
+  if prc.sym.kind notin {skProc, skConverter, skMacro}:
+    InternalError(n.info, "evalCall")
+    return
+  for i in countup(1, sonsLen(n) - 1): 
+    result = evalAux(c, n.sons[i], {})
+    if isSpecial(result): return 
+    d.params[i] = result
+  if n.typ != nil: d.params[0] = getNullValue(n.typ, n.info)
+  
+  when hasFFI:
+    if sfImportc in prc.sym.flags:
+      var newCall = newNodeI(nkCall, n.info, n.len)
+      newCall.sons[0] = evalGlobalVar(c, prc.sym, {})
+      for i in 1 .. <n.len:
+        newCall.sons[i] = d.params[i-1]
+      return callForeignFunction(newCall)
+  
+  pushStackFrame(c, d)
+  result = evalAux(c, prc.sym.getBody, {})
+  if result.kind == nkExceptBranch: return 
+  if n.typ != nil: result = d.params[0]
+  popStackFrame(c)
+
 proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = 
   result = evalAux(c, n.sons[0], flags)
   if isSpecial(result): return 
@@ -520,7 +539,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
-  if result == nil or {sfImportc, sfForward} * s.flags != {}:
+  const mask = when hasFFI: {sfForward} else: {sfImportc, sfForward}
+  if result == nil or mask * s.flags != {}:
     result = raiseCannotEval(c, n.info)
 
 proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =