VM: minor fixes to make lexim work
This commit is contained in:
parent
dc3a0bc009
commit
7be092bba5
4 changed files with 75 additions and 67 deletions
|
|
@ -9,40 +9,40 @@
|
||||||
|
|
||||||
# tree helper routines
|
# tree helper routines
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, lexer, msgs, strutils, wordrecg
|
ast, astalgo, lexer, msgs, strutils, wordrecg
|
||||||
|
|
||||||
proc hasSon(father, son: PNode): bool =
|
proc hasSon(father, son: PNode): bool =
|
||||||
for i in countup(0, sonsLen(father) - 1):
|
for i in countup(0, sonsLen(father) - 1):
|
||||||
if father.sons[i] == son:
|
if father.sons[i] == son:
|
||||||
return true
|
return true
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc cyclicTreeAux(n, s: PNode): bool =
|
proc cyclicTreeAux(n, s: PNode): bool =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
return false
|
return false
|
||||||
if hasSon(s, n):
|
if hasSon(s, n):
|
||||||
return true
|
return true
|
||||||
var m = sonsLen(s)
|
var m = sonsLen(s)
|
||||||
addSon(s, n)
|
addSon(s, n)
|
||||||
if not (n.kind in {nkEmpty..nkNilLit}):
|
if not (n.kind in {nkEmpty..nkNilLit}):
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if cyclicTreeAux(n.sons[i], s):
|
if cyclicTreeAux(n.sons[i], s):
|
||||||
return true
|
return true
|
||||||
result = false
|
result = false
|
||||||
delSon(s, m)
|
delSon(s, m)
|
||||||
|
|
||||||
proc cyclicTree*(n: PNode): bool =
|
proc cyclicTree*(n: PNode): bool =
|
||||||
var s = newNodeI(nkEmpty, n.info)
|
var s = newNodeI(nkEmpty, n.info)
|
||||||
result = cyclicTreeAux(n, s)
|
result = cyclicTreeAux(n, s)
|
||||||
|
|
||||||
proc exprStructuralEquivalent*(a, b: PNode): bool =
|
proc exprStructuralEquivalent*(a, b: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
if a == b:
|
if a == b:
|
||||||
result = true
|
result = true
|
||||||
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
# don't go nuts here: same symbol as string is enough:
|
# don't go nuts here: same symbol as string is enough:
|
||||||
result = a.sym.name.id == b.sym.name.id
|
result = a.sym.name.id == b.sym.name.id
|
||||||
of nkIdent: result = a.ident.id == b.ident.id
|
of nkIdent: result = a.ident.id == b.ident.id
|
||||||
|
|
@ -50,12 +50,12 @@ proc exprStructuralEquivalent*(a, b: PNode): bool =
|
||||||
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||||
of nkEmpty, nkNilLit, nkType: result = true
|
of nkEmpty, nkNilLit, nkType: result = true
|
||||||
else:
|
else:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
for i in countup(0, sonsLen(a) - 1):
|
for i in countup(0, sonsLen(a) - 1):
|
||||||
if not exprStructuralEquivalent(a.sons[i], b.sons[i]): return
|
if not exprStructuralEquivalent(a.sons[i], b.sons[i]): return
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc sameTree*(a, b: PNode): bool =
|
proc sameTree*(a, b: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
if a == b:
|
if a == b:
|
||||||
|
|
@ -66,7 +66,7 @@ proc sameTree*(a, b: PNode): bool =
|
||||||
if a.info.col != b.info.col:
|
if a.info.col != b.info.col:
|
||||||
return #if a.info.fileIndex <> b.info.fileIndex then exit;
|
return #if a.info.fileIndex <> b.info.fileIndex then exit;
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
# don't go nuts here: same symbol as string is enough:
|
# don't go nuts here: same symbol as string is enough:
|
||||||
result = a.sym.name.id == b.sym.name.id
|
result = a.sym.name.id == b.sym.name.id
|
||||||
of nkIdent: result = a.ident.id == b.ident.id
|
of nkIdent: result = a.ident.id == b.ident.id
|
||||||
|
|
@ -75,15 +75,15 @@ proc sameTree*(a, b: PNode): bool =
|
||||||
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||||
of nkEmpty, nkNilLit, nkType: result = true
|
of nkEmpty, nkNilLit, nkType: result = true
|
||||||
else:
|
else:
|
||||||
if sonsLen(a) == sonsLen(b):
|
if sonsLen(a) == sonsLen(b):
|
||||||
for i in countup(0, sonsLen(a) - 1):
|
for i in countup(0, sonsLen(a) - 1):
|
||||||
if not sameTree(a.sons[i], b.sons[i]): return
|
if not sameTree(a.sons[i], b.sons[i]): return
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc getProcSym*(call: PNode): PSym =
|
proc getProcSym*(call: PNode): PSym =
|
||||||
result = call.sons[0].sym
|
result = call.sons[0].sym
|
||||||
|
|
||||||
proc getOpSym*(op: PNode): PSym =
|
proc getOpSym*(op: PNode): PSym =
|
||||||
if op.kind notin {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}:
|
if op.kind notin {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}:
|
||||||
result = nil
|
result = nil
|
||||||
else:
|
else:
|
||||||
|
|
@ -91,25 +91,25 @@ proc getOpSym*(op: PNode): PSym =
|
||||||
elif op.sons[0].kind == nkSym: result = op.sons[0].sym
|
elif op.sons[0].kind == nkSym: result = op.sons[0].sym
|
||||||
else: result = nil
|
else: result = nil
|
||||||
|
|
||||||
proc getMagic*(op: PNode): TMagic =
|
proc getMagic*(op: PNode): TMagic =
|
||||||
case op.kind
|
case op.kind
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
case op.sons[0].kind
|
case op.sons[0].kind
|
||||||
of nkSym: result = op.sons[0].sym.magic
|
of nkSym: result = op.sons[0].sym.magic
|
||||||
else: result = mNone
|
else: result = mNone
|
||||||
else: result = mNone
|
else: result = mNone
|
||||||
|
|
||||||
proc treeToSym*(t: PNode): PSym =
|
proc treeToSym*(t: PNode): PSym =
|
||||||
result = t.sym
|
result = t.sym
|
||||||
|
|
||||||
proc isConstExpr*(n: PNode): bool =
|
proc isConstExpr*(n: PNode): bool =
|
||||||
result = (n.kind in
|
result = (n.kind in
|
||||||
{nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
{nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||||
nkFloatLit..nkFloat64Lit, nkNilLit}) or (nfAllConst in n.flags)
|
nkFloatLit..nkFloat64Lit, nkNilLit}) or (nfAllConst in n.flags)
|
||||||
|
|
||||||
proc isDeepConstExpr*(n: PNode): bool =
|
proc isDeepConstExpr*(n: PNode): bool =
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
of nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||||
nkFloatLit..nkFloat64Lit, nkNilLit:
|
nkFloatLit..nkFloat64Lit, nkNilLit:
|
||||||
result = true
|
result = true
|
||||||
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
|
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
|
||||||
|
|
@ -122,33 +122,33 @@ proc isDeepConstExpr*(n: PNode): bool =
|
||||||
result = n.typ.isNil or n.typ.skipTypes({tyGenericInst, tyDistinct}).kind != tyObject
|
result = n.typ.isNil or n.typ.skipTypes({tyGenericInst, tyDistinct}).kind != tyObject
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc flattenTreeAux(d, a: PNode, op: TMagic) =
|
proc flattenTreeAux(d, a: PNode, op: TMagic) =
|
||||||
if (getMagic(a) == op): # a is a "leaf", so add it:
|
if (getMagic(a) == op): # a is a "leaf", so add it:
|
||||||
for i in countup(1, sonsLen(a) - 1): # BUGFIX
|
for i in countup(1, sonsLen(a) - 1): # BUGFIX
|
||||||
flattenTreeAux(d, a.sons[i], op)
|
flattenTreeAux(d, a.sons[i], op)
|
||||||
else:
|
else:
|
||||||
addSon(d, copyTree(a))
|
addSon(d, copyTree(a))
|
||||||
|
|
||||||
proc flattenTree*(root: PNode, op: TMagic): PNode =
|
proc flattenTree*(root: PNode, op: TMagic): PNode =
|
||||||
result = copyNode(root)
|
result = copyNode(root)
|
||||||
if getMagic(root) == op:
|
if getMagic(root) == op:
|
||||||
# BUGFIX: forget to copy prc
|
# BUGFIX: forget to copy prc
|
||||||
addSon(result, copyNode(root.sons[0]))
|
addSon(result, copyNode(root.sons[0]))
|
||||||
flattenTreeAux(result, root, op)
|
flattenTreeAux(result, root, op)
|
||||||
|
|
||||||
proc swapOperands*(op: PNode) =
|
proc swapOperands*(op: PNode) =
|
||||||
var tmp = op.sons[1]
|
var tmp = op.sons[1]
|
||||||
op.sons[1] = op.sons[2]
|
op.sons[1] = op.sons[2]
|
||||||
op.sons[2] = tmp
|
op.sons[2] = tmp
|
||||||
|
|
||||||
proc isRange*(n: PNode): bool {.inline.} =
|
proc isRange*(n: PNode): bool {.inline.} =
|
||||||
if n.kind == nkInfix:
|
if n.kind in nkCallKinds:
|
||||||
if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or
|
if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or
|
||||||
n[0].kind in {nkClosedSymChoice, nkOpenSymChoice} and
|
n[0].kind in {nkClosedSymChoice, nkOpenSymChoice} and
|
||||||
n[0][1].sym.name.id == ord(wDotDot):
|
n[0][1].sym.name.id == ord(wDotDot):
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc whichPragma*(n: PNode): TSpecialWord =
|
proc whichPragma*(n: PNode): TSpecialWord =
|
||||||
let key = if n.kind == nkExprColonExpr: n.sons[0] else: n
|
let key = if n.kind == nkExprColonExpr: n.sons[0] else: n
|
||||||
if key.kind == nkIdent: result = whichKeyword(key.ident)
|
if key.kind == nkIdent: result = whichKeyword(key.ident)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1043,7 +1043,14 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
let newLen = regs[rb].intVal.int
|
let newLen = regs[rb].intVal.int
|
||||||
if regs[ra].node.isNil: stackTrace(c, tos, pc, errNilAccess)
|
if regs[ra].node.isNil: stackTrace(c, tos, pc, errNilAccess)
|
||||||
else: setLen(regs[ra].node.sons, newLen)
|
else:
|
||||||
|
let oldLen = regs[ra].node.len
|
||||||
|
setLen(regs[ra].node.sons, newLen)
|
||||||
|
if oldLen < newLen:
|
||||||
|
# XXX This is still not entirely correct
|
||||||
|
# set to default value:
|
||||||
|
for i in oldLen .. <newLen:
|
||||||
|
regs[ra].node.sons[i] = newNodeI(nkEmpty, c.debug[pc])
|
||||||
of opcSwap:
|
of opcSwap:
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
if regs[ra].kind == regs[rb].kind:
|
if regs[ra].kind == regs[rb].kind:
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const
|
||||||
byteExcess* = 128 # we use excess-K for immediates
|
byteExcess* = 128 # we use excess-K for immediates
|
||||||
wordExcess* = 32768
|
wordExcess* = 32768
|
||||||
|
|
||||||
MaxLoopIterations* = 500_000 # max iterations of all loops
|
MaxLoopIterations* = 1500_000 # max iterations of all loops
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -29,7 +29,7 @@ type
|
||||||
opcRet, # return
|
opcRet, # return
|
||||||
opcYldYoid, # yield with no value
|
opcYldYoid, # yield with no value
|
||||||
opcYldVal, # yield with a value
|
opcYldVal, # yield with a value
|
||||||
|
|
||||||
opcAsgnInt,
|
opcAsgnInt,
|
||||||
opcAsgnStr,
|
opcAsgnStr,
|
||||||
opcAsgnFloat,
|
opcAsgnFloat,
|
||||||
|
|
@ -48,8 +48,8 @@ type
|
||||||
opcWrDeref,
|
opcWrDeref,
|
||||||
opcWrStrIdx,
|
opcWrStrIdx,
|
||||||
opcLdStrIdx, # a = b[c]
|
opcLdStrIdx, # a = b[c]
|
||||||
|
|
||||||
opcAddInt,
|
opcAddInt,
|
||||||
opcAddImmInt,
|
opcAddImmInt,
|
||||||
opcSubInt,
|
opcSubInt,
|
||||||
opcSubImmInt,
|
opcSubImmInt,
|
||||||
|
|
@ -58,36 +58,36 @@ type
|
||||||
|
|
||||||
opcIncl, opcInclRange, opcExcl, opcCard, opcMulInt, opcDivInt, opcModInt,
|
opcIncl, opcInclRange, opcExcl, opcCard, opcMulInt, opcDivInt, opcModInt,
|
||||||
opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt,
|
opcAddFloat, opcSubFloat, opcMulFloat, opcDivFloat, opcShrInt, opcShlInt,
|
||||||
opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu,
|
opcBitandInt, opcBitorInt, opcBitxorInt, opcAddu, opcSubu, opcMulu,
|
||||||
opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat,
|
opcDivu, opcModu, opcEqInt, opcLeInt, opcLtInt, opcEqFloat,
|
||||||
opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcEqNimrodNode, opcXor,
|
opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcEqNimrodNode, opcXor,
|
||||||
opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
|
opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt,
|
||||||
opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
|
opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
|
||||||
opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
|
opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
|
||||||
opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
|
opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
|
||||||
opcSwap, opcIsNil, opcOf, opcIs,
|
opcSwap, opcIsNil, opcOf, opcIs,
|
||||||
opcSubStr, opcParseFloat, opcConv, opcCast, opcQuit, opcReset,
|
opcSubStr, opcParseFloat, opcConv, opcCast, opcQuit, opcReset,
|
||||||
opcNarrowS, opcNarrowU,
|
opcNarrowS, opcNarrowU,
|
||||||
|
|
||||||
opcAddStrCh,
|
opcAddStrCh,
|
||||||
opcAddStrStr,
|
opcAddStrStr,
|
||||||
opcAddSeqElem,
|
opcAddSeqElem,
|
||||||
opcRangeChck,
|
opcRangeChck,
|
||||||
|
|
||||||
opcNAdd,
|
opcNAdd,
|
||||||
opcNAddMultiple,
|
opcNAddMultiple,
|
||||||
opcNKind,
|
opcNKind,
|
||||||
opcNIntVal,
|
opcNIntVal,
|
||||||
opcNFloatVal,
|
opcNFloatVal,
|
||||||
opcNSymbol,
|
opcNSymbol,
|
||||||
opcNIdent,
|
opcNIdent,
|
||||||
opcNGetType,
|
opcNGetType,
|
||||||
opcNStrVal,
|
opcNStrVal,
|
||||||
|
|
||||||
opcNSetIntVal,
|
opcNSetIntVal,
|
||||||
opcNSetFloatVal, opcNSetSymbol, opcNSetIdent, opcNSetType, opcNSetStrVal,
|
opcNSetFloatVal, opcNSetSymbol, opcNSetIdent, opcNSetType, opcNSetStrVal,
|
||||||
opcNNewNimNode, opcNCopyNimNode, opcNCopyNimTree, opcNDel, opcGenSym,
|
opcNNewNimNode, opcNCopyNimNode, opcNCopyNimTree, opcNDel, opcGenSym,
|
||||||
|
|
||||||
opcSlurp,
|
opcSlurp,
|
||||||
opcGorge,
|
opcGorge,
|
||||||
opcParseExprToAst,
|
opcParseExprToAst,
|
||||||
|
|
@ -100,7 +100,7 @@ type
|
||||||
opcEqIdent,
|
opcEqIdent,
|
||||||
opcStrToIdent,
|
opcStrToIdent,
|
||||||
opcIdentToStr,
|
opcIdentToStr,
|
||||||
|
|
||||||
opcEcho,
|
opcEcho,
|
||||||
opcIndCall, # dest = call regStart, n; where regStart = fn, arg1, ...
|
opcIndCall, # dest = call regStart, n; where regStart = fn, arg1, ...
|
||||||
opcIndCallAsgn, # dest = call regStart, n; where regStart = fn, arg1, ...
|
opcIndCallAsgn, # dest = call regStart, n; where regStart = fn, arg1, ...
|
||||||
|
|
@ -110,7 +110,7 @@ type
|
||||||
opcNSetChild,
|
opcNSetChild,
|
||||||
opcCallSite,
|
opcCallSite,
|
||||||
opcNewStr,
|
opcNewStr,
|
||||||
|
|
||||||
opcTJmp, # jump Bx if A != 0
|
opcTJmp, # jump Bx if A != 0
|
||||||
opcFJmp, # jump Bx if A == 0
|
opcFJmp, # jump Bx if A == 0
|
||||||
opcJmp, # jump Bx
|
opcJmp, # jump Bx
|
||||||
|
|
@ -178,13 +178,13 @@ type
|
||||||
slots*: pointer
|
slots*: pointer
|
||||||
currentException*: PNode
|
currentException*: PNode
|
||||||
VmCallback* = proc (args: VmArgs) {.closure.}
|
VmCallback* = proc (args: VmArgs) {.closure.}
|
||||||
|
|
||||||
PCtx* = ref TCtx
|
PCtx* = ref TCtx
|
||||||
TCtx* = object of passes.TPassContext # code gen context
|
TCtx* = object of passes.TPassContext # code gen context
|
||||||
code*: seq[TInstr]
|
code*: seq[TInstr]
|
||||||
debug*: seq[TLineInfo] # line info for every instruction; kept separate
|
debug*: seq[TLineInfo] # line info for every instruction; kept separate
|
||||||
# to not slow down interpretation
|
# to not slow down interpretation
|
||||||
globals*: PNode #
|
globals*: PNode #
|
||||||
constants*: PNode # constant data
|
constants*: PNode # constant data
|
||||||
types*: seq[PType] # some instructions reference types (e.g. 'except')
|
types*: seq[PType] # some instructions reference types (e.g. 'except')
|
||||||
currentExceptionA*, currentExceptionB*: PNode
|
currentExceptionA*, currentExceptionB*: PNode
|
||||||
|
|
@ -203,7 +203,7 @@ type
|
||||||
TPosition* = distinct int
|
TPosition* = distinct int
|
||||||
|
|
||||||
PEvalContext* = PCtx
|
PEvalContext* = PCtx
|
||||||
|
|
||||||
proc newCtx*(module: PSym): PCtx =
|
proc newCtx*(module: PSym): PCtx =
|
||||||
PCtx(code: @[], debug: @[],
|
PCtx(code: @[], debug: @[],
|
||||||
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
||||||
|
|
|
||||||
|
|
@ -1364,7 +1364,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
of tyCString, tyString:
|
of tyCString, tyString:
|
||||||
result = newNodeIT(nkStrLit, info, t)
|
result = newNodeIT(nkStrLit, info, t)
|
||||||
of tyVar, tyPointer, tyPtr, tySequence, tyExpr,
|
of tyVar, tyPointer, tyPtr, tySequence, tyExpr,
|
||||||
tyStmt, tyTypeDesc, tyStatic, tyRef:
|
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
||||||
result = newNodeIT(nkNilLit, info, t)
|
result = newNodeIT(nkNilLit, info, t)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
if t.callConv != ccClosure:
|
if t.callConv != ccClosure:
|
||||||
|
|
@ -1391,7 +1391,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
addSon(result, getNullValue(t.sons[i], info))
|
addSon(result, getNullValue(t.sons[i], info))
|
||||||
of tySet:
|
of tySet:
|
||||||
result = newNodeIT(nkCurly, info, t)
|
result = newNodeIT(nkCurly, info, t)
|
||||||
else: internalError("getNullValue: " & $t.kind)
|
else: internalError(info, "getNullValue: " & $t.kind)
|
||||||
|
|
||||||
proc ldNullOpcode(t: PType): TOpcode =
|
proc ldNullOpcode(t: PType): TOpcode =
|
||||||
if fitsRegister(t): opcLdNullReg else: opcLdNull
|
if fitsRegister(t): opcLdNullReg else: opcLdNull
|
||||||
|
|
@ -1610,7 +1610,8 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||||
genBreak(c, n)
|
genBreak(c, n)
|
||||||
of nkTryStmt: genTry(c, n, dest)
|
of nkTryStmt: genTry(c, n, dest)
|
||||||
of nkStmtList:
|
of nkStmtList:
|
||||||
unused(n, dest)
|
#unused(n, dest)
|
||||||
|
# XXX Fix this bug properly, lexim triggers it
|
||||||
for x in n: gen(c, x)
|
for x in n: gen(c, x)
|
||||||
of nkStmtListExpr:
|
of nkStmtListExpr:
|
||||||
let L = n.len-1
|
let L = n.len-1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue