refactorings for the eval engine; bugfix: clean templates as accessors

This commit is contained in:
Araq 2013-07-19 22:22:20 +02:00
commit bfbdb1f028
10 changed files with 235 additions and 239 deletions

View file

@ -110,13 +110,18 @@ proc stackTraceAux(x: PStackFrame) =
add(s, x.prc.name.s)
MsgWriteln(s)
proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg = "") =
proc stackTrace(c: PEvalContext, info: TLineInfo, msg: TMsgKind, arg = "") =
MsgWriteln("stack trace: (most recent call last)")
stackTraceAux(c.tos)
LocalError(n.info, msg, arg)
LocalError(info, msg, arg)
proc isSpecial(n: PNode): bool {.inline.} =
result = n.kind == nkExceptBranch
template isSpecial(n: PNode): bool = n.kind == nkExceptBranch
template bailout() {.dirty.} =
if isSpecial(result): return
template evalX(n, flags) {.dirty.} =
result = evalAux(c, n, flags)
bailout()
proc myreset(n: PNode) =
when defined(system.reset):
@ -128,19 +133,17 @@ proc evalIf(c: PEvalContext, n: PNode): PNode =
var i = 0
var length = sonsLen(n)
while (i < length) and (sonsLen(n.sons[i]) >= 2):
result = evalAux(c, n.sons[i].sons[0], {})
if isSpecial(result): return
if (result.kind == nkIntLit) and (result.intVal != 0):
evalX(n.sons[i].sons[0], {})
if result.kind == nkIntLit and result.intVal != 0:
return evalAux(c, n.sons[i].sons[1], {})
inc(i)
if (i < length) and (sonsLen(n.sons[i]) < 2):
if (i < length) and (sonsLen(n.sons[i]) < 2):
result = evalAux(c, n.sons[i].sons[0], {})
else:
else:
result = emptyNode
proc evalCase(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[0], {})
if isSpecial(result): return
evalX(n.sons[0], {})
var res = result
result = emptyNode
for i in countup(1, sonsLen(n) - 1):
@ -160,9 +163,8 @@ var
proc evalWhile(c: PEvalContext, n: PNode): PNode =
while true:
result = evalAux(c, n.sons[0], {})
if isSpecial(result): return
if getOrdValue(result) == 0: break
evalX(n.sons[0], {})
if getOrdValue(result) == 0: break
result = evalAux(c, n.sons[1], {})
case result.kind
of nkBreakStmt:
@ -177,7 +179,7 @@ proc evalWhile(c: PEvalContext, n: PNode): PNode =
if allowInfiniteLoops in c.features:
gWhileCounter = 0
else:
stackTrace(c, n, errTooManyIterations)
stackTrace(c, n.info, errTooManyIterations)
break
proc evalBlock(c: PEvalContext, n: PNode): PNode =
@ -222,7 +224,9 @@ proc evalTry(c: PEvalContext, n: PNode): PNode =
else:
for j in countup(0, blen - 2):
assert(n.sons[i].sons[j].kind == nkType)
if exc.typ.id == n.sons[i].sons[j].typ.id:
let a = exc.typ.skipTypes(abstractPtrs)
let b = n.sons[i].sons[j].typ.skipTypes(abstractPtrs)
if a == b:
result = evalAux(c, n.sons[i].sons[blen - 1], {})
exc = result
break
@ -239,7 +243,7 @@ proc getNullValueAux(obj: PNode, result: PNode) =
getNullValueAux(obj.sons[0], result)
for i in countup(1, sonsLen(obj) - 1):
getNullValueAux(lastSon(obj.sons[i]), result)
of nkSym:
of nkSym:
var s = obj.sym
var p = newNodeIT(nkExprColonExpr, result.info, s.typ)
addSon(p, newSymNode(s, result.info))
@ -290,14 +294,17 @@ proc evalVarValue(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n, {})
if result.kind in {nkType..nkNilLit}: result = result.copyNode
proc allocSlot(c: PStackFrame; sym: PSym): int =
result = sym.position + ord(sym.kind == skParam)
if result == 0 and sym.kind != skResult:
result = c.slots.len
if result == 0: result = 1
sym.position = result
setLen(c.slots, max(result+1, c.slots.len))
proc setSlot(c: PStackFrame, sym: PSym, val: PNode) =
assert sym.owner == c.prc
var idx = sym.position
if idx == 0:
idx = c.slots.len
if idx == 0: idx = 1
sym.position = idx
setLen(c.slots, max(idx+1, c.slots.len))
let idx = allocSlot(c, sym)
c.slots[idx] = val
proc setVar(c: PEvalContext, v: PSym, n: PNode) =
@ -313,7 +320,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
result = evalVarValue(c, a.lastSon)
if result.kind in {nkType..nkNilLit}:
result = result.copyNode
if isSpecial(result): return
bailout()
if result.kind != nkPar:
return raiseCannotEval(c, n.info)
for i in 0 .. a.len-3:
@ -322,7 +329,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
else:
if a.sons[2].kind != nkEmpty:
result = evalVarValue(c, a.sons[2])
if isSpecial(result): return
bailout()
else:
result = getNullValue(a.sons[0].typ, a.sons[0].info)
if a.sons[0].kind == nkSym:
@ -331,8 +338,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
else:
# assign to a.sons[0]:
var x = result
result = evalAux(c, a.sons[0], {})
if isSpecial(result): return
evalX(a.sons[0], {})
myreset(x)
x.kind = result.kind
x.typ = result.typ
@ -392,6 +398,9 @@ proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
else:
result = raiseCannotEval(nil, s.info)
proc optBody(c: PEvalContext, s: PSym): PNode =
result = s.getBody
proc evalCall(c: PEvalContext, n: PNode): PNode =
var d = newStackFrame()
d.call = n
@ -400,8 +409,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
setlen(d.slots, sonsLen(n) + ord(isClosure))
if isClosure:
#debug prc
result = evalAux(c, prc.sons[1], {efLValue})
if isSpecial(result): return
evalX(prc.sons[1], {efLValue})
d.slots[sonsLen(n)] = result
result = evalAux(c, prc.sons[0], {})
else:
@ -418,8 +426,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
InternalError(n.info, "evalCall")
return
for i in countup(1, sonsLen(n) - 1):
result = evalAux(c, n.sons[i], {})
if isSpecial(result): return
evalX(n.sons[i], {})
d.slots[i] = result
if n.typ != nil: d.slots[0] = getNullValue(n.typ, n.info)
@ -432,33 +439,30 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
return callForeignFunction(newCall)
pushStackFrame(c, d)
result = evalAux(c, prc.sym.getBody, {})
if result.kind == nkExceptBranch: return
evalX(optBody(c, prc.sym), {})
if n.typ != nil: result = d.slots[0]
popStackFrame(c)
proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = evalAux(c, n.sons[0], flags)
if isSpecial(result): return
evalX(n.sons[0], flags)
var x = result
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
evalX(n.sons[1], {})
var idx = getOrdValue(result)
result = emptyNode
case x.kind
of nkPar:
of nkPar:
if (idx >= 0) and (idx < sonsLen(x)):
result = x.sons[int(idx)]
if result.kind == nkExprColonExpr: result = result.sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
else:
stackTrace(c, n, errIndexOutOfBounds)
stackTrace(c, n.info, errIndexOutOfBounds)
of nkBracket, nkMetaNode:
if (idx >= 0) and (idx < sonsLen(x)):
result = x.sons[int(idx)]
if not aliasNeeded(result, flags): result = copyTree(result)
else:
stackTrace(c, n, errIndexOutOfBounds)
stackTrace(c, n.info, errIndexOutOfBounds)
of nkStrLit..nkTripleStrLit:
if efLValue in flags: return raiseCannotEval(c, n.info)
result = newNodeIT(nkCharLit, x.info, getSysType(tyChar))
@ -467,14 +471,13 @@ proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
elif idx == len(x.strVal):
nil
else:
stackTrace(c, n, errIndexOutOfBounds)
else: stackTrace(c, n, errNilAccess)
stackTrace(c, n.info, errIndexOutOfBounds)
else: stackTrace(c, n.info, errNilAccess)
proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
# a real field access; proc calls have already been transformed
# XXX: field checks!
result = evalAux(c, n.sons[0], flags)
if isSpecial(result): return
evalX(n.sons[0], flags)
var x = result
if x.kind != nkPar: return raiseCannotEval(c, n.info)
# this is performance critical:
@ -482,48 +485,26 @@ proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = x.sons[field.position]
if result.kind == nkExprColonExpr: result = result.sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
when false:
var field = n.sons[1].sym
for i in countup(0, sonsLen(x) - 1):
var it = x.sons[i]
if it.kind != nkExprColonExpr:
# lookup per index:
result = x.sons[field.position]
if result.kind == nkExprColonExpr: result = result.sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
return
#InternalError(it.info, "evalFieldAccess")
if it.sons[0].sym.name.id == field.name.id:
result = x.sons[i].sons[1]
if not aliasNeeded(result, flags): result = copyTree(result)
return
stackTrace(c, n, errFieldXNotFound, field.name.s)
result = emptyNode
proc evalAsgn(c: PEvalContext, n: PNode): PNode =
proc evalAsgn(c: PEvalContext, n: PNode): PNode =
var a = n.sons[0]
if a.kind == nkBracketExpr and a.sons[0].typ.kind in {tyString, tyCString}:
result = evalAux(c, a.sons[0], {efLValue})
if isSpecial(result): return
evalX(a.sons[0], {efLValue})
var x = result
result = evalAux(c, a.sons[1], {})
if isSpecial(result): return
evalX(a.sons[1], {})
var idx = getOrdValue(result)
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
if result.kind != nkCharLit: return raiseCannotEval(c, n.info)
evalX(n.sons[1], {})
if result.kind notin {nkIntLit, nkCharLit}: return c.raiseCannotEval(n.info)
if (idx >= 0) and (idx < len(x.strVal)):
if idx >= 0 and idx < len(x.strVal):
x.strVal[int(idx)] = chr(int(result.intVal))
else:
stackTrace(c, n, errIndexOutOfBounds)
else:
stackTrace(c, n.info, errIndexOutOfBounds)
else:
result = evalAux(c, n.sons[0], {efLValue})
if isSpecial(result): return
evalX(n.sons[0], {efLValue})
var x = result
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
evalX(n.sons[1], {})
myreset(x)
x.kind = result.kind
x.typ = result.typ
@ -541,13 +522,11 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
assert result.kind == nkEmpty
proc evalSwap(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[0], {efLValue})
if isSpecial(result): return
evalX(n.sons[0], {efLValue})
var x = result
result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return
evalX(n.sons[1], {efLValue})
if x.kind != result.kind:
stackTrace(c, n, errCannotInterpretNodeX, $n.kind)
stackTrace(c, n.info, errCannotInterpretNodeX, $n.kind)
else:
case x.kind
of nkCharLit..nkInt64Lit: swap(x.intVal, result.intVal)
@ -587,11 +566,9 @@ proc evalSym(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = raiseCannotEval(c, n.info)
proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return
evalX(n.sons[1], {efLValue})
var a = result
result = evalAux(c, n.sons[2], {})
if isSpecial(result): return
evalX(n.sons[2], {})
var b = result
case a.kind
of nkCharLit..nkInt64Lit: a.intval = a.intVal + sign * getOrdValue(b)
@ -607,64 +584,62 @@ proc getStrValue(n: PNode): string =
proc evalEcho(c: PEvalContext, n: PNode): PNode =
for i in countup(1, sonsLen(n) - 1):
result = evalAux(c, n.sons[i], {})
if isSpecial(result): return
evalX(n.sons[i], {})
Write(stdout, getStrValue(result))
writeln(stdout, "")
result = emptyNode
proc evalExit(c: PEvalContext, n: PNode): PNode =
if c.mode in {emRepl, emStatic}:
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
evalX(n.sons[1], {})
Message(n.info, hintQuitCalled)
quit(int(getOrdValue(result)))
else:
result = raiseCannotEval(c, n.info)
proc evalOr(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
if result.kind != nkIntLit: InternalError(n.info, "evalOr")
elif result.intVal == 0: result = evalAux(c, n.sons[2], {})
evalX(n.sons[1], {})
if result.intVal == 0: result = evalAux(c, n.sons[2], {})
proc evalAnd(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
if result.kind != nkIntLit: InternalError(n.info, "evalAnd")
elif result.intVal != 0: result = evalAux(c, n.sons[2], {})
evalX(n.sons[1], {})
if result.intVal != 0: result = evalAux(c, n.sons[2], {})
proc evalNew(c: PEvalContext, n: PNode): PNode =
#if c.mode == emOptimize: return raiseCannotEval(c, n.info)
# we ignore the finalizer for now and most likely forever :-)
result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return
evalX(n.sons[1], {efLValue})
var a = result
var t = skipTypes(n.sons[1].typ, abstractVar)
if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty")
myreset(a)
a.kind = nkRefTy
a.info = n.info
let u = getNullValue(t.sons[0], n.info)
a.kind = u.kind
a.typ = t
a.sons = nil
addSon(a, getNullValue(t.sons[0], n.info))
shallowCopy(a.sons, u.sons)
result = emptyNode
when false:
a.kind = nkRefTy
a.info = n.info
a.typ = t
a.sons = nil
addSon(a, getNullValue(t.sons[0], n.info))
result = emptyNode
proc evalDeref(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = evalAux(c, n.sons[0], {efLValue})
if isSpecial(result): return
evalX(n.sons[0], {efLValue})
case result.kind
of nkNilLit: stackTrace(c, n, errNilAccess)
of nkNilLit: stackTrace(c, n.info, errNilAccess)
of nkRefTy:
# XXX efLValue?
result = result.sons[0]
else:
result = raiseCannotEval(c, n.info)
if skipTypes(n.sons[0].typ, abstractInst).kind != tyRef:
result = raiseCannotEval(c, n.info)
proc evalAddr(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = evalAux(c, n.sons[0], {efLValue})
if isSpecial(result): return
evalX(n.sons[0], {efLValue})
var a = result
var t = newType(tyPtr, c.module)
addSonSkipIntLit(t, a.typ)
@ -703,24 +678,22 @@ proc evalUpConv(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
var dest = skipTypes(n.typ, abstractPtrs)
var src = skipTypes(result.typ, abstractPtrs)
if inheritanceDiff(src, dest) > 0:
stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src))
stackTrace(c, n.info, errInvalidConversionFromTypeX, typeToString(src))
proc evalRangeChck(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[0], {})
if isSpecial(result): return
evalX(n.sons[0], {})
var x = result
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
evalX(n.sons[1], {})
var a = result
result = evalAux(c, n.sons[2], {})
if isSpecial(result): return
evalX(n.sons[2], {})
var b = result
if leValueConv(a, x) and leValueConv(x, b):
result = x # a <= x and x <= b
result.typ = n.typ
else:
stackTrace(c, n, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [
typeToString(n.sons[0].typ), typeToString(n.typ)])
stackTrace(c, n.info, errGenerated,
msgKindToString(errIllegalConvFromXtoY) % [
typeToString(n.sons[0].typ), typeToString(n.typ)])
proc evalConvStrToCStr(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[0], {})
@ -744,7 +717,7 @@ proc evalRaise(c: PEvalContext, n: PNode): PNode =
elif c.lastException != nil:
result = c.lastException
else:
stackTrace(c, n, errExceptionAlreadyHandled)
stackTrace(c, n.info, errExceptionAlreadyHandled)
result = newNodeIT(nkExceptBranch, n.info, nil)
addSon(result, ast.emptyNode)
else:
@ -1089,7 +1062,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
case a.kind
of nkEmpty..nkNilLit: nil
else: result.intVal = sonsLen(a)
of mNChild:
of mNChild:
result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return
var a = result
@ -1100,7 +1073,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = a.sons[int(k)]
if result == nil: result = newNode(nkEmpty)
else:
stackTrace(c, n, errIndexOutOfBounds)
stackTrace(c, n.info, errIndexOutOfBounds)
result = emptyNode
of mNSetChild:
result = evalAux(c, n.sons[1], {efLValue})
@ -1115,7 +1088,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}):
a.sons[int(k)] = result
else:
stackTrace(c, n, errIndexOutOfBounds)
stackTrace(c, n.info, errIndexOutOfBounds)
result = emptyNode
of mNAdd:
result = evalAux(c, n.sons[1], {efLValue})
@ -1158,7 +1131,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = newNodeIT(nkIntLit, n.info, n.typ)
case a.kind
of nkCharLit..nkInt64Lit: result.intVal = a.intVal
else: stackTrace(c, n, errFieldXNotFound, "intVal")
else: stackTrace(c, n.info, errFieldXNotFound, "intVal")
of mNFloatVal:
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
@ -1166,15 +1139,15 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = newNodeIT(nkFloatLit, n.info, n.typ)
case a.kind
of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal
else: stackTrace(c, n, errFieldXNotFound, "floatVal")
else: stackTrace(c, n.info, errFieldXNotFound, "floatVal")
of mNSymbol:
result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return
if result.kind != nkSym: stackTrace(c, n, errFieldXNotFound, "symbol")
if result.kind != nkSym: stackTrace(c, n.info, errFieldXNotFound, "symbol")
of mNIdent:
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
if result.kind != nkIdent: stackTrace(c, n, errFieldXNotFound, "ident")
if result.kind != nkIdent: stackTrace(c, n.info, errFieldXNotFound, "ident")
of mNGetType:
var ast = evalAux(c, n.sons[1], {})
InternalAssert c.getType != nil
@ -1186,7 +1159,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = newNodeIT(nkStrLit, n.info, n.typ)
case a.kind
of nkStrLit..nkTripleStrLit: result.strVal = a.strVal
else: stackTrace(c, n, errFieldXNotFound, "strVal")
else: stackTrace(c, n.info, errFieldXNotFound, "strVal")
of mNSetIntVal:
result = evalAux(c, n.sons[1], {efLValue})
if isSpecial(result): return
@ -1197,7 +1170,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result.kind in {nkCharLit..nkInt64Lit}:
a.intVal = result.intVal
else:
stackTrace(c, n, errFieldXNotFound, "intVal")
stackTrace(c, n.info, errFieldXNotFound, "intVal")
result = emptyNode
of mNSetFloatVal:
result = evalAux(c, n.sons[1], {efLValue})
@ -1209,7 +1182,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result.kind in {nkFloatLit..nkFloat64Lit}:
a.floatVal = result.floatVal
else:
stackTrace(c, n, errFieldXNotFound, "floatVal")
stackTrace(c, n.info, errFieldXNotFound, "floatVal")
result = emptyNode
of mNSetSymbol:
result = evalAux(c, n.sons[1], {efLValue})
@ -1220,7 +1193,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
if a.kind == nkSym and result.kind == nkSym:
a.sym = result.sym
else:
stackTrace(c, n, errFieldXNotFound, "symbol")
stackTrace(c, n.info, errFieldXNotFound, "symbol")
result = emptyNode
of mNSetIdent:
result = evalAux(c, n.sons[1], {efLValue})
@ -1231,7 +1204,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
if a.kind == nkIdent and result.kind == nkIdent:
a.ident = result.ident
else:
stackTrace(c, n, errFieldXNotFound, "ident")
stackTrace(c, n.info, errFieldXNotFound, "ident")
result = emptyNode
of mNSetType:
result = evalAux(c, n.sons[1], {efLValue})
@ -1252,7 +1225,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
if a.kind in {nkStrLit..nkTripleStrLit} and
result.kind in {nkStrLit..nkTripleStrLit}:
a.strVal = result.strVal
else: stackTrace(c, n, errFieldXNotFound, "strVal")
else: stackTrace(c, n.info, errFieldXNotFound, "strVal")
result = emptyNode
of mNNewNimNode:
result = evalAux(c, n.sons[1], {})
@ -1280,7 +1253,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
if not (result.kind in {nkStrLit..nkTripleStrLit}):
stackTrace(c, n, errFieldXNotFound, "strVal")
stackTrace(c, n.info, errFieldXNotFound, "strVal")
return
var a = result
result = newNodeIT(nkIdent, n.info, n.typ)
@ -1333,7 +1306,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNError:
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
stackTrace(c, n, errUser, getStrValue(result))
stackTrace(c, n.info, errUser, getStrValue(result))
result = emptyNode
of mConStrStr:
result = evalConStrStr(c, n)
@ -1353,7 +1326,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
result.strVal = newString(0)
of mNCallSite:
if c.callsite != nil: result = c.callsite
else: stackTrace(c, n, errFieldXNotFound, "callsite")
else: stackTrace(c, n.info, errFieldXNotFound, "callsite")
else:
result = evalAux(c, n.sons[1], {})
if isSpecial(result): return
@ -1371,10 +1344,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
if isEmpty(a) or isEmpty(b) or isEmpty(cc): result = emptyNode
else: result = evalOp(m, n, a, b, cc)
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = emptyNode
dec(gNestedEvals)
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
if gNestedEvals <= 0: stackTrace(c, n.info, errTooManyIterations)
case n.kind
of nkSym: result = evalSym(c, n, flags)
of nkType..nkNilLit:
@ -1473,6 +1446,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
result = n
else: InternalError(n.info, "evalAux: " & $n.kind)
if result == nil:
debug n
InternalError(n.info, "evalAux: returned nil " & $n.kind)
inc(gNestedEvals)
@ -1489,9 +1463,9 @@ proc eval*(c: PEvalContext, n: PNode): PNode =
result = tryEval(c, n)
if result.kind == nkExceptBranch:
if sonsLen(result) >= 1:
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
stackTrace(c, n.info, errUnhandledExceptionX, typeToString(result.typ))
else:
stackTrace(c, result, errCannotInterpretNodeX, renderTree(n))
stackTrace(c, result.info, errCannotInterpretNodeX, renderTree(n))
proc evalConstExprAux(module, prc: PSym, e: PNode, mode: TEvalMode): PNode =
var p = newEvalContext(module, mode)
@ -1531,7 +1505,7 @@ proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
# setup parameters:
for i in 1 .. < L: s.slots[i] = setupMacroParam(n.sons[i])
pushStackFrame(c, s)
discard eval(c, sym.getBody)
discard eval(c, optBody(c, sym))
result = s.slots[0]
popStackFrame(c)
if cyclicTree(result): GlobalError(n.info, errCyclicTree)