refactorings for the eval engine; bugfix: clean templates as accessors
This commit is contained in:
parent
0c18e05336
commit
bfbdb1f028
10 changed files with 235 additions and 239 deletions
|
|
@ -211,7 +211,7 @@ type
|
||||||
nkClosure, # (prc, env)-pair (internally used for code gen)
|
nkClosure, # (prc, env)-pair (internally used for code gen)
|
||||||
nkGotoState, # used for the state machine (for iterators)
|
nkGotoState, # used for the state machine (for iterators)
|
||||||
nkState, # give a label to a code section (for iterators)
|
nkState, # give a label to a code section (for iterators)
|
||||||
nkBreakState # special break statement for easier code generation
|
nkBreakState, # special break statement for easier code generation
|
||||||
TNodeKinds* = set[TNodeKind]
|
TNodeKinds* = set[TNodeKind]
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -534,7 +534,6 @@ type
|
||||||
when defined(useNodeIds):
|
when defined(useNodeIds):
|
||||||
id*: int
|
id*: int
|
||||||
typ*: PType
|
typ*: PType
|
||||||
comment*: string
|
|
||||||
info*: TLineInfo
|
info*: TLineInfo
|
||||||
flags*: TNodeFlags
|
flags*: TNodeFlags
|
||||||
case Kind*: TNodeKind
|
case Kind*: TNodeKind
|
||||||
|
|
@ -550,6 +549,7 @@ type
|
||||||
ident*: PIdent
|
ident*: PIdent
|
||||||
else:
|
else:
|
||||||
sons*: TNodeSeq
|
sons*: TNodeSeq
|
||||||
|
comment*: string
|
||||||
|
|
||||||
TSymSeq* = seq[PSym]
|
TSymSeq* = seq[PSym]
|
||||||
TStrTable* = object # a table[PIdent] of PSym
|
TStrTable* = object # a table[PIdent] of PSym
|
||||||
|
|
@ -667,7 +667,7 @@ type
|
||||||
# for modules, an unique index corresponding
|
# for modules, an unique index corresponding
|
||||||
# to the module's fileIdx
|
# to the module's fileIdx
|
||||||
# for variables a slot index for the evaluator
|
# for variables a slot index for the evaluator
|
||||||
|
# for routines a superop-ID
|
||||||
offset*: int # offset of record field
|
offset*: int # offset of record field
|
||||||
loc*: TLoc
|
loc*: TLoc
|
||||||
annex*: PLib # additional fields (seldom used, so we use a
|
annex*: PLib # additional fields (seldom used, so we use a
|
||||||
|
|
@ -778,10 +778,10 @@ const
|
||||||
genericParamsPos* = 2
|
genericParamsPos* = 2
|
||||||
paramsPos* = 3
|
paramsPos* = 3
|
||||||
pragmasPos* = 4
|
pragmasPos* = 4
|
||||||
exceptionPos* = 5 # will be used for exception tracking
|
optimizedCodePos* = 5 # will be used for exception tracking
|
||||||
bodyPos* = 6 # position of body; use rodread.getBody() instead!
|
bodyPos* = 6 # position of body; use rodread.getBody() instead!
|
||||||
resultPos* = 7
|
resultPos* = 7
|
||||||
dispatcherPos* = 8 # caution: if method has no 'result' it can be position 5!
|
dispatcherPos* = 8 # caution: if method has no 'result' it can be position 7!
|
||||||
|
|
||||||
nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
|
nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix,
|
||||||
nkCommand, nkCallStrLit, nkHiddenCallConv}
|
nkCommand, nkCallStrLit, nkHiddenCallConv}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ proc InitDefines*() =
|
||||||
DefineSymbol("nimmixin")
|
DefineSymbol("nimmixin")
|
||||||
DefineSymbol("nimeffects")
|
DefineSymbol("nimeffects")
|
||||||
DefineSymbol("nimbabel")
|
DefineSymbol("nimbabel")
|
||||||
|
DefineSymbol("nimsuperops")
|
||||||
|
|
||||||
# add platform specific symbols:
|
# add platform specific symbols:
|
||||||
case targetCPU
|
case targetCPU
|
||||||
|
|
|
||||||
|
|
@ -110,13 +110,18 @@ proc stackTraceAux(x: PStackFrame) =
|
||||||
add(s, x.prc.name.s)
|
add(s, x.prc.name.s)
|
||||||
MsgWriteln(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)")
|
MsgWriteln("stack trace: (most recent call last)")
|
||||||
stackTraceAux(c.tos)
|
stackTraceAux(c.tos)
|
||||||
LocalError(n.info, msg, arg)
|
LocalError(info, msg, arg)
|
||||||
|
|
||||||
proc isSpecial(n: PNode): bool {.inline.} =
|
template isSpecial(n: PNode): bool = n.kind == nkExceptBranch
|
||||||
result = 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) =
|
proc myreset(n: PNode) =
|
||||||
when defined(system.reset):
|
when defined(system.reset):
|
||||||
|
|
@ -128,9 +133,8 @@ proc evalIf(c: PEvalContext, n: PNode): PNode =
|
||||||
var i = 0
|
var i = 0
|
||||||
var length = sonsLen(n)
|
var length = sonsLen(n)
|
||||||
while (i < length) and (sonsLen(n.sons[i]) >= 2):
|
while (i < length) and (sonsLen(n.sons[i]) >= 2):
|
||||||
result = evalAux(c, n.sons[i].sons[0], {})
|
evalX(n.sons[i].sons[0], {})
|
||||||
if isSpecial(result): return
|
if result.kind == nkIntLit and result.intVal != 0:
|
||||||
if (result.kind == nkIntLit) and (result.intVal != 0):
|
|
||||||
return evalAux(c, n.sons[i].sons[1], {})
|
return evalAux(c, n.sons[i].sons[1], {})
|
||||||
inc(i)
|
inc(i)
|
||||||
if (i < length) and (sonsLen(n.sons[i]) < 2):
|
if (i < length) and (sonsLen(n.sons[i]) < 2):
|
||||||
|
|
@ -139,8 +143,7 @@ proc evalIf(c: PEvalContext, n: PNode): PNode =
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalCase(c: PEvalContext, n: PNode): PNode =
|
proc evalCase(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[0], {})
|
evalX(n.sons[0], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var res = result
|
var res = result
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
|
|
@ -160,8 +163,7 @@ var
|
||||||
|
|
||||||
proc evalWhile(c: PEvalContext, n: PNode): PNode =
|
proc evalWhile(c: PEvalContext, n: PNode): PNode =
|
||||||
while true:
|
while true:
|
||||||
result = evalAux(c, n.sons[0], {})
|
evalX(n.sons[0], {})
|
||||||
if isSpecial(result): return
|
|
||||||
if getOrdValue(result) == 0: break
|
if getOrdValue(result) == 0: break
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
case result.kind
|
case result.kind
|
||||||
|
|
@ -177,7 +179,7 @@ proc evalWhile(c: PEvalContext, n: PNode): PNode =
|
||||||
if allowInfiniteLoops in c.features:
|
if allowInfiniteLoops in c.features:
|
||||||
gWhileCounter = 0
|
gWhileCounter = 0
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errTooManyIterations)
|
stackTrace(c, n.info, errTooManyIterations)
|
||||||
break
|
break
|
||||||
|
|
||||||
proc evalBlock(c: PEvalContext, n: PNode): PNode =
|
proc evalBlock(c: PEvalContext, n: PNode): PNode =
|
||||||
|
|
@ -222,7 +224,9 @@ proc evalTry(c: PEvalContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
for j in countup(0, blen - 2):
|
for j in countup(0, blen - 2):
|
||||||
assert(n.sons[i].sons[j].kind == nkType)
|
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], {})
|
result = evalAux(c, n.sons[i].sons[blen - 1], {})
|
||||||
exc = result
|
exc = result
|
||||||
break
|
break
|
||||||
|
|
@ -290,14 +294,17 @@ proc evalVarValue(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n, {})
|
result = evalAux(c, n, {})
|
||||||
if result.kind in {nkType..nkNilLit}: result = result.copyNode
|
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) =
|
proc setSlot(c: PStackFrame, sym: PSym, val: PNode) =
|
||||||
assert sym.owner == c.prc
|
assert sym.owner == c.prc
|
||||||
var idx = sym.position
|
let idx = allocSlot(c, sym)
|
||||||
if idx == 0:
|
|
||||||
idx = c.slots.len
|
|
||||||
if idx == 0: idx = 1
|
|
||||||
sym.position = idx
|
|
||||||
setLen(c.slots, max(idx+1, c.slots.len))
|
|
||||||
c.slots[idx] = val
|
c.slots[idx] = val
|
||||||
|
|
||||||
proc setVar(c: PEvalContext, v: PSym, n: PNode) =
|
proc setVar(c: PEvalContext, v: PSym, n: PNode) =
|
||||||
|
|
@ -313,7 +320,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalVarValue(c, a.lastSon)
|
result = evalVarValue(c, a.lastSon)
|
||||||
if result.kind in {nkType..nkNilLit}:
|
if result.kind in {nkType..nkNilLit}:
|
||||||
result = result.copyNode
|
result = result.copyNode
|
||||||
if isSpecial(result): return
|
bailout()
|
||||||
if result.kind != nkPar:
|
if result.kind != nkPar:
|
||||||
return raiseCannotEval(c, n.info)
|
return raiseCannotEval(c, n.info)
|
||||||
for i in 0 .. a.len-3:
|
for i in 0 .. a.len-3:
|
||||||
|
|
@ -322,7 +329,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
if a.sons[2].kind != nkEmpty:
|
if a.sons[2].kind != nkEmpty:
|
||||||
result = evalVarValue(c, a.sons[2])
|
result = evalVarValue(c, a.sons[2])
|
||||||
if isSpecial(result): return
|
bailout()
|
||||||
else:
|
else:
|
||||||
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
result = getNullValue(a.sons[0].typ, a.sons[0].info)
|
||||||
if a.sons[0].kind == nkSym:
|
if a.sons[0].kind == nkSym:
|
||||||
|
|
@ -331,8 +338,7 @@ proc evalVar(c: PEvalContext, n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
# assign to a.sons[0]:
|
# assign to a.sons[0]:
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, a.sons[0], {})
|
evalX(a.sons[0], {})
|
||||||
if isSpecial(result): return
|
|
||||||
myreset(x)
|
myreset(x)
|
||||||
x.kind = result.kind
|
x.kind = result.kind
|
||||||
x.typ = result.typ
|
x.typ = result.typ
|
||||||
|
|
@ -392,6 +398,9 @@ proc evalGlobalVar(c: PEvalContext, s: PSym, flags: TEvalFlags): PNode =
|
||||||
else:
|
else:
|
||||||
result = raiseCannotEval(nil, s.info)
|
result = raiseCannotEval(nil, s.info)
|
||||||
|
|
||||||
|
proc optBody(c: PEvalContext, s: PSym): PNode =
|
||||||
|
result = s.getBody
|
||||||
|
|
||||||
proc evalCall(c: PEvalContext, n: PNode): PNode =
|
proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
var d = newStackFrame()
|
var d = newStackFrame()
|
||||||
d.call = n
|
d.call = n
|
||||||
|
|
@ -400,8 +409,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
setlen(d.slots, sonsLen(n) + ord(isClosure))
|
setlen(d.slots, sonsLen(n) + ord(isClosure))
|
||||||
if isClosure:
|
if isClosure:
|
||||||
#debug prc
|
#debug prc
|
||||||
result = evalAux(c, prc.sons[1], {efLValue})
|
evalX(prc.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
d.slots[sonsLen(n)] = result
|
d.slots[sonsLen(n)] = result
|
||||||
result = evalAux(c, prc.sons[0], {})
|
result = evalAux(c, prc.sons[0], {})
|
||||||
else:
|
else:
|
||||||
|
|
@ -418,8 +426,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
InternalError(n.info, "evalCall")
|
InternalError(n.info, "evalCall")
|
||||||
return
|
return
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
result = evalAux(c, n.sons[i], {})
|
evalX(n.sons[i], {})
|
||||||
if isSpecial(result): return
|
|
||||||
d.slots[i] = result
|
d.slots[i] = result
|
||||||
if n.typ != nil: d.slots[0] = getNullValue(n.typ, n.info)
|
if n.typ != nil: d.slots[0] = getNullValue(n.typ, n.info)
|
||||||
|
|
||||||
|
|
@ -432,17 +439,14 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
return callForeignFunction(newCall)
|
return callForeignFunction(newCall)
|
||||||
|
|
||||||
pushStackFrame(c, d)
|
pushStackFrame(c, d)
|
||||||
result = evalAux(c, prc.sym.getBody, {})
|
evalX(optBody(c, prc.sym), {})
|
||||||
if result.kind == nkExceptBranch: return
|
|
||||||
if n.typ != nil: result = d.slots[0]
|
if n.typ != nil: result = d.slots[0]
|
||||||
popStackFrame(c)
|
popStackFrame(c)
|
||||||
|
|
||||||
proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = evalAux(c, n.sons[0], flags)
|
evalX(n.sons[0], flags)
|
||||||
if isSpecial(result): return
|
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var idx = getOrdValue(result)
|
var idx = getOrdValue(result)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
case x.kind
|
case x.kind
|
||||||
|
|
@ -452,13 +456,13 @@ proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
if result.kind == nkExprColonExpr: result = result.sons[1]
|
if result.kind == nkExprColonExpr: result = result.sons[1]
|
||||||
if not aliasNeeded(result, flags): result = copyTree(result)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errIndexOutOfBounds)
|
stackTrace(c, n.info, errIndexOutOfBounds)
|
||||||
of nkBracket, nkMetaNode:
|
of nkBracket, nkMetaNode:
|
||||||
if (idx >= 0) and (idx < sonsLen(x)):
|
if (idx >= 0) and (idx < sonsLen(x)):
|
||||||
result = x.sons[int(idx)]
|
result = x.sons[int(idx)]
|
||||||
if not aliasNeeded(result, flags): result = copyTree(result)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errIndexOutOfBounds)
|
stackTrace(c, n.info, errIndexOutOfBounds)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if efLValue in flags: return raiseCannotEval(c, n.info)
|
if efLValue in flags: return raiseCannotEval(c, n.info)
|
||||||
result = newNodeIT(nkCharLit, x.info, getSysType(tyChar))
|
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):
|
elif idx == len(x.strVal):
|
||||||
nil
|
nil
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errIndexOutOfBounds)
|
stackTrace(c, n.info, errIndexOutOfBounds)
|
||||||
else: stackTrace(c, n, errNilAccess)
|
else: stackTrace(c, n.info, errNilAccess)
|
||||||
|
|
||||||
proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
# a real field access; proc calls have already been transformed
|
# a real field access; proc calls have already been transformed
|
||||||
# XXX: field checks!
|
# XXX: field checks!
|
||||||
result = evalAux(c, n.sons[0], flags)
|
evalX(n.sons[0], flags)
|
||||||
if isSpecial(result): return
|
|
||||||
var x = result
|
var x = result
|
||||||
if x.kind != nkPar: return raiseCannotEval(c, n.info)
|
if x.kind != nkPar: return raiseCannotEval(c, n.info)
|
||||||
# this is performance critical:
|
# this is performance critical:
|
||||||
|
|
@ -482,48 +485,26 @@ proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = x.sons[field.position]
|
result = x.sons[field.position]
|
||||||
if result.kind == nkExprColonExpr: result = result.sons[1]
|
if result.kind == nkExprColonExpr: result = result.sons[1]
|
||||||
if not aliasNeeded(result, flags): result = copyTree(result)
|
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]
|
var a = n.sons[0]
|
||||||
if a.kind == nkBracketExpr and a.sons[0].typ.kind in {tyString, tyCString}:
|
if a.kind == nkBracketExpr and a.sons[0].typ.kind in {tyString, tyCString}:
|
||||||
result = evalAux(c, a.sons[0], {efLValue})
|
evalX(a.sons[0], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, a.sons[1], {})
|
evalX(a.sons[1], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var idx = getOrdValue(result)
|
var idx = getOrdValue(result)
|
||||||
|
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if result.kind notin {nkIntLit, nkCharLit}: return c.raiseCannotEval(n.info)
|
||||||
if result.kind != nkCharLit: return raiseCannotEval(c, 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))
|
x.strVal[int(idx)] = chr(int(result.intVal))
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errIndexOutOfBounds)
|
stackTrace(c, n.info, errIndexOutOfBounds)
|
||||||
else:
|
else:
|
||||||
result = evalAux(c, n.sons[0], {efLValue})
|
evalX(n.sons[0], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
|
||||||
myreset(x)
|
myreset(x)
|
||||||
x.kind = result.kind
|
x.kind = result.kind
|
||||||
x.typ = result.typ
|
x.typ = result.typ
|
||||||
|
|
@ -541,13 +522,11 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
|
||||||
assert result.kind == nkEmpty
|
assert result.kind == nkEmpty
|
||||||
|
|
||||||
proc evalSwap(c: PEvalContext, n: PNode): PNode =
|
proc evalSwap(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[0], {efLValue})
|
evalX(n.sons[0], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
evalX(n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
if x.kind != result.kind:
|
if x.kind != result.kind:
|
||||||
stackTrace(c, n, errCannotInterpretNodeX, $n.kind)
|
stackTrace(c, n.info, errCannotInterpretNodeX, $n.kind)
|
||||||
else:
|
else:
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkCharLit..nkInt64Lit: swap(x.intVal, result.intVal)
|
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)
|
result = raiseCannotEval(c, n.info)
|
||||||
|
|
||||||
proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
|
proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
evalX(n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
evalX(n.sons[2], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var b = result
|
var b = result
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit: a.intval = a.intVal + sign * getOrdValue(b)
|
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 =
|
proc evalEcho(c: PEvalContext, n: PNode): PNode =
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
result = evalAux(c, n.sons[i], {})
|
evalX(n.sons[i], {})
|
||||||
if isSpecial(result): return
|
|
||||||
Write(stdout, getStrValue(result))
|
Write(stdout, getStrValue(result))
|
||||||
writeln(stdout, "")
|
writeln(stdout, "")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
||||||
proc evalExit(c: PEvalContext, n: PNode): PNode =
|
proc evalExit(c: PEvalContext, n: PNode): PNode =
|
||||||
if c.mode in {emRepl, emStatic}:
|
if c.mode in {emRepl, emStatic}:
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
|
||||||
Message(n.info, hintQuitCalled)
|
Message(n.info, hintQuitCalled)
|
||||||
quit(int(getOrdValue(result)))
|
quit(int(getOrdValue(result)))
|
||||||
else:
|
else:
|
||||||
result = raiseCannotEval(c, n.info)
|
result = raiseCannotEval(c, n.info)
|
||||||
|
|
||||||
proc evalOr(c: PEvalContext, n: PNode): PNode =
|
proc evalOr(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if result.intVal == 0: result = evalAux(c, n.sons[2], {})
|
||||||
if result.kind != nkIntLit: InternalError(n.info, "evalOr")
|
|
||||||
elif result.intVal == 0: result = evalAux(c, n.sons[2], {})
|
|
||||||
|
|
||||||
proc evalAnd(c: PEvalContext, n: PNode): PNode =
|
proc evalAnd(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if result.intVal != 0: result = evalAux(c, n.sons[2], {})
|
||||||
if result.kind != nkIntLit: InternalError(n.info, "evalAnd")
|
|
||||||
elif result.intVal != 0: result = evalAux(c, n.sons[2], {})
|
|
||||||
|
|
||||||
proc evalNew(c: PEvalContext, n: PNode): PNode =
|
proc evalNew(c: PEvalContext, n: PNode): PNode =
|
||||||
#if c.mode == emOptimize: return raiseCannotEval(c, n.info)
|
#if c.mode == emOptimize: return raiseCannotEval(c, n.info)
|
||||||
|
|
||||||
# we ignore the finalizer for now and most likely forever :-)
|
# we ignore the finalizer for now and most likely forever :-)
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
evalX(n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
var a = result
|
var a = result
|
||||||
var t = skipTypes(n.sons[1].typ, abstractVar)
|
var t = skipTypes(n.sons[1].typ, abstractVar)
|
||||||
if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty")
|
if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty")
|
||||||
myreset(a)
|
myreset(a)
|
||||||
a.kind = nkRefTy
|
let u = getNullValue(t.sons[0], n.info)
|
||||||
a.info = n.info
|
a.kind = u.kind
|
||||||
a.typ = t
|
a.typ = t
|
||||||
a.sons = nil
|
shallowCopy(a.sons, u.sons)
|
||||||
addSon(a, getNullValue(t.sons[0], n.info))
|
|
||||||
result = emptyNode
|
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 =
|
proc evalDeref(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = evalAux(c, n.sons[0], {efLValue})
|
evalX(n.sons[0], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
case result.kind
|
case result.kind
|
||||||
of nkNilLit: stackTrace(c, n, errNilAccess)
|
of nkNilLit: stackTrace(c, n.info, errNilAccess)
|
||||||
of nkRefTy:
|
of nkRefTy:
|
||||||
# XXX efLValue?
|
# XXX efLValue?
|
||||||
result = result.sons[0]
|
result = result.sons[0]
|
||||||
else:
|
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 =
|
proc evalAddr(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = evalAux(c, n.sons[0], {efLValue})
|
evalX(n.sons[0], {efLValue})
|
||||||
if isSpecial(result): return
|
|
||||||
var a = result
|
var a = result
|
||||||
var t = newType(tyPtr, c.module)
|
var t = newType(tyPtr, c.module)
|
||||||
addSonSkipIntLit(t, a.typ)
|
addSonSkipIntLit(t, a.typ)
|
||||||
|
|
@ -703,24 +678,22 @@ proc evalUpConv(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
var dest = skipTypes(n.typ, abstractPtrs)
|
var dest = skipTypes(n.typ, abstractPtrs)
|
||||||
var src = skipTypes(result.typ, abstractPtrs)
|
var src = skipTypes(result.typ, abstractPtrs)
|
||||||
if inheritanceDiff(src, dest) > 0:
|
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 =
|
proc evalRangeChck(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[0], {})
|
evalX(n.sons[0], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var x = result
|
var x = result
|
||||||
result = evalAux(c, n.sons[1], {})
|
evalX(n.sons[1], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
evalX(n.sons[2], {})
|
||||||
if isSpecial(result): return
|
|
||||||
var b = result
|
var b = result
|
||||||
if leValueConv(a, x) and leValueConv(x, b):
|
if leValueConv(a, x) and leValueConv(x, b):
|
||||||
result = x # a <= x and x <= b
|
result = x # a <= x and x <= b
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [
|
stackTrace(c, n.info, errGenerated,
|
||||||
typeToString(n.sons[0].typ), typeToString(n.typ)])
|
msgKindToString(errIllegalConvFromXtoY) % [
|
||||||
|
typeToString(n.sons[0].typ), typeToString(n.typ)])
|
||||||
|
|
||||||
proc evalConvStrToCStr(c: PEvalContext, n: PNode): PNode =
|
proc evalConvStrToCStr(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[0], {})
|
result = evalAux(c, n.sons[0], {})
|
||||||
|
|
@ -744,7 +717,7 @@ proc evalRaise(c: PEvalContext, n: PNode): PNode =
|
||||||
elif c.lastException != nil:
|
elif c.lastException != nil:
|
||||||
result = c.lastException
|
result = c.lastException
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errExceptionAlreadyHandled)
|
stackTrace(c, n.info, errExceptionAlreadyHandled)
|
||||||
result = newNodeIT(nkExceptBranch, n.info, nil)
|
result = newNodeIT(nkExceptBranch, n.info, nil)
|
||||||
addSon(result, ast.emptyNode)
|
addSon(result, ast.emptyNode)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1100,7 +1073,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = a.sons[int(k)]
|
result = a.sons[int(k)]
|
||||||
if result == nil: result = newNode(nkEmpty)
|
if result == nil: result = newNode(nkEmpty)
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errIndexOutOfBounds)
|
stackTrace(c, n.info, errIndexOutOfBounds)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNSetChild:
|
of mNSetChild:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
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}):
|
if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}):
|
||||||
a.sons[int(k)] = result
|
a.sons[int(k)] = result
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errIndexOutOfBounds)
|
stackTrace(c, n.info, errIndexOutOfBounds)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNAdd:
|
of mNAdd:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
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)
|
result = newNodeIT(nkIntLit, n.info, n.typ)
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit: result.intVal = a.intVal
|
of nkCharLit..nkInt64Lit: result.intVal = a.intVal
|
||||||
else: stackTrace(c, n, errFieldXNotFound, "intVal")
|
else: stackTrace(c, n.info, errFieldXNotFound, "intVal")
|
||||||
of mNFloatVal:
|
of mNFloatVal:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -1166,15 +1139,15 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = newNodeIT(nkFloatLit, n.info, n.typ)
|
result = newNodeIT(nkFloatLit, n.info, n.typ)
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal
|
of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal
|
||||||
else: stackTrace(c, n, errFieldXNotFound, "floatVal")
|
else: stackTrace(c, n.info, errFieldXNotFound, "floatVal")
|
||||||
of mNSymbol:
|
of mNSymbol:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
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:
|
of mNIdent:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
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:
|
of mNGetType:
|
||||||
var ast = evalAux(c, n.sons[1], {})
|
var ast = evalAux(c, n.sons[1], {})
|
||||||
InternalAssert c.getType != nil
|
InternalAssert c.getType != nil
|
||||||
|
|
@ -1186,7 +1159,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = newNodeIT(nkStrLit, n.info, n.typ)
|
result = newNodeIT(nkStrLit, n.info, n.typ)
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkStrLit..nkTripleStrLit: result.strVal = a.strVal
|
of nkStrLit..nkTripleStrLit: result.strVal = a.strVal
|
||||||
else: stackTrace(c, n, errFieldXNotFound, "strVal")
|
else: stackTrace(c, n.info, errFieldXNotFound, "strVal")
|
||||||
of mNSetIntVal:
|
of mNSetIntVal:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -1197,7 +1170,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result.kind in {nkCharLit..nkInt64Lit}:
|
result.kind in {nkCharLit..nkInt64Lit}:
|
||||||
a.intVal = result.intVal
|
a.intVal = result.intVal
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errFieldXNotFound, "intVal")
|
stackTrace(c, n.info, errFieldXNotFound, "intVal")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNSetFloatVal:
|
of mNSetFloatVal:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
|
|
@ -1209,7 +1182,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result.kind in {nkFloatLit..nkFloat64Lit}:
|
result.kind in {nkFloatLit..nkFloat64Lit}:
|
||||||
a.floatVal = result.floatVal
|
a.floatVal = result.floatVal
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errFieldXNotFound, "floatVal")
|
stackTrace(c, n.info, errFieldXNotFound, "floatVal")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNSetSymbol:
|
of mNSetSymbol:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
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:
|
if a.kind == nkSym and result.kind == nkSym:
|
||||||
a.sym = result.sym
|
a.sym = result.sym
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errFieldXNotFound, "symbol")
|
stackTrace(c, n.info, errFieldXNotFound, "symbol")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNSetIdent:
|
of mNSetIdent:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
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:
|
if a.kind == nkIdent and result.kind == nkIdent:
|
||||||
a.ident = result.ident
|
a.ident = result.ident
|
||||||
else:
|
else:
|
||||||
stackTrace(c, n, errFieldXNotFound, "ident")
|
stackTrace(c, n.info, errFieldXNotFound, "ident")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNSetType:
|
of mNSetType:
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
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
|
if a.kind in {nkStrLit..nkTripleStrLit} and
|
||||||
result.kind in {nkStrLit..nkTripleStrLit}:
|
result.kind in {nkStrLit..nkTripleStrLit}:
|
||||||
a.strVal = result.strVal
|
a.strVal = result.strVal
|
||||||
else: stackTrace(c, n, errFieldXNotFound, "strVal")
|
else: stackTrace(c, n.info, errFieldXNotFound, "strVal")
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mNNewNimNode:
|
of mNNewNimNode:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
|
|
@ -1280,7 +1253,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
if not (result.kind in {nkStrLit..nkTripleStrLit}):
|
if not (result.kind in {nkStrLit..nkTripleStrLit}):
|
||||||
stackTrace(c, n, errFieldXNotFound, "strVal")
|
stackTrace(c, n.info, errFieldXNotFound, "strVal")
|
||||||
return
|
return
|
||||||
var a = result
|
var a = result
|
||||||
result = newNodeIT(nkIdent, n.info, n.typ)
|
result = newNodeIT(nkIdent, n.info, n.typ)
|
||||||
|
|
@ -1333,7 +1306,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
of mNError:
|
of mNError:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
stackTrace(c, n, errUser, getStrValue(result))
|
stackTrace(c, n.info, errUser, getStrValue(result))
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
of mConStrStr:
|
of mConStrStr:
|
||||||
result = evalConStrStr(c, n)
|
result = evalConStrStr(c, n)
|
||||||
|
|
@ -1353,7 +1326,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result.strVal = newString(0)
|
result.strVal = newString(0)
|
||||||
of mNCallSite:
|
of mNCallSite:
|
||||||
if c.callsite != nil: result = c.callsite
|
if c.callsite != nil: result = c.callsite
|
||||||
else: stackTrace(c, n, errFieldXNotFound, "callsite")
|
else: stackTrace(c, n.info, errFieldXNotFound, "callsite")
|
||||||
else:
|
else:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
|
|
@ -1374,7 +1347,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
dec(gNestedEvals)
|
dec(gNestedEvals)
|
||||||
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
|
if gNestedEvals <= 0: stackTrace(c, n.info, errTooManyIterations)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym: result = evalSym(c, n, flags)
|
of nkSym: result = evalSym(c, n, flags)
|
||||||
of nkType..nkNilLit:
|
of nkType..nkNilLit:
|
||||||
|
|
@ -1473,6 +1446,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
result = n
|
result = n
|
||||||
else: InternalError(n.info, "evalAux: " & $n.kind)
|
else: InternalError(n.info, "evalAux: " & $n.kind)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
|
debug n
|
||||||
InternalError(n.info, "evalAux: returned nil " & $n.kind)
|
InternalError(n.info, "evalAux: returned nil " & $n.kind)
|
||||||
inc(gNestedEvals)
|
inc(gNestedEvals)
|
||||||
|
|
||||||
|
|
@ -1489,9 +1463,9 @@ proc eval*(c: PEvalContext, n: PNode): PNode =
|
||||||
result = tryEval(c, n)
|
result = tryEval(c, n)
|
||||||
if result.kind == nkExceptBranch:
|
if result.kind == nkExceptBranch:
|
||||||
if sonsLen(result) >= 1:
|
if sonsLen(result) >= 1:
|
||||||
stackTrace(c, n, errUnhandledExceptionX, typeToString(result.typ))
|
stackTrace(c, n.info, errUnhandledExceptionX, typeToString(result.typ))
|
||||||
else:
|
else:
|
||||||
stackTrace(c, result, errCannotInterpretNodeX, renderTree(n))
|
stackTrace(c, result.info, errCannotInterpretNodeX, renderTree(n))
|
||||||
|
|
||||||
proc evalConstExprAux(module, prc: PSym, e: PNode, mode: TEvalMode): PNode =
|
proc evalConstExprAux(module, prc: PSym, e: PNode, mode: TEvalMode): PNode =
|
||||||
var p = newEvalContext(module, mode)
|
var p = newEvalContext(module, mode)
|
||||||
|
|
@ -1531,7 +1505,7 @@ proc evalMacroCall(c: PEvalContext, n, nOrig: PNode, sym: PSym): PNode =
|
||||||
# setup parameters:
|
# setup parameters:
|
||||||
for i in 1 .. < L: s.slots[i] = setupMacroParam(n.sons[i])
|
for i in 1 .. < L: s.slots[i] = setupMacroParam(n.sons[i])
|
||||||
pushStackFrame(c, s)
|
pushStackFrame(c, s)
|
||||||
discard eval(c, sym.getBody)
|
discard eval(c, optBody(c, sym))
|
||||||
result = s.slots[0]
|
result = s.slots[0]
|
||||||
popStackFrame(c)
|
popStackFrame(c)
|
||||||
if cyclicTree(result): GlobalError(n.info, errCyclicTree)
|
if cyclicTree(result): GlobalError(n.info, errCyclicTree)
|
||||||
|
|
|
||||||
|
|
@ -491,20 +491,13 @@ proc factImplies(fact, prop: PNode): TImplication =
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
case prop.sons[0].sym.magic
|
case prop.sons[0].sym.magic
|
||||||
of mNot:
|
of mNot: result = ~fact.factImplies(prop.sons[1])
|
||||||
result = ~fact.factImplies(prop.sons[1])
|
of mIsNil: result = impliesIsNil(fact, prop)
|
||||||
of mIsNil:
|
of someEq: result = impliesEq(fact, prop)
|
||||||
result = impliesIsNil(fact, prop)
|
of someLe: result = impliesLe(fact, prop.sons[1], prop.sons[2])
|
||||||
of someEq:
|
of someLt: result = impliesLt(fact, prop.sons[1], prop.sons[2])
|
||||||
result = impliesEq(fact, prop)
|
of mInSet: result = impliesIn(fact, prop.sons[2], prop.sons[1])
|
||||||
of someLe:
|
else: internalError(prop.info, "invalid proposition")
|
||||||
result = impliesLe(fact, prop.sons[1], prop.sons[2])
|
|
||||||
of someLt:
|
|
||||||
result = impliesLt(fact, prop.sons[1], prop.sons[2])
|
|
||||||
of mInSet:
|
|
||||||
result = impliesIn(fact, prop.sons[2], prop.sons[1])
|
|
||||||
else:
|
|
||||||
internalError(prop.info, "invalid proposition")
|
|
||||||
|
|
||||||
proc doesImply*(facts: TModel, prop: PNode): TImplication =
|
proc doesImply*(facts: TModel, prop: PNode): TImplication =
|
||||||
assert prop.kind in nkCallKinds
|
assert prop.kind in nkCallKinds
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,7 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||||
of tyPointer:
|
of tyPointer:
|
||||||
# treat a tyPointer like a typed pointer to an array of bytes
|
# treat a tyPointer like a typed pointer to an array of bytes
|
||||||
result = etyInt
|
result = etyInt
|
||||||
of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter,
|
of tyRange, tyDistinct, tyOrdinal, tyConst, tyMutable, tyIter, tyProxy:
|
||||||
tyProxy:
|
|
||||||
result = mapType(t.sons[0])
|
result = mapType(t.sons[0])
|
||||||
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
|
of tyInt..tyInt64, tyUInt..tyUInt64, tyEnum, tyChar: result = etyInt
|
||||||
of tyBool: result = etyBool
|
of tyBool: result = etyBool
|
||||||
|
|
@ -826,17 +825,18 @@ proc genSwap(p: PProc, n: PNode) =
|
||||||
gen(p, n.sons[1], a)
|
gen(p, n.sons[1], a)
|
||||||
gen(p, n.sons[2], b)
|
gen(p, n.sons[2], b)
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
let tmp = ropef("Tmp$1", [toRope(p.unique)])
|
var tmp = ropef("Tmp$1", [toRope(p.unique)])
|
||||||
case mapType(skipTypes(n.sons[1].typ, abstractVar))
|
if mapType(skipTypes(n.sons[1].typ, abstractVar)) == etyBaseIndex:
|
||||||
of etyBaseIndex:
|
|
||||||
inc(p.unique)
|
inc(p.unique)
|
||||||
let tmp2 = ropef("Tmp$1", [toRope(p.unique)])
|
let tmp2 = ropef("Tmp$1", [toRope(p.unique)])
|
||||||
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
|
||||||
internalError(n.info, "genSwap")
|
internalError(n.info, "genSwap")
|
||||||
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1;$n", [tmp, a.address, b.address])
|
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1;$n" |
|
||||||
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1", [tmp2, a.res, b.res])
|
"local $1 = $2; $2 = $3; $3 = $1;$n", [
|
||||||
else:
|
tmp, a.address, b.address])
|
||||||
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1", [tmp, a.res, b.res])
|
tmp = tmp2
|
||||||
|
appf(p.body, "var $1 = $2; $2 = $3; $3 = $1" |
|
||||||
|
"local $1 = $2; $2 = $3; $3 = $1", [tmp, a.res, b.res])
|
||||||
|
|
||||||
proc getFieldPosition(f: PNode): int =
|
proc getFieldPosition(f: PNode): int =
|
||||||
case f.kind
|
case f.kind
|
||||||
|
|
@ -1664,25 +1664,27 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||||
app(p.g.code, p.locals)
|
app(p.g.code, p.locals)
|
||||||
app(p.g.code, p.body)
|
app(p.g.code, p.body)
|
||||||
|
|
||||||
|
proc wholeCode*(m: BModule): PRope =
|
||||||
|
for prc in globals.forwarded:
|
||||||
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
|
var p = newProc(globals, m, nil, m.module.options)
|
||||||
|
app(p.g.code, genProc(p, prc))
|
||||||
|
|
||||||
|
var disp = generateMethodDispatchers()
|
||||||
|
for i in 0..sonsLen(disp)-1:
|
||||||
|
let prc = disp.sons[i].sym
|
||||||
|
if not globals.generatedSyms.containsOrIncl(prc.id):
|
||||||
|
var p = newProc(globals, m, nil, m.module.options)
|
||||||
|
app(p.g.code, genProc(p, prc))
|
||||||
|
|
||||||
|
result = con(globals.typeInfo, globals.code)
|
||||||
|
|
||||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
if passes.skipCodegen(n): return n
|
if passes.skipCodegen(n): return n
|
||||||
result = myProcess(b, n)
|
result = myProcess(b, n)
|
||||||
var m = BModule(b)
|
var m = BModule(b)
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
for prc in globals.forwarded:
|
let code = wholeCode(m)
|
||||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
|
||||||
var p = newProc(globals, m, nil, m.module.options)
|
|
||||||
app(p.g.code, genProc(p, prc))
|
|
||||||
|
|
||||||
var disp = generateMethodDispatchers()
|
|
||||||
for i in 0..sonsLen(disp)-1:
|
|
||||||
let prc = disp.sons[i].sym
|
|
||||||
if not globals.generatedSyms.containsOrIncl(prc.id):
|
|
||||||
var p = newProc(globals, m, nil, m.module.options)
|
|
||||||
app(p.g.code, genProc(p, prc))
|
|
||||||
|
|
||||||
# write the file:
|
|
||||||
var code = con(globals.typeInfo, globals.code)
|
|
||||||
var outfile = changeFileExt(completeCFilePath(m.module.filename), "js")
|
var outfile = changeFileExt(completeCFilePath(m.module.filename), "js")
|
||||||
discard writeRopeIfNotEqual(con(genHeader(), code), outfile)
|
discard writeRopeIfNotEqual(con(genHeader(), code), outfile)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -341,6 +341,18 @@ proc CommandInteractive =
|
||||||
incl(m.flags, sfMainModule)
|
incl(m.flags, sfMainModule)
|
||||||
processModule(m, LLStreamOpenStdIn(), nil)
|
processModule(m, LLStreamOpenStdIn(), nil)
|
||||||
|
|
||||||
|
proc execute*(program: string) =
|
||||||
|
passes.gIncludeFile = includeModule
|
||||||
|
passes.gImportModule = importModule
|
||||||
|
initDefines()
|
||||||
|
LoadConfigs(DefaultConfig)
|
||||||
|
InteractivePasses()
|
||||||
|
appendStr(searchPaths, options.libpath)
|
||||||
|
compileSystemModule()
|
||||||
|
var m = makeStdinModule()
|
||||||
|
incl(m.flags, sfMainModule)
|
||||||
|
processModule(m, LLStreamOpen(program), nil)
|
||||||
|
|
||||||
const evalPasses = [verbosePass, semPass, evalPass]
|
const evalPasses = [verbosePass, semPass, evalPass]
|
||||||
|
|
||||||
proc evalNim(nodes: PNode, module: PSym) =
|
proc evalNim(nodes: PNode, module: PSym) =
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const
|
||||||
wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
wCompilerProc, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
||||||
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC,
|
||||||
wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
wNoStackFrame, wError, wDiscardable, wNoInit, wDestructor, wCodegenDecl,
|
||||||
wGenSym, wInject, wRaises, wTags}
|
wGenSym, wInject, wRaises, wTags, wOperator}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas
|
methodPragmas* = procPragmas
|
||||||
templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty}
|
templatePragmas* = {wImmediate, wDeprecated, wError, wGenSym, wInject, wDirty}
|
||||||
|
|
@ -34,7 +34,7 @@ const
|
||||||
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect,
|
iteratorPragmas* = {FirstCallConv..LastCallConv, wNosideEffect, wSideEffect,
|
||||||
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern,
|
||||||
wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject, wRaises,
|
wImportcpp, wImportobjc, wError, wDiscardable, wGenSym, wInject, wRaises,
|
||||||
wTags}
|
wTags, wOperator}
|
||||||
exprPragmas* = {wLine}
|
exprPragmas* = {wLine}
|
||||||
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
||||||
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings, wHints,
|
||||||
|
|
@ -717,6 +717,9 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
|
||||||
if sym == nil: invalidPragma(it)
|
if sym == nil: invalidPragma(it)
|
||||||
of wLine: PragmaLine(c, it)
|
of wLine: PragmaLine(c, it)
|
||||||
of wRaises, wTags: pragmaRaisesOrTags(c, it)
|
of wRaises, wTags: pragmaRaisesOrTags(c, it)
|
||||||
|
of wOperator:
|
||||||
|
if sym == nil: invalidPragma(it)
|
||||||
|
else: sym.position = expectIntLit(c, it)
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: invalidPragma(it)
|
else: invalidPragma(it)
|
||||||
else: processNote(c, it)
|
else: processNote(c, it)
|
||||||
|
|
|
||||||
|
|
@ -620,7 +620,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||||
{skProc, skMethod, skConverter, skMacro, skTemplate})
|
{skProc, skMethod, skConverter, skMacro, skTemplate})
|
||||||
if result != nil:
|
if result != nil:
|
||||||
if result.sons[0].kind != nkSym:
|
if result.sons[0].kind != nkSym:
|
||||||
InternalError("semDirectCallAnalyseEffects")
|
InternalError("semOverloadedCallAnalyseEffects")
|
||||||
return
|
return
|
||||||
let callee = result.sons[0].sym
|
let callee = result.sons[0].sym
|
||||||
case callee.kind
|
case callee.kind
|
||||||
|
|
@ -632,10 +632,6 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||||
if {sfImportc, sfSideEffect} * callee.flags != {}:
|
if {sfImportc, sfSideEffect} * callee.flags != {}:
|
||||||
incl(c.p.owner.flags, sfSideEffect)
|
incl(c.p.owner.flags, sfSideEffect)
|
||||||
|
|
||||||
proc semDirectCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
|
||||||
flags: TExprFlags): PNode =
|
|
||||||
result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags)
|
|
||||||
|
|
||||||
proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode
|
proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||||
proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = nil
|
result = nil
|
||||||
|
|
@ -707,12 +703,28 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
LocalError(n.info, errExprXCannotBeCalled,
|
LocalError(n.info, errExprXCannotBeCalled,
|
||||||
renderTree(n, {renderNoComments}))
|
renderTree(n, {renderNoComments}))
|
||||||
return errorNode(c, n)
|
return errorNode(c, n)
|
||||||
|
#result = afterCallActions(c, result, nOrig, flags)
|
||||||
fixAbstractType(c, result)
|
fixAbstractType(c, result)
|
||||||
analyseIfAddressTakenInCall(c, result)
|
analyseIfAddressTakenInCall(c, result)
|
||||||
if result.sons[0].kind == nkSym and result.sons[0].sym.magic != mNone:
|
if result.sons[0].kind == nkSym and result.sons[0].sym.magic != mNone:
|
||||||
result = magicsAfterOverloadResolution(c, result, flags)
|
result = magicsAfterOverloadResolution(c, result, flags)
|
||||||
result = evalAtCompileTime(c, result)
|
result = evalAtCompileTime(c, result)
|
||||||
|
|
||||||
|
proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
|
||||||
|
result = n
|
||||||
|
let callee = result.sons[0].sym
|
||||||
|
case callee.kind
|
||||||
|
of skMacro: result = semMacroExpr(c, result, orig, callee)
|
||||||
|
of skTemplate: result = semTemplateExpr(c, result, callee)
|
||||||
|
else:
|
||||||
|
semFinishOperands(c, result)
|
||||||
|
activate(c, result)
|
||||||
|
fixAbstractType(c, result)
|
||||||
|
analyseIfAddressTakenInCall(c, result)
|
||||||
|
if callee.magic != mNone:
|
||||||
|
result = magicsAfterOverloadResolution(c, result, flags)
|
||||||
|
result = evalAtCompileTime(c, result)
|
||||||
|
|
||||||
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# this seems to be a hotspot in the compiler!
|
# this seems to be a hotspot in the compiler!
|
||||||
let nOrig = n.copyTree
|
let nOrig = n.copyTree
|
||||||
|
|
@ -723,18 +735,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if result == nil:
|
if result == nil:
|
||||||
NotFoundError(c, n)
|
NotFoundError(c, n)
|
||||||
return errorNode(c, n)
|
return errorNode(c, n)
|
||||||
let callee = result.sons[0].sym
|
result = afterCallActions(c, result, nOrig, flags)
|
||||||
case callee.kind
|
|
||||||
of skMacro: result = semMacroExpr(c, result, nOrig, callee)
|
|
||||||
of skTemplate: result = semTemplateExpr(c, result, callee)
|
|
||||||
else:
|
|
||||||
semFinishOperands(c, n)
|
|
||||||
activate(c, n)
|
|
||||||
fixAbstractType(c, result)
|
|
||||||
analyseIfAddressTakenInCall(c, result)
|
|
||||||
if callee.magic != mNone:
|
|
||||||
result = magicsAfterOverloadResolution(c, result, flags)
|
|
||||||
result = evalAtCompileTime(c, result)
|
|
||||||
|
|
||||||
proc buildStringify(c: PContext, arg: PNode): PNode =
|
proc buildStringify(c: PContext, arg: PNode): PNode =
|
||||||
if arg.typ != nil and
|
if arg.typ != nil and
|
||||||
|
|
@ -928,30 +929,33 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = n
|
result = n
|
||||||
markUsed(n, f)
|
markUsed(n, f)
|
||||||
|
|
||||||
|
proc dotTransformation(c: PContext, n: PNode): PNode =
|
||||||
|
if isSymChoice(n.sons[1]):
|
||||||
|
result = newNodeI(nkDotCall, n.info)
|
||||||
|
addSon(result, n.sons[1])
|
||||||
|
addSon(result, copyTree(n[0]))
|
||||||
|
else:
|
||||||
|
var i = considerAcc(n.sons[1])
|
||||||
|
var f = searchInScopes(c, i)
|
||||||
|
# if f != nil and f.kind == skStub: loadStub(f)
|
||||||
|
# ``loadStub`` is not correct here as we don't care for ``f`` really
|
||||||
|
if f != nil:
|
||||||
|
# BUGFIX: do not check for (f.kind in {skProc, skMethod, skIterator}) here
|
||||||
|
# This special node kind is to merge with the call handler in `semExpr`.
|
||||||
|
result = newNodeI(nkDotCall, n.info)
|
||||||
|
addSon(result, newIdentNode(i, n[1].info))
|
||||||
|
addSon(result, copyTree(n[0]))
|
||||||
|
else:
|
||||||
|
if not ContainsOrIncl(c.UnknownIdents, i.id):
|
||||||
|
LocalError(n.Info, errUndeclaredFieldX, i.s)
|
||||||
|
result = errorNode(c, n)
|
||||||
|
|
||||||
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
# this is difficult, because the '.' is used in many different contexts
|
# this is difficult, because the '.' is used in many different contexts
|
||||||
# in Nimrod. We first allow types in the semantic checking.
|
# in Nimrod. We first allow types in the semantic checking.
|
||||||
result = builtinFieldAccess(c, n, flags)
|
result = builtinFieldAccess(c, n, flags)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
if isSymChoice(n.sons[1]):
|
result = dotTransformation(c, n)
|
||||||
result = newNodeI(nkDotCall, n.info)
|
|
||||||
addSon(result, n.sons[1])
|
|
||||||
addSon(result, copyTree(n[0]))
|
|
||||||
else:
|
|
||||||
var i = considerAcc(n.sons[1])
|
|
||||||
var f = searchInScopes(c, i)
|
|
||||||
# if f != nil and f.kind == skStub: loadStub(f)
|
|
||||||
# ``loadStub`` is not correct here as we don't care for ``f`` really
|
|
||||||
if f != nil:
|
|
||||||
# BUGFIX: do not check for (f.kind in {skProc, skMethod, skIterator}) here
|
|
||||||
# This special node kind is to merge with the call handler in `semExpr`.
|
|
||||||
result = newNodeI(nkDotCall, n.info)
|
|
||||||
addSon(result, newIdentNode(i, n[1].info))
|
|
||||||
addSon(result, copyTree(n[0]))
|
|
||||||
else:
|
|
||||||
if not ContainsOrIncl(c.UnknownIdents, i.id):
|
|
||||||
LocalError(n.Info, errUndeclaredFieldX, i.s)
|
|
||||||
result = errorNode(c, n)
|
|
||||||
|
|
||||||
proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
|
proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
|
||||||
result = newNodeI(nkCall, n.info)
|
result = newNodeI(nkCall, n.info)
|
||||||
|
|
@ -1030,14 +1034,12 @@ proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
||||||
let aOrig = nOrig[0]
|
let aOrig = nOrig[0]
|
||||||
result = newNode(nkCall, n.info, sons = @[setterId, a[0], semExpr(c, n[1])])
|
result = newNode(nkCall, n.info, sons = @[setterId, a[0], semExpr(c, n[1])])
|
||||||
let orig = newNode(nkCall, n.info, sons = @[setterId, aOrig[0], nOrig[1]])
|
let orig = newNode(nkCall, n.info, sons = @[setterId, aOrig[0], nOrig[1]])
|
||||||
result = semDirectCallAnalyseEffects(c, result, orig, {})
|
result = semOverloadedCallAnalyseEffects(c, result, orig, {})
|
||||||
|
|
||||||
if result != nil:
|
if result != nil:
|
||||||
fixAbstractType(c, result)
|
result = afterCallActions(c, result, nOrig, {})
|
||||||
analyseIfAddressTakenInCall(c, result)
|
#fixAbstractType(c, result)
|
||||||
else:
|
#analyseIfAddressTakenInCall(c, result)
|
||||||
if not ContainsOrIncl(c.UnknownIdents, id.id):
|
|
||||||
LocalError(n.Info, errUndeclaredFieldX, id.s)
|
|
||||||
result = errorNode(c, n)
|
|
||||||
|
|
||||||
proc takeImplicitAddr(c: PContext, n: PNode): PNode =
|
proc takeImplicitAddr(c: PContext, n: PNode): PNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -1072,7 +1074,14 @@ proc semAsgn(c: PContext, n: PNode): PNode =
|
||||||
let nOrig = n.copyTree
|
let nOrig = n.copyTree
|
||||||
a = builtinFieldAccess(c, a, {efLValue})
|
a = builtinFieldAccess(c, a, {efLValue})
|
||||||
if a == nil:
|
if a == nil:
|
||||||
return propertyWriteAccess(c, n, nOrig, n[0])
|
a = propertyWriteAccess(c, n, nOrig, n[0])
|
||||||
|
if a != nil: return a
|
||||||
|
# we try without the '='; proc that return 'var' or macros are still
|
||||||
|
# possible:
|
||||||
|
a = dotTransformation(c, n[0])
|
||||||
|
if a.kind == nkDotCall:
|
||||||
|
a.kind = nkCall
|
||||||
|
a = semExprWithType(c, a, {efLValue})
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
# a[i] = x
|
# a[i] = x
|
||||||
# --> `[]=`(a, i, x)
|
# --> `[]=`(a, i, x)
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ proc normalize*(s: string): string {.noSideEffect, procvar,
|
||||||
if j != s.len: setLen(result, j)
|
if j != s.len: setLen(result, j)
|
||||||
|
|
||||||
proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,
|
proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,
|
||||||
rtl, extern: "nsuCmpIgnoreCase", procvar.} =
|
rtl, extern: "nsuCmpIgnoreCase", procvar, operator: 4.} =
|
||||||
## Compares two strings in a case insensitive manner. Returns:
|
## Compares two strings in a case insensitive manner. Returns:
|
||||||
##
|
##
|
||||||
## | 0 iff a == b
|
## | 0 iff a == b
|
||||||
|
|
@ -119,7 +119,7 @@ proc cmpIgnoreCase*(a, b: string): int {.noSideEffect,
|
||||||
# thus we compile without checks here
|
# thus we compile without checks here
|
||||||
|
|
||||||
proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
|
proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
|
||||||
rtl, extern: "nsuCmpIgnoreStyle", procvar.} =
|
rtl, extern: "nsuCmpIgnoreStyle", procvar, operator: 3.} =
|
||||||
## Compares two strings normalized (i.e. case and
|
## Compares two strings normalized (i.e. case and
|
||||||
## underscores do not matter). Returns:
|
## underscores do not matter). Returns:
|
||||||
##
|
##
|
||||||
|
|
@ -141,7 +141,7 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
|
proc strip*(s: string, leading = true, trailing = true): string {.noSideEffect,
|
||||||
rtl, extern: "nsuStrip".} =
|
rtl, extern: "nsuStrip", operator: 5.} =
|
||||||
## Strips whitespace from `s` and returns the resulting string.
|
## Strips whitespace from `s` and returns the resulting string.
|
||||||
## If `leading` is true, leading whitespace is stripped.
|
## If `leading` is true, leading whitespace is stripped.
|
||||||
## If `trailing` is true, trailing whitespace is stripped.
|
## If `trailing` is true, trailing whitespace is stripped.
|
||||||
|
|
@ -665,7 +665,7 @@ proc findAux(s, sub: string, start: int, a: TSkipTable): int =
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc find*(s, sub: string, start: int = 0): int {.noSideEffect,
|
proc find*(s, sub: string, start: int = 0): int {.noSideEffect,
|
||||||
rtl, extern: "nsuFindStr".} =
|
rtl, extern: "nsuFindStr", operator: 6.} =
|
||||||
## Searches for `sub` in `s` starting at position `start`. Searching is
|
## Searches for `sub` in `s` starting at position `start`. Searching is
|
||||||
## case-sensitive. If `sub` is not in `s`, -1 is returned.
|
## case-sensitive. If `sub` is not in `s`, -1 is returned.
|
||||||
var a {.noinit.}: TSkipTable
|
var a {.noinit.}: TSkipTable
|
||||||
|
|
@ -723,7 +723,7 @@ proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} =
|
||||||
return find(s, chars) >= 0
|
return find(s, chars) >= 0
|
||||||
|
|
||||||
proc replace*(s, sub: string, by = ""): string {.noSideEffect,
|
proc replace*(s, sub: string, by = ""): string {.noSideEffect,
|
||||||
rtl, extern: "nsuReplaceStr".} =
|
rtl, extern: "nsuReplaceStr", operator: 1.} =
|
||||||
## Replaces `sub` in `s` by the string `by`.
|
## Replaces `sub` in `s` by the string `by`.
|
||||||
var a {.noinit.}: TSkipTable
|
var a {.noinit.}: TSkipTable
|
||||||
result = ""
|
result = ""
|
||||||
|
|
@ -1023,7 +1023,7 @@ type
|
||||||
ffScientific ## use scientific notation (using ``e`` character)
|
ffScientific ## use scientific notation (using ``e`` character)
|
||||||
|
|
||||||
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
||||||
precision = 16): string {.noSideEffect,
|
precision = 16): string {.noSideEffect, operator: 2,
|
||||||
rtl, extern: "nsu$1".} =
|
rtl, extern: "nsu$1".} =
|
||||||
## converts a floating point value `f` to a string.
|
## converts a floating point value `f` to a string.
|
||||||
##
|
##
|
||||||
|
|
@ -1054,7 +1054,7 @@ proc formatBiggestFloat*(f: BiggestFloat, format: TFloatFormat = ffDefault,
|
||||||
result = $buf
|
result = $buf
|
||||||
|
|
||||||
proc formatFloat*(f: float, format: TFloatFormat = ffDefault,
|
proc formatFloat*(f: float, format: TFloatFormat = ffDefault,
|
||||||
precision = 16): string {.noSideEffect,
|
precision = 16): string {.noSideEffect, operator: 2,
|
||||||
rtl, extern: "nsu$1".} =
|
rtl, extern: "nsu$1".} =
|
||||||
## converts a floating point value `f` to a string.
|
## converts a floating point value `f` to a string.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -42,3 +42,5 @@ else:
|
||||||
{.pragma: inl, inline.}
|
{.pragma: inl, inline.}
|
||||||
{.pragma: compilerRtl, compilerproc.}
|
{.pragma: compilerRtl, compilerproc.}
|
||||||
|
|
||||||
|
when not defined(nimsuperops):
|
||||||
|
{.pragma: operator.}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue