diff options
author | Araq <rumpf_a@web.de> | 2013-01-02 01:17:53 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-01-02 01:17:53 +0100 |
commit | 88a441ea8ea25f7a298a1279e0fb89274e2c544d (patch) | |
tree | cf6ccfc296c2a3df40b2790d0eea1af25c4b1de2 /compiler/evals.nim | |
parent | 23b90eaa3aab87a5c34cca4cb13a19611beed084 (diff) | |
download | Nim-88a441ea8ea25f7a298a1279e0fb89274e2c544d.tar.gz |
next steps for FFI at compile time
Diffstat (limited to 'compiler/evals.nim')
-rwxr-xr-x | compiler/evals.nim | 23 |
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 |