new VM is getting stable
This commit is contained in:
parent
6ea538cec3
commit
b4e25a6372
8 changed files with 206 additions and 124 deletions
|
|
@ -216,7 +216,7 @@ proc makeYamlString*(s: string): PRope =
|
||||||
const MaxLineLength = 64
|
const MaxLineLength = 64
|
||||||
result = nil
|
result = nil
|
||||||
var res = "\""
|
var res = "\""
|
||||||
for i in countup(0, len(s) - 1):
|
for i in countup(0, if s.isNil: -1 else: (len(s)-1)):
|
||||||
if (i + 1) mod MaxLineLength == 0:
|
if (i + 1) mod MaxLineLength == 0:
|
||||||
add(res, '\"')
|
add(res, '\"')
|
||||||
add(res, "\n")
|
add(res, "\n")
|
||||||
|
|
|
||||||
252
compiler/vm.nim
252
compiler/vm.nim
|
|
@ -68,6 +68,19 @@ proc myreset(n: PNode) =
|
||||||
reset(n[])
|
reset(n[])
|
||||||
n.info = oldInfo
|
n.info = oldInfo
|
||||||
|
|
||||||
|
proc skipMeta(n: PNode): PNode = (if n.kind != nkMetaNode: n else: n.sons[0])
|
||||||
|
|
||||||
|
proc setMeta(n, child: PNode) =
|
||||||
|
assert n.kind == nkMetaNode
|
||||||
|
let child = child.skipMeta
|
||||||
|
if n.sons.isNil: n.sons = @[child]
|
||||||
|
else: n.sons[0] = child
|
||||||
|
|
||||||
|
proc uast(n: PNode): PNode {.inline.} =
|
||||||
|
# "underlying ast"
|
||||||
|
assert n.kind == nkMetaNode
|
||||||
|
n.sons[0]
|
||||||
|
|
||||||
template ensureKind(k: expr) {.immediate, dirty.} =
|
template ensureKind(k: expr) {.immediate, dirty.} =
|
||||||
if regs[ra].kind != k:
|
if regs[ra].kind != k:
|
||||||
myreset(regs[ra])
|
myreset(regs[ra])
|
||||||
|
|
@ -98,26 +111,30 @@ template decodeBx(k: expr) {.immediate, dirty.} =
|
||||||
template move(a, b: expr) = system.shallowCopy(a, b)
|
template move(a, b: expr) = system.shallowCopy(a, b)
|
||||||
# XXX fix minor 'shallowCopy' overloading bug in compiler
|
# XXX fix minor 'shallowCopy' overloading bug in compiler
|
||||||
|
|
||||||
when false:
|
proc moveConst(x, y: PNode) =
|
||||||
proc asgnRef(x, y: PNode) =
|
if x.kind != y.kind:
|
||||||
myreset(x)
|
myreset(x)
|
||||||
x.kind = y.kind
|
x.kind = y.kind
|
||||||
x.typ = y.typ
|
x.typ = y.typ
|
||||||
case x.kind
|
case x.kind
|
||||||
of nkCharLit..nkInt64Lit: x.intVal = y.intVal
|
of nkCharLit..nkInt64Lit: x.intVal = y.intVal
|
||||||
of nkFloatLit..nkFloat64Lit: x.floatVal = y.floatVal
|
of nkFloatLit..nkFloat64Lit: x.floatVal = y.floatVal
|
||||||
of nkStrLit..nkTripleStrLit: x.strVal = y.strVal
|
of nkStrLit..nkTripleStrLit: move(x.strVal, y.strVal)
|
||||||
of nkIdent: x.ident = y.ident
|
of nkIdent: x.ident = y.ident
|
||||||
of nkSym: x.sym = y.sym
|
of nkSym: x.sym = y.sym
|
||||||
|
of nkMetaNode:
|
||||||
|
if x.sons.isNil: x.sons = @[y.sons[0]]
|
||||||
|
else: x.sons[0] = y.sons[0]
|
||||||
else:
|
else:
|
||||||
if x.kind notin {nkEmpty..nkNilLit}:
|
if x.kind notin {nkEmpty..nkNilLit}:
|
||||||
move(x.sons, y.sons)
|
move(x.sons, y.sons)
|
||||||
else:
|
|
||||||
# this seems to be the best way to model the reference semantics
|
# this seems to be the best way to model the reference semantics
|
||||||
# of PNimrodNode:
|
# of PNimrodNode:
|
||||||
template asgnRef(x, y: expr) = x = y
|
template asgnRef(x, y: expr) = moveConst(x, y)
|
||||||
|
|
||||||
proc asgnComplex(x, y: PNode) =
|
proc asgnComplex(x, y: PNode) =
|
||||||
|
if x.kind != y.kind:
|
||||||
myreset(x)
|
myreset(x)
|
||||||
x.kind = y.kind
|
x.kind = y.kind
|
||||||
x.typ = y.typ
|
x.typ = y.typ
|
||||||
|
|
@ -127,6 +144,9 @@ proc asgnComplex(x, y: PNode) =
|
||||||
of nkStrLit..nkTripleStrLit: x.strVal = y.strVal
|
of nkStrLit..nkTripleStrLit: x.strVal = y.strVal
|
||||||
of nkIdent: x.ident = y.ident
|
of nkIdent: x.ident = y.ident
|
||||||
of nkSym: x.sym = y.sym
|
of nkSym: x.sym = y.sym
|
||||||
|
of nkMetaNode:
|
||||||
|
if x.sons.isNil: x.sons = @[y.sons[0]]
|
||||||
|
else: x.sons[0] = y.sons[0]
|
||||||
else:
|
else:
|
||||||
if x.kind notin {nkEmpty..nkNilLit}:
|
if x.kind notin {nkEmpty..nkNilLit}:
|
||||||
let y = y.copyTree
|
let y = y.copyTree
|
||||||
|
|
@ -286,16 +306,17 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
of opcAsgnRef:
|
of opcAsgnRef:
|
||||||
asgnRef(regs[ra], regs[instr.regB])
|
asgnRef(regs[ra], regs[instr.regB])
|
||||||
of opcWrGlobalRef:
|
of opcWrGlobalRef:
|
||||||
asgnRef(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
|
asgnRef(c.globals.sons[instr.regBx-wordExcess-1], regs[ra].skipMeta)
|
||||||
of opcWrGlobal:
|
of opcWrGlobal:
|
||||||
asgnComplex(c.globals.sons[instr.regBx-wordExcess-1], regs[ra])
|
asgnComplex(c.globals.sons[instr.regBx-wordExcess-1], regs[ra].skipMeta)
|
||||||
of opcLdArr:
|
of opcLdArr:
|
||||||
# a = b[c]
|
# a = b[c]
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
let idx = regs[rc].intVal
|
let idx = regs[rc].intVal
|
||||||
# XXX what if the array is not 0-based? -> codegen should insert a sub
|
# XXX what if the array is not 0-based? -> codegen should insert a sub
|
||||||
regs[ra] = regs[rb].sons[idx.int]
|
assert regs[rb].kind != nkMetaNode
|
||||||
|
asgnComplex(regs[ra], regs[rb].sons[idx.int])
|
||||||
of opcLdStrIdx:
|
of opcLdStrIdx:
|
||||||
decodeBC(nkIntLit)
|
decodeBC(nkIntLit)
|
||||||
let idx = regs[rc].intVal
|
let idx = regs[rc].intVal
|
||||||
|
|
@ -305,12 +326,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
let idx = regs[rb].intVal
|
let idx = regs[rb].intVal
|
||||||
asgnComplex(regs[ra].sons[idx.int], regs[rc])
|
asgnComplex(regs[ra].sons[idx.int], regs[rc].skipMeta)
|
||||||
of opcWrArrRef:
|
of opcWrArrRef:
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
let idx = regs[rb].intVal
|
let idx = regs[rb].intVal
|
||||||
asgnRef(regs[ra].sons[idx.int], regs[rc])
|
asgnRef(regs[ra].sons[idx.int], regs[rc].skipMeta)
|
||||||
of opcLdObj:
|
of opcLdObj:
|
||||||
# a = b.c
|
# a = b.c
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
|
|
@ -322,11 +343,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
# a.b = c
|
# a.b = c
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
asgnComplex(regs[ra].sons[rb], regs[rc])
|
asgnComplex(regs[ra].sons[rb], regs[rc].skipMeta)
|
||||||
of opcWrObjRef:
|
of opcWrObjRef:
|
||||||
let rb = instr.regB
|
let rb = instr.regB
|
||||||
let rc = instr.regC
|
let rc = instr.regC
|
||||||
asgnRef(regs[ra].sons[rb], regs[rc])
|
asgnRef(regs[ra].sons[rb], regs[rc].skipMeta)
|
||||||
of opcWrStrIdx:
|
of opcWrStrIdx:
|
||||||
decodeBC(nkStrLit)
|
decodeBC(nkStrLit)
|
||||||
let idx = regs[rb].intVal.int
|
let idx = regs[rb].intVal.int
|
||||||
|
|
@ -341,6 +362,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
if regs[rb].kind == nkNilLit:
|
if regs[rb].kind == nkNilLit:
|
||||||
stackTrace(c, tos, pc, errNilAccess)
|
stackTrace(c, tos, pc, errNilAccess)
|
||||||
assert regs[rb].kind == nkRefTy
|
assert regs[rb].kind == nkRefTy
|
||||||
|
# XXX this is not correct
|
||||||
regs[ra] = regs[rb].sons[0]
|
regs[ra] = regs[rb].sons[0]
|
||||||
of opcAddInt:
|
of opcAddInt:
|
||||||
decodeBC(nkIntLit)
|
decodeBC(nkIntLit)
|
||||||
|
|
@ -357,8 +379,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
of opcLenSeq:
|
of opcLenSeq:
|
||||||
decodeBImm(nkIntLit)
|
decodeBImm(nkIntLit)
|
||||||
#assert regs[rb].kind == nkBracket
|
#assert regs[rb].kind == nkBracket
|
||||||
# also used by mNLen
|
# also used by mNLen:
|
||||||
regs[ra].intVal = regs[rb].len - imm
|
regs[ra].intVal = regs[rb].skipMeta.len - imm
|
||||||
of opcLenStr:
|
of opcLenStr:
|
||||||
decodeBImm(nkIntLit)
|
decodeBImm(nkIntLit)
|
||||||
assert regs[rb].kind == nkStrLit
|
assert regs[rb].kind == nkStrLit
|
||||||
|
|
@ -366,6 +388,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
of opcIncl:
|
of opcIncl:
|
||||||
decodeB(nkCurly)
|
decodeB(nkCurly)
|
||||||
if not inSet(regs[ra], regs[rb]): addSon(regs[ra], copyTree(regs[rb]))
|
if not inSet(regs[ra], regs[rb]): addSon(regs[ra], copyTree(regs[rb]))
|
||||||
|
of opcInclRange:
|
||||||
|
decodeBC(nkCurly)
|
||||||
|
var r = newNode(nkRange)
|
||||||
|
r.add regs[rb]
|
||||||
|
r.add regs[rc]
|
||||||
|
addSon(regs[ra], r.copyTree)
|
||||||
of opcExcl:
|
of opcExcl:
|
||||||
decodeB(nkCurly)
|
decodeB(nkCurly)
|
||||||
var b = newNodeIT(nkCurly, regs[rb].info, regs[rb].typ)
|
var b = newNodeIT(nkCurly, regs[rb].info, regs[rb].typ)
|
||||||
|
|
@ -456,6 +484,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
regs[ra].intVal = ord((regs[rb].kind == nkNilLit and
|
regs[ra].intVal = ord((regs[rb].kind == nkNilLit and
|
||||||
regs[rc].kind == nkNilLit) or
|
regs[rc].kind == nkNilLit) or
|
||||||
regs[rb].sons == regs[rc].sons)
|
regs[rb].sons == regs[rc].sons)
|
||||||
|
of opcEqNimrodNode:
|
||||||
|
decodeBC(nkIntLit)
|
||||||
|
regs[ra].intVal = ord(regs[rb].uast == regs[rc].uast)
|
||||||
of opcXor:
|
of opcXor:
|
||||||
decodeBC(nkIntLit)
|
decodeBC(nkIntLit)
|
||||||
regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
|
regs[ra].intVal = ord(regs[rb].intVal != regs[rc].intVal)
|
||||||
|
|
@ -529,7 +560,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
writeln(stdout, "")
|
writeln(stdout, "")
|
||||||
of opcContainsSet:
|
of opcContainsSet:
|
||||||
decodeBC(nkIntLit)
|
decodeBC(nkIntLit)
|
||||||
regs[ra].intVal = Ord(inSet(regs[rb], regs[rc]))
|
regs[ra].intVal = ord(inSet(regs[rb], regs[rc]))
|
||||||
of opcSubStr:
|
of opcSubStr:
|
||||||
decodeBC(nkStrLit)
|
decodeBC(nkStrLit)
|
||||||
inc pc
|
inc pc
|
||||||
|
|
@ -581,18 +612,18 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
|
let rbx = instr.regBx - wordExcess - 1 # -1 for the following 'inc pc'
|
||||||
inc pc, rbx
|
inc pc, rbx
|
||||||
of opcBranch:
|
of opcBranch:
|
||||||
# we know the next instruction is a 'jmp':
|
# we know the next instruction is a 'fjmp':
|
||||||
let branch = c.constants[instr.regBx-wordExcess]
|
let branch = c.constants[instr.regBx-wordExcess]
|
||||||
var cond = false
|
var cond = false
|
||||||
for j in countup(0, sonsLen(branch) - 2):
|
for j in countup(0, sonsLen(branch) - 2):
|
||||||
if overlap(regs[ra], branch.sons[j]):
|
if overlap(regs[ra], branch.sons[j]):
|
||||||
cond = true
|
cond = true
|
||||||
break
|
break
|
||||||
assert c.code[pc+1].opcode == opcJmp
|
assert c.code[pc+1].opcode == opcFJmp
|
||||||
inc pc
|
inc pc
|
||||||
# we skip this instruction so that the final 'inc(pc)' skips
|
# we skip this instruction so that the final 'inc(pc)' skips
|
||||||
# the following jump
|
# the following jump
|
||||||
if cond:
|
if not cond:
|
||||||
let instr2 = c.code[pc]
|
let instr2 = c.code[pc]
|
||||||
let rbx = instr2.regBx - wordExcess - 1 # -1 for the following 'inc pc'
|
let rbx = instr2.regBx - wordExcess - 1 # -1 for the following 'inc pc'
|
||||||
inc pc, rbx
|
inc pc, rbx
|
||||||
|
|
@ -646,7 +677,11 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
let typ = c.types[instr.regBx - wordExcess]
|
let typ = c.types[instr.regBx - wordExcess]
|
||||||
regs[ra] = getNullValue(typ, c.debug[pc])
|
regs[ra] = getNullValue(typ, c.debug[pc])
|
||||||
of opcLdConst:
|
of opcLdConst:
|
||||||
regs[ra] = c.constants.sons[instr.regBx - wordExcess]
|
let rb = instr.regBx - wordExcess
|
||||||
|
if regs[ra].isNil:
|
||||||
|
regs[ra] = copyTree(c.constants.sons[rb])
|
||||||
|
else:
|
||||||
|
moveConst(regs[ra], c.constants.sons[rb])
|
||||||
of opcAsgnConst:
|
of opcAsgnConst:
|
||||||
let rb = instr.regBx - wordExcess
|
let rb = instr.regBx - wordExcess
|
||||||
if regs[ra].isNil:
|
if regs[ra].isNil:
|
||||||
|
|
@ -661,7 +696,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
asgnComplex(regs[ra], c.globals.sons[rb])
|
asgnComplex(regs[ra], c.globals.sons[rb])
|
||||||
of opcRepr:
|
of opcRepr:
|
||||||
decodeB(nkStrLit)
|
decodeB(nkStrLit)
|
||||||
regs[ra].strVal = renderTree(regs[rb], {renderNoComments})
|
regs[ra].strVal = renderTree(regs[rb].skipMeta, {renderNoComments})
|
||||||
of opcQuit:
|
of opcQuit:
|
||||||
if c.mode in {emRepl, emStatic}:
|
if c.mode in {emRepl, emStatic}:
|
||||||
Message(c.debug[pc], hintQuitCalled)
|
Message(c.debug[pc], hintQuitCalled)
|
||||||
|
|
@ -674,62 +709,71 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
of opcOf:
|
of opcOf:
|
||||||
decodeBC(nkIntLit)
|
decodeBC(nkIntLit)
|
||||||
regs[ra].intVal = ord(inheritanceDiff(regs[rb].typ, regs[rc].typ) >= 0)
|
regs[ra].intVal = ord(inheritanceDiff(regs[rb].typ, regs[rc].typ) >= 0)
|
||||||
of opcSetLenSeq,
|
of opcSetLenSeq:
|
||||||
opcSwap, opcIsNil,
|
decodeB(nkBracket)
|
||||||
opcCast, opcReset:
|
let newLen = regs[rb].getOrdValue.int
|
||||||
|
setLen(regs[ra].sons, newLen)
|
||||||
|
of opcSwap, opcCast, opcReset:
|
||||||
internalError(c.debug[pc], "too implement")
|
internalError(c.debug[pc], "too implement")
|
||||||
|
of opcIsNil:
|
||||||
|
decodeB(nkIntLit)
|
||||||
|
regs[ra].intVal = ord(regs[rb].skipMeta.kind == nkNilLit)
|
||||||
of opcNBindSym:
|
of opcNBindSym:
|
||||||
# trivial implementation:
|
# trivial implementation:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
regs[ra] = regs[rb].sons[1]
|
setMeta(regs[ra], regs[rb].skipMeta.sons[1])
|
||||||
of opcNChild:
|
of opcNChild:
|
||||||
let rb = instr.regB
|
decodeBC(nkMetaNode)
|
||||||
let rc = instr.regC
|
setMeta(regs[ra], regs[rb].uast.sons[regs[rc].intVal.int])
|
||||||
regs[ra] = regs[rb].sons[regs[rc].intVal.int]
|
|
||||||
of opcNSetChild:
|
of opcNSetChild:
|
||||||
let rb = instr.regB
|
decodeBC(nkMetaNode)
|
||||||
let rc = instr.regC
|
regs[ra].uast.sons[regs[rb].intVal.int] = regs[rc].uast
|
||||||
regs[ra].sons[regs[rb].intVal.int] = regs[rc]
|
|
||||||
of opcNAdd:
|
of opcNAdd:
|
||||||
declBC()
|
decodeBC(nkMetaNode)
|
||||||
regs[rb].add(regs[rc])
|
var u = regs[rb].uast
|
||||||
regs[ra] = regs[rb]
|
u.add(regs[rc].uast)
|
||||||
|
setMeta(regs[ra], u)
|
||||||
of opcNAddMultiple:
|
of opcNAddMultiple:
|
||||||
declBC()
|
decodeBC(nkMetaNode)
|
||||||
let x = regs[rc]
|
let x = regs[rc]
|
||||||
|
var u = regs[rb].uast
|
||||||
# XXX can be optimized:
|
# XXX can be optimized:
|
||||||
for i in 0.. <x.len: regs[rb].add(x.sons[i])
|
for i in 0.. <x.len: u.add(x.sons[i].skipMeta)
|
||||||
regs[ra] = regs[rb]
|
setMeta(regs[ra], u)
|
||||||
of opcNKind:
|
of opcNKind:
|
||||||
decodeB(nkIntLit)
|
decodeB(nkIntLit)
|
||||||
regs[ra].intVal = ord(regs[rb].kind)
|
regs[ra].intVal = ord(regs[rb].uast.kind)
|
||||||
of opcNIntVal:
|
of opcNIntVal:
|
||||||
decodeB(nkIntLit)
|
decodeB(nkIntLit)
|
||||||
let a = regs[rb]
|
let a = regs[rb].uast
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkInt64Lit: regs[ra].intVal = a.intVal
|
of nkCharLit..nkInt64Lit: regs[ra].intVal = a.intVal
|
||||||
else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
|
else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
|
||||||
of opcNFloatVal:
|
of opcNFloatVal:
|
||||||
decodeB(nkFloatLit)
|
decodeB(nkFloatLit)
|
||||||
let a = regs[rb]
|
let a = regs[rb].uast
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal
|
of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal
|
||||||
else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
|
else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
|
||||||
of opcNSymbol:
|
of opcNSymbol:
|
||||||
let rb = instr.regB
|
decodeB(nkSym)
|
||||||
if regs[rb].kind != nkSym:
|
let a = regs[rb].uast
|
||||||
|
if a.kind == nkSym:
|
||||||
|
regs[ra].sym = a.sym
|
||||||
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
|
stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
|
||||||
regs[ra] = regs[rb]
|
|
||||||
of opcNIdent:
|
of opcNIdent:
|
||||||
let rb = instr.regB
|
decodeB(nkIdent)
|
||||||
if regs[rb].kind != nkIdent:
|
let a = regs[rb].uast
|
||||||
|
if a.kind == nkIdent:
|
||||||
|
regs[ra].ident = a.ident
|
||||||
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "ident")
|
stackTrace(c, tos, pc, errFieldXNotFound, "ident")
|
||||||
regs[ra] = regs[rb]
|
|
||||||
of opcNGetType:
|
of opcNGetType:
|
||||||
InternalError(c.debug[pc], "unknown opcode " & $instr.opcode)
|
InternalError(c.debug[pc], "unknown opcode " & $instr.opcode)
|
||||||
of opcNStrVal:
|
of opcNStrVal:
|
||||||
decodeB(nkStrLit)
|
decodeB(nkStrLit)
|
||||||
let a = regs[rb]
|
let a = regs[rb].uast
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkStrLit..nkTripleStrLit: regs[ra].strVal = a.strVal
|
of nkStrLit..nkTripleStrLit: regs[ra].strVal = a.strVal
|
||||||
else: stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
|
else: stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
|
||||||
|
|
@ -746,25 +790,26 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
of opcNHint:
|
of opcNHint:
|
||||||
Message(c.debug[pc], hintUser, regs[ra].strVal)
|
Message(c.debug[pc], hintUser, regs[ra].strVal)
|
||||||
of opcParseExprToAst:
|
of opcParseExprToAst:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
# c.debug[pc].line.int - countLines(regs[rb].strVal) ?
|
# c.debug[pc].line.int - countLines(regs[rb].strVal) ?
|
||||||
let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename,
|
let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename,
|
||||||
c.debug[pc].line.int)
|
c.debug[pc].line.int)
|
||||||
if sonsLen(ast) != 1:
|
if sonsLen(ast) != 1:
|
||||||
GlobalError(c.debug[pc], errExprExpected, "multiple statements")
|
GlobalError(c.debug[pc], errExprExpected, "multiple statements")
|
||||||
regs[ra] = ast.sons[0]
|
setMeta(regs[ra], ast.sons[0])
|
||||||
of opcParseStmtToAst:
|
of opcParseStmtToAst:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename,
|
let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename,
|
||||||
c.debug[pc].line.int)
|
c.debug[pc].line.int)
|
||||||
regs[ra] = ast
|
setMeta(regs[ra], ast)
|
||||||
of opcCallSite:
|
of opcCallSite:
|
||||||
if c.callsite != nil: regs[ra] = c.callsite
|
ensureKind(nkMetaNode)
|
||||||
|
if c.callsite != nil: setMeta(regs[ra], c.callsite)
|
||||||
else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite")
|
else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite")
|
||||||
of opcNLineInfo:
|
of opcNLineInfo:
|
||||||
let rb = instr.regB
|
decodeB(nkStrLit)
|
||||||
let n = regs[rb]
|
let n = regs[rb]
|
||||||
regs[ra] = newStrNode(nkStrLit, n.info.toFileLineCol)
|
regs[ra].strVal = n.info.toFileLineCol
|
||||||
regs[ra].info = c.debug[pc]
|
regs[ra].info = c.debug[pc]
|
||||||
of opcEqIdent:
|
of opcEqIdent:
|
||||||
decodeBC(nkIntLit)
|
decodeBC(nkIntLit)
|
||||||
|
|
@ -773,16 +818,16 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
else:
|
else:
|
||||||
regs[ra].intVal = 0
|
regs[ra].intVal = 0
|
||||||
of opcStrToIdent:
|
of opcStrToIdent:
|
||||||
let rb = instr.regB
|
decodeB(nkIdent)
|
||||||
if regs[rb].kind notin {nkStrLit..nkTripleStrLit}:
|
if regs[rb].kind notin {nkStrLit..nkTripleStrLit}:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
|
stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
|
||||||
else:
|
else:
|
||||||
regs[ra] = newNodeI(nkIdent, c.debug[pc])
|
regs[ra].info = c.debug[pc]
|
||||||
regs[ra].ident = getIdent(regs[rb].strVal)
|
regs[ra].ident = getIdent(regs[rb].strVal)
|
||||||
of opcIdentToStr:
|
of opcIdentToStr:
|
||||||
let rb = instr.regB
|
decodeB(nkStrLit)
|
||||||
let a = regs[rb]
|
let a = regs[rb]
|
||||||
regs[ra] = newNodeI(nkStrLit, c.debug[pc])
|
regs[ra].info = c.debug[pc]
|
||||||
if a.kind == nkSym:
|
if a.kind == nkSym:
|
||||||
regs[ra].strVal = a.sym.name.s
|
regs[ra].strVal = a.sym.name.s
|
||||||
elif a.kind == nkIdent:
|
elif a.kind == nkIdent:
|
||||||
|
|
@ -800,71 +845,80 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
|
||||||
msgKindToString(errIllegalConvFromXtoY) % [
|
msgKindToString(errIllegalConvFromXtoY) % [
|
||||||
"unknown type" , "unknown type"])
|
"unknown type" , "unknown type"])
|
||||||
of opcNSetIntVal:
|
of opcNSetIntVal:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
if regs[ra].kind in {nkCharLit..nkInt64Lit} and
|
var dest = regs[ra].uast
|
||||||
|
if dest.kind in {nkCharLit..nkInt64Lit} and
|
||||||
regs[rb].kind in {nkCharLit..nkInt64Lit}:
|
regs[rb].kind in {nkCharLit..nkInt64Lit}:
|
||||||
regs[ra].intVal = regs[rb].intVal
|
dest.intVal = regs[rb].intVal
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
|
stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
|
||||||
of opcNSetFloatVal:
|
of opcNSetFloatVal:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
if regs[ra].kind in {nkFloatLit..nkFloat64Lit} and
|
var dest = regs[ra].uast
|
||||||
|
if dest.kind in {nkFloatLit..nkFloat64Lit} and
|
||||||
regs[rb].kind in {nkFloatLit..nkFloat64Lit}:
|
regs[rb].kind in {nkFloatLit..nkFloat64Lit}:
|
||||||
regs[ra].floatVal = regs[rb].floatVal
|
dest.floatVal = regs[rb].floatVal
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
|
stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
|
||||||
of opcNSetSymbol:
|
of opcNSetSymbol:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
if regs[ra].kind == nkSym and regs[rb].kind == nkSym:
|
var dest = regs[ra].uast
|
||||||
regs[ra].sym = regs[rb].sym
|
if dest.kind == nkSym and regs[rb].kind == nkSym:
|
||||||
|
dest.sym = regs[rb].sym
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
|
stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
|
||||||
of opcNSetIdent:
|
of opcNSetIdent:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
if regs[ra].kind == nkIdent and regs[rb].kind == nkIdent:
|
var dest = regs[ra].uast
|
||||||
regs[ra].ident = regs[rb].ident
|
if dest.kind == nkIdent and regs[rb].kind == nkIdent:
|
||||||
|
dest.ident = regs[rb].ident
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "ident")
|
stackTrace(c, tos, pc, errFieldXNotFound, "ident")
|
||||||
of opcNSetType:
|
of opcNSetType:
|
||||||
let b = regs[instr.regB]
|
decodeB(nkMetaNode)
|
||||||
|
let b = regs[rb].skipMeta
|
||||||
InternalAssert b.kind == nkSym and b.sym.kind == skType
|
InternalAssert b.kind == nkSym and b.sym.kind == skType
|
||||||
regs[ra].typ = b.sym.typ
|
regs[ra].uast.typ = b.sym.typ
|
||||||
of opcNSetStrVal:
|
of opcNSetStrVal:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
if regs[ra].kind in {nkStrLit..nkTripleStrLit} and
|
var dest = regs[ra].uast
|
||||||
|
if dest.kind in {nkStrLit..nkTripleStrLit} and
|
||||||
regs[rb].kind in {nkStrLit..nkTripleStrLit}:
|
regs[rb].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
regs[ra].strVal = regs[rb].strVal
|
dest.strVal = regs[rb].strVal
|
||||||
else:
|
else:
|
||||||
|
#c.echoCode
|
||||||
|
#debug regs[ra]
|
||||||
|
#debug regs[rb]
|
||||||
stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
|
stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
|
||||||
of opcNNewNimNode:
|
of opcNNewNimNode:
|
||||||
let rb = instr.regB
|
decodeBC(nkMetaNode)
|
||||||
let rc = instr.regC
|
|
||||||
var k = regs[rb].intVal
|
var k = regs[rb].intVal
|
||||||
if k < 0 or k > ord(high(TNodeKind)):
|
if k < 0 or k > ord(high(TNodeKind)):
|
||||||
internalError(c.debug[pc],
|
internalError(c.debug[pc],
|
||||||
"request to create a NimNode with invalid kind")
|
"request to create a NimNode of invalid kind")
|
||||||
regs[ra] = newNodeI(TNodeKind(int(k)),
|
let cc = regs[rc].skipMeta
|
||||||
if regs[rc].kind == nkNilLit: c.debug[pc] else: regs[rc].info)
|
setMeta(regs[ra], newNodeI(TNodeKind(int(k)),
|
||||||
|
if cc.kind == nkNilLit: c.debug[pc] else: cc.info))
|
||||||
of opcNCopyNimNode:
|
of opcNCopyNimNode:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
regs[ra] = copyNode(regs[rb])
|
setMeta(regs[ra], copyNode(regs[rb]))
|
||||||
of opcNCopyNimTree:
|
of opcNCopyNimTree:
|
||||||
let rb = instr.regB
|
decodeB(nkMetaNode)
|
||||||
regs[ra] = copyTree(regs[rb])
|
setMeta(regs[ra], copyTree(regs[rb]))
|
||||||
of opcNDel:
|
of opcNDel:
|
||||||
let rb = instr.regB
|
decodeBC(nkMetaNode)
|
||||||
let rc = instr.regC
|
let bb = regs[rb].intVal.int
|
||||||
for i in countup(0, regs[rc].intVal.int-1):
|
for i in countup(0, regs[rc].intVal.int-1):
|
||||||
delSon(regs[ra], regs[rb].intVal.int)
|
delSon(regs[ra].uast, bb)
|
||||||
of opcGenSym:
|
of opcGenSym:
|
||||||
let k = regs[instr.regB].intVal
|
decodeBC(nkMetaNode)
|
||||||
let b = regs[instr.regC]
|
let k = regs[rb].intVal
|
||||||
let name = if b.strVal.len == 0: ":tmp" else: b.strVal
|
let name = if regs[rc].strVal.len == 0: ":tmp" else: regs[rc].strVal
|
||||||
if k < 0 or k > ord(high(TSymKind)):
|
if k < 0 or k > ord(high(TSymKind)):
|
||||||
internalError(c.debug[pc], "request to create symbol of invalid kind")
|
internalError(c.debug[pc], "request to create symbol of invalid kind")
|
||||||
regs[ra] = newSymNode(newSym(k.TSymKind, name.getIdent, c.module,
|
var sym = newSym(k.TSymKind, name.getIdent, c.module, c.debug[pc])
|
||||||
c.debug[pc]))
|
incl(sym.flags, sfGenSym)
|
||||||
incl(regs[ra].sym.flags, sfGenSym)
|
setMeta(regs[ra], newSymNode(sym))
|
||||||
of opcTypeTrait:
|
of opcTypeTrait:
|
||||||
# XXX only supports 'name' for now; we can use regC to encode the
|
# XXX only supports 'name' for now; we can use regC to encode the
|
||||||
# type trait operation
|
# type trait operation
|
||||||
|
|
@ -894,6 +948,8 @@ proc evalExpr*(c: PCtx, n: PNode): PNode =
|
||||||
let start = genExpr(c, n)
|
let start = genExpr(c, n)
|
||||||
assert c.code[start].opcode != opcEof
|
assert c.code[start].opcode != opcEof
|
||||||
result = execute(c, start)
|
result = execute(c, start)
|
||||||
|
if not result.isNil:
|
||||||
|
result = result.skipMeta
|
||||||
fixType(result, n)
|
fixType(result, n)
|
||||||
|
|
||||||
# for now we share the 'globals' environment. XXX Coming soon: An API for
|
# for now we share the 'globals' environment. XXX Coming soon: An API for
|
||||||
|
|
@ -949,6 +1005,9 @@ proc evalStaticExpr*(module: PSym, e: PNode, prc: PSym): PNode =
|
||||||
proc setupMacroParam(x: PNode): PNode =
|
proc setupMacroParam(x: PNode): PNode =
|
||||||
result = x
|
result = x
|
||||||
if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1]
|
if result.kind in {nkHiddenSubConv, nkHiddenStdConv}: result = result.sons[1]
|
||||||
|
let y = result
|
||||||
|
result = newNode(nkMetaNode)
|
||||||
|
result.add y
|
||||||
|
|
||||||
var evalMacroCounter: int
|
var evalMacroCounter: int
|
||||||
|
|
||||||
|
|
@ -979,4 +1038,7 @@ proc evalMacroCall*(module: PSym, n, nOrig: PNode, sym: PSym): PNode =
|
||||||
result = rawExecute(c, start, tos)
|
result = rawExecute(c, start, tos)
|
||||||
if cyclicTree(result): GlobalError(n.info, errCyclicTree)
|
if cyclicTree(result): GlobalError(n.info, errCyclicTree)
|
||||||
dec(evalMacroCounter)
|
dec(evalMacroCounter)
|
||||||
|
if result != nil:
|
||||||
|
internalAssert result.kind == nkMetaNode
|
||||||
|
result = result.sons[0]
|
||||||
c.callsite = nil
|
c.callsite = nil
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,11 @@ type
|
||||||
opcLenSeq,
|
opcLenSeq,
|
||||||
opcLenStr,
|
opcLenStr,
|
||||||
|
|
||||||
opcIncl, 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, 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,
|
||||||
|
|
|
||||||
|
|
@ -277,9 +277,9 @@ proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) =
|
||||||
# asgn dest, b
|
# asgn dest, b
|
||||||
# L1:
|
# L1:
|
||||||
if dest < 0: dest = getTemp(c, n.typ)
|
if dest < 0: dest = getTemp(c, n.typ)
|
||||||
c.gen(n.sons[0], dest)
|
|
||||||
let L1 = c.xjmp(n, opc)
|
|
||||||
c.gen(n.sons[1], dest)
|
c.gen(n.sons[1], dest)
|
||||||
|
let L1 = c.xjmp(n, opc, dest)
|
||||||
|
c.gen(n.sons[2], dest)
|
||||||
c.patch(L1)
|
c.patch(L1)
|
||||||
|
|
||||||
proc rawGenLiteral(c: PCtx; n: PNode): int =
|
proc rawGenLiteral(c: PCtx; n: PNode): int =
|
||||||
|
|
@ -758,7 +758,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
of mStrToIdent: genUnaryABC(c, n, dest, opcStrToIdent)
|
of mStrToIdent: genUnaryABC(c, n, dest, opcStrToIdent)
|
||||||
of mIdentToStr: genUnaryABC(c, n, dest, opcIdentToStr)
|
of mIdentToStr: genUnaryABC(c, n, dest, opcIdentToStr)
|
||||||
of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent)
|
of mEqIdent: genBinaryABC(c, n, dest, opcEqIdent)
|
||||||
of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqRef)
|
of mEqNimrodNode: genBinaryABC(c, n, dest, opcEqNimrodNode)
|
||||||
of mNLineInfo: genUnaryABC(c, n, dest, opcNLineInfo)
|
of mNLineInfo: genUnaryABC(c, n, dest, opcNLineInfo)
|
||||||
of mNHint:
|
of mNHint:
|
||||||
unused(n, dest)
|
unused(n, dest)
|
||||||
|
|
@ -1040,6 +1040,13 @@ proc genSetConstr(c: PCtx, n: PNode, dest: var TDest) =
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
c.gABx(n, opcLdNull, dest, c.genType(n.typ))
|
c.gABx(n, opcLdNull, dest, c.genType(n.typ))
|
||||||
for x in n:
|
for x in n:
|
||||||
|
if x.kind == nkRange:
|
||||||
|
let a = c.genx(x.sons[0])
|
||||||
|
let b = c.genx(x.sons[1])
|
||||||
|
c.gABC(n, opcInclRange, dest, a, b)
|
||||||
|
c.freeTemp(b)
|
||||||
|
c.freeTemp(a)
|
||||||
|
else:
|
||||||
let a = c.genx(x)
|
let a = c.genx(x)
|
||||||
c.gABC(n, opcIncl, dest, a)
|
c.gABC(n, opcIncl, dest, a)
|
||||||
c.freeTemp(a)
|
c.freeTemp(a)
|
||||||
|
|
@ -1297,8 +1304,6 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||||
c.gABC(body, opcEof, eofInstr.regA)
|
c.gABC(body, opcEof, eofInstr.regA)
|
||||||
s.position = c.prc.maxSlots
|
s.position = c.prc.maxSlots
|
||||||
c.prc = oldPrc
|
c.prc = oldPrc
|
||||||
#if s.name.s == "xmlConstructor":
|
|
||||||
# echoCode(c)
|
|
||||||
else:
|
else:
|
||||||
c.prc.maxSlots = s.position
|
c.prc.maxSlots = s.position
|
||||||
result = x.intVal.int
|
result = x.intVal.int
|
||||||
|
|
|
||||||
9
koch.nim
9
koch.nim
|
|
@ -45,6 +45,7 @@ Possible Commands:
|
||||||
tests run the testsuite
|
tests run the testsuite
|
||||||
update updates nimrod to the latest version from github
|
update updates nimrod to the latest version from github
|
||||||
(compile koch with -d:withUpdate to enable)
|
(compile koch with -d:withUpdate to enable)
|
||||||
|
temp options creates a temporary compiler for testing
|
||||||
Boot options:
|
Boot options:
|
||||||
-d:release produce a release version of the compiler
|
-d:release produce a release version of the compiler
|
||||||
-d:tinyc include the Tiny C backend (not supported on Windows)
|
-d:tinyc include the Tiny C backend (not supported on Windows)
|
||||||
|
|
@ -268,6 +269,13 @@ proc tests(args: string) =
|
||||||
exec(getCurrentDir() / "tests/tester".exe & " run")
|
exec(getCurrentDir() / "tests/tester".exe & " run")
|
||||||
exec(getCurrentDir() / "tests/tester".exe & " merge")
|
exec(getCurrentDir() / "tests/tester".exe & " merge")
|
||||||
|
|
||||||
|
proc temp(args: string) =
|
||||||
|
var output = "compiler" / "nimrod".exe
|
||||||
|
var finalDest = "bin" / "nimrod".exe
|
||||||
|
exec("nimrod c compiler" / "nimrod")
|
||||||
|
copyExe(output, finalDest)
|
||||||
|
if args.len > 0: exec(finalDest & " " & args)
|
||||||
|
|
||||||
proc showHelp() =
|
proc showHelp() =
|
||||||
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)),
|
quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)),
|
||||||
CompileDate, CompileTime])
|
CompileDate, CompileTime])
|
||||||
|
|
@ -291,6 +299,7 @@ of cmdArgument:
|
||||||
update(op.cmdLineRest)
|
update(op.cmdLineRest)
|
||||||
else:
|
else:
|
||||||
quit "this Koch has not been compiled with -d:withUpdate"
|
quit "this Koch has not been compiled with -d:withUpdate"
|
||||||
|
of "temp": temp(op.cmdLineRest)
|
||||||
else: showHelp()
|
else: showHelp()
|
||||||
of cmdEnd: showHelp()
|
of cmdEnd: showHelp()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,13 @@ proc `intVal=`*(n: PNimrodNode, val: biggestInt) {.magic: "NSetIntVal".}
|
||||||
proc `floatVal=`*(n: PNimrodNode, val: biggestFloat) {.magic: "NSetFloatVal".}
|
proc `floatVal=`*(n: PNimrodNode, val: biggestFloat) {.magic: "NSetFloatVal".}
|
||||||
proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol".}
|
proc `symbol=`*(n: PNimrodNode, val: PNimrodSymbol) {.magic: "NSetSymbol".}
|
||||||
proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent".}
|
proc `ident=`*(n: PNimrodNode, val: TNimrodIdent) {.magic: "NSetIdent".}
|
||||||
proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
|
#proc `typ=`*(n: PNimrodNode, typ: typedesc) {.magic: "NSetType".}
|
||||||
|
# this is not sound! Unfortunately forbidding 'typ=' is not enough, as you
|
||||||
|
# can easily do:
|
||||||
|
# let bracket = semCheck([1, 2])
|
||||||
|
# let fake = semCheck(2.0)
|
||||||
|
# bracket[0] = fake # constructs a mixed array with ints and floats!
|
||||||
|
|
||||||
proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal".}
|
proc `strVal=`*(n: PNimrodNode, val: string) {.magic: "NSetStrVal".}
|
||||||
|
|
||||||
proc newNimNode*(kind: TNimrodNodeKind,
|
proc newNimNode*(kind: TNimrodNodeKind,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ proc normalize*(s: string): string {.noSideEffect, procvar,
|
||||||
var j = 0
|
var j = 0
|
||||||
for i in 0..len(s) - 1:
|
for i in 0..len(s) - 1:
|
||||||
if s[i] in {'A'..'Z'}:
|
if s[i] in {'A'..'Z'}:
|
||||||
result[j] = Chr(Ord(s[i]) + (Ord('a') - Ord('A')))
|
result[j] = chr(ord(s[i]) + (ord('a') - ord('A')))
|
||||||
inc j
|
inc j
|
||||||
elif s[i] != '_':
|
elif s[i] != '_':
|
||||||
result[j] = s[i]
|
result[j] = s[i]
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -2,8 +2,8 @@ version 0.9.4
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- new VM:
|
- new VM:
|
||||||
- get rid of nkIntLit..nkUInt64Lit,
|
compiling htmlgen (txmlgen) makes the compiler go into an infinite loop
|
||||||
nkFloatLit..nkFloat128Lit, nkStrLit..nkTripleStrLit?
|
tcntseq
|
||||||
- new VM requires lambda lifting
|
- new VM requires lambda lifting
|
||||||
- implement overflow checking
|
- implement overflow checking
|
||||||
- implement the FFI
|
- implement the FFI
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue