new VM: next steps
This commit is contained in:
parent
ec86d5db0f
commit
30bb68d48a
7 changed files with 72 additions and 28 deletions
|
|
@ -144,7 +144,8 @@ proc processSym(c: PPassContext, n: PNode): PNode =
|
||||||
cannotRename.incl(s.id)
|
cannotRename.incl(s.id)
|
||||||
return
|
return
|
||||||
let last = first+identLen(line, first)-1
|
let last = first+identLen(line, first)-1
|
||||||
if last-first+1 != newName.len or differ(line, first, last, newName):
|
if differ(line, first, last, newName):
|
||||||
|
# last-first+1 != newName.len or
|
||||||
var x = line.subStr(0, first-1) & newName & line.substr(last+1)
|
var x = line.subStr(0, first-1) & newName & line.substr(last+1)
|
||||||
when removeTP:
|
when removeTP:
|
||||||
# the WinAPI module is full of 'TX = X' which after the substitution
|
# the WinAPI module is full of 'TX = X' which after the substitution
|
||||||
|
|
|
||||||
|
|
@ -663,6 +663,10 @@ proc execute(c: PCtx, start: int) =
|
||||||
of opcCallSite:
|
of opcCallSite:
|
||||||
if c.callsite != nil: regs[ra] = c.callsite
|
if c.callsite != nil: regs[ra] = c.callsite
|
||||||
else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite")
|
else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite")
|
||||||
|
of opcNLineInfo:
|
||||||
|
let rb = instr.regB
|
||||||
|
let n = regs[rb]
|
||||||
|
regs[ra] = newStrNodeT(n.info.toFileLineCol, n)
|
||||||
else:
|
else:
|
||||||
InternalError(c.debug[pc], "unknown opcode " & $instr.opcode)
|
InternalError(c.debug[pc], "unknown opcode " & $instr.opcode)
|
||||||
inc pc
|
inc pc
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ type
|
||||||
opcNError,
|
opcNError,
|
||||||
opcNWarning,
|
opcNWarning,
|
||||||
opcNHint,
|
opcNHint,
|
||||||
|
opcNLineInfo,
|
||||||
|
|
||||||
opcEcho,
|
opcEcho,
|
||||||
opcIndCall, # dest = call regStart, n; where regStart = fn, arg1, ...
|
opcIndCall, # dest = call regStart, n; where regStart = fn, arg1, ...
|
||||||
|
|
|
||||||
|
|
@ -540,7 +540,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
of mLtF64: genBinaryABC(c, n, dest, opcLtFloat)
|
of mLtF64: genBinaryABC(c, n, dest, opcLtFloat)
|
||||||
of mLePtr, mLeU, mLeU64: genBinaryABC(c, n, dest, opcLeu)
|
of mLePtr, mLeU, mLeU64: genBinaryABC(c, n, dest, opcLeu)
|
||||||
of mLtPtr, mLtU, mLtU64: genBinaryABC(c, n, dest, opcLtu)
|
of mLtPtr, mLtU, mLtU64: genBinaryABC(c, n, dest, opcLtu)
|
||||||
of mEqProc, mEqRef, mEqUntracedRef: genBinaryABC(c, n, dest, opcEqRef)
|
of mEqProc, mEqRef, mEqUntracedRef, mEqCString:
|
||||||
|
genBinaryABC(c, n, dest, opcEqRef)
|
||||||
of mXor: genBinaryABC(c, n, dest, opcXor)
|
of mXor: genBinaryABC(c, n, dest, opcXor)
|
||||||
of mNot: genUnaryABC(c, n, dest, opcNot)
|
of mNot: genUnaryABC(c, n, dest, opcNot)
|
||||||
of mUnaryMinusI, mUnaryMinusI64: genUnaryABC(c, n, dest, opcUnaryMinusInt)
|
of mUnaryMinusI, mUnaryMinusI64: genUnaryABC(c, n, dest, opcUnaryMinusInt)
|
||||||
|
|
@ -645,7 +646,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
genUnaryABC(c, n, dest, opcParseExprToAst)
|
genUnaryABC(c, n, dest, opcParseExprToAst)
|
||||||
of mParseStmtToAst:
|
of mParseStmtToAst:
|
||||||
genUnaryABC(c, n, dest, opcParseStmtToAst)
|
genUnaryABC(c, n, dest, opcParseStmtToAst)
|
||||||
of mExpandToAst: InternalError(n.info, "cannot generate code for: " & $m)
|
of mExpandToAst:
|
||||||
|
InternalError(n.info, "cannot generate code for: " & $m)
|
||||||
of mTypeTrait: InternalError(n.info, "cannot generate code for: " & $m)
|
of mTypeTrait: InternalError(n.info, "cannot generate code for: " & $m)
|
||||||
of mIs: InternalError(n.info, "cannot generate code for: " & $m)
|
of mIs: InternalError(n.info, "cannot generate code for: " & $m)
|
||||||
of mSlurp: genUnaryABC(c, n, dest, opcSlurp)
|
of mSlurp: genUnaryABC(c, n, dest, opcSlurp)
|
||||||
|
|
@ -700,9 +702,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
of mNCallSite:
|
of mNCallSite:
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
c.gABC(n, opcCallSite, dest)
|
c.gABC(n, opcCallSite, dest)
|
||||||
|
of mMinI, mMaxI, mMinI64, mMaxI64, mAbsF64, mMinF64, mMaxF64, mAbsI, mAbsI64:
|
||||||
|
c.genCall(n, dest)
|
||||||
else:
|
else:
|
||||||
# XXX get rid of these: mMinI, mMaxI, mMinI64, mMaxI64, mMinF64, mMaxF64
|
# mGCref, mGCunref,
|
||||||
# mGCref, mGCunref, mEqCString, mAbsI, mAbsI64, mAbsF64
|
|
||||||
InternalError(n.info, "cannot generate code for: " & $m)
|
InternalError(n.info, "cannot generate code for: " & $m)
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ been renamed to fit this scheme. The ultimate goal is that the programmer can
|
||||||
------------------- ------------ --------------------------------------
|
------------------- ------------ --------------------------------------
|
||||||
English word To use Notes
|
English word To use Notes
|
||||||
------------------- ------------ --------------------------------------
|
------------------- ------------ --------------------------------------
|
||||||
|
initialize initT ``init`` is used to create a
|
||||||
|
value type ``T``
|
||||||
|
new newP ``new`` is used to create a
|
||||||
|
reference type ``P``
|
||||||
find find should return the position where
|
find find should return the position where
|
||||||
something was found; for a bool result
|
something was found; for a bool result
|
||||||
use ``contains``
|
use ``contains``
|
||||||
|
|
|
||||||
|
|
@ -581,15 +581,6 @@ proc `<` *(x, y: int32): bool {.magic: "LtI", noSideEffect.}
|
||||||
proc `<` *(x, y: int64): bool {.magic: "LtI64", noSideEffect.}
|
proc `<` *(x, y: int64): bool {.magic: "LtI64", noSideEffect.}
|
||||||
## Returns true iff `x` is less than `y`.
|
## Returns true iff `x` is less than `y`.
|
||||||
|
|
||||||
proc abs*(x: int): int {.magic: "AbsI", noSideEffect.}
|
|
||||||
proc abs*(x: int8): int8 {.magic: "AbsI", noSideEffect.}
|
|
||||||
proc abs*(x: int16): int16 {.magic: "AbsI", noSideEffect.}
|
|
||||||
proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.}
|
|
||||||
proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
|
|
||||||
## returns the absolute value of `x`. If `x` is ``low(x)`` (that
|
|
||||||
## is -MININT for its type), an overflow exception is thrown (if overflow
|
|
||||||
## checking is turned on).
|
|
||||||
|
|
||||||
type
|
type
|
||||||
IntMax32 = bool|int|int8|int16|int32
|
IntMax32 = bool|int|int8|int16|int32
|
||||||
|
|
||||||
|
|
@ -647,9 +638,6 @@ proc `/` *(x, y: float): float {.magic: "DivF64", noSideEffect.}
|
||||||
proc `==` *(x, y: float): bool {.magic: "EqF64", noSideEffect.}
|
proc `==` *(x, y: float): bool {.magic: "EqF64", noSideEffect.}
|
||||||
proc `<=` *(x, y: float): bool {.magic: "LeF64", noSideEffect.}
|
proc `<=` *(x, y: float): bool {.magic: "LeF64", noSideEffect.}
|
||||||
proc `<` *(x, y: float): bool {.magic: "LtF64", noSideEffect.}
|
proc `<` *(x, y: float): bool {.magic: "LtF64", noSideEffect.}
|
||||||
proc abs*(x: float): float {.magic: "AbsF64", noSideEffect.}
|
|
||||||
proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.}
|
|
||||||
proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.}
|
|
||||||
|
|
||||||
# set operators
|
# set operators
|
||||||
proc `*` *[T](x, y: set[T]): set[T] {.magic: "MulSet", noSideEffect.}
|
proc `*` *[T](x, y: set[T]): set[T] {.magic: "MulSet", noSideEffect.}
|
||||||
|
|
@ -1306,12 +1294,18 @@ iterator `||`*[S, T](a: S, b: T, annotation=""): T {.
|
||||||
## and GC.
|
## and GC.
|
||||||
nil
|
nil
|
||||||
|
|
||||||
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
|
{.push stackTrace:off.}
|
||||||
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.}
|
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} =
|
||||||
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.}
|
if x <= y: x else: y
|
||||||
proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.}
|
proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.} =
|
||||||
proc min*(x, y: int64): int64 {.magic: "MinI64", noSideEffect.}
|
if x <= y: x else: y
|
||||||
|
proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.} =
|
||||||
|
if x <= y: x else: y
|
||||||
|
proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} =
|
||||||
|
if x <= y: x else: y
|
||||||
|
proc min*(x, y: int64): int64 {.magic: "MinI64", noSideEffect.} =
|
||||||
## The minimum value of two integers.
|
## The minimum value of two integers.
|
||||||
|
if x <= y: x else: y
|
||||||
|
|
||||||
proc min*[T](x: varargs[T]): T =
|
proc min*[T](x: varargs[T]): T =
|
||||||
## The minimum value of `x`. ``T`` needs to have a ``<`` operator.
|
## The minimum value of `x`. ``T`` needs to have a ``<`` operator.
|
||||||
|
|
@ -1319,12 +1313,17 @@ proc min*[T](x: varargs[T]): T =
|
||||||
for i in 1..high(x):
|
for i in 1..high(x):
|
||||||
if x[i] < result: result = x[i]
|
if x[i] < result: result = x[i]
|
||||||
|
|
||||||
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.}
|
proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} =
|
||||||
proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.}
|
if y <= x: x else: y
|
||||||
proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.}
|
proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.} =
|
||||||
proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.}
|
if y <= x: x else: y
|
||||||
proc max*(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.}
|
proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.} =
|
||||||
|
if y <= x: x else: y
|
||||||
|
proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} =
|
||||||
|
if y <= x: x else: y
|
||||||
|
proc max*(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.} =
|
||||||
## The maximum value of two integers.
|
## The maximum value of two integers.
|
||||||
|
if y <= x: x else: y
|
||||||
|
|
||||||
proc max*[T](x: varargs[T]): T =
|
proc max*[T](x: varargs[T]): T =
|
||||||
## The maximum value of `x`. ``T`` needs to have a ``<`` operator.
|
## The maximum value of `x`. ``T`` needs to have a ``<`` operator.
|
||||||
|
|
@ -1332,6 +1331,14 @@ proc max*[T](x: varargs[T]): T =
|
||||||
for i in 1..high(x):
|
for i in 1..high(x):
|
||||||
if result < x[i]: result = x[i]
|
if result < x[i]: result = x[i]
|
||||||
|
|
||||||
|
proc abs*(x: float): float {.magic: "AbsF64", noSideEffect.} =
|
||||||
|
if x < 0.0: -x else: x
|
||||||
|
proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.} =
|
||||||
|
if x <= y: x else: y
|
||||||
|
proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} =
|
||||||
|
if y <= x: x else: y
|
||||||
|
{.pop.}
|
||||||
|
|
||||||
proc clamp*[T](x, a, b: T): T =
|
proc clamp*[T](x, a, b: T): T =
|
||||||
## limits the value ``x`` within the interval [a, b]
|
## limits the value ``x`` within the interval [a, b]
|
||||||
if x < a: return a
|
if x < a: return a
|
||||||
|
|
@ -1817,6 +1824,22 @@ proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo".}
|
||||||
## get type information for `x`. Ordinary code should not use this, but
|
## get type information for `x`. Ordinary code should not use this, but
|
||||||
## the `typeinfo` module instead.
|
## the `typeinfo` module instead.
|
||||||
|
|
||||||
|
{.push stackTrace: off.}
|
||||||
|
proc abs*(x: int): int {.magic: "AbsI", noSideEffect.} =
|
||||||
|
if x < 0: -x else: x
|
||||||
|
proc abs*(x: int8): int8 {.magic: "AbsI", noSideEffect.} =
|
||||||
|
if x < 0: -x else: x
|
||||||
|
proc abs*(x: int16): int16 {.magic: "AbsI", noSideEffect.} =
|
||||||
|
if x < 0: -x else: x
|
||||||
|
proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.} =
|
||||||
|
if x < 0: -x else: x
|
||||||
|
proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.} =
|
||||||
|
## returns the absolute value of `x`. If `x` is ``low(x)`` (that
|
||||||
|
## is -MININT for its type), an overflow exception is thrown (if overflow
|
||||||
|
## checking is turned on).
|
||||||
|
if x < 0: -x else: x
|
||||||
|
{.pop.}
|
||||||
|
|
||||||
when not defined(JS): #and not defined(NimrodVM):
|
when not defined(JS): #and not defined(NimrodVM):
|
||||||
{.push stack_trace: off, profiler:off.}
|
{.push stack_trace: off, profiler:off.}
|
||||||
|
|
||||||
|
|
@ -2390,7 +2413,7 @@ proc `[]=`*[T](s: var seq[T], x: TSlice[int], b: openArray[T]) =
|
||||||
for i in 0 .. <L: s[i+a] = b[i]
|
for i in 0 .. <L: s[i+a] = b[i]
|
||||||
else:
|
else:
|
||||||
spliceImpl(s, a, L, b)
|
spliceImpl(s, a, L, b)
|
||||||
|
|
||||||
proc slurp*(filename: string): string {.magic: "Slurp".}
|
proc slurp*(filename: string): string {.magic: "Slurp".}
|
||||||
## This is an alias for ``staticRead``.
|
## This is an alias for ``staticRead``.
|
||||||
|
|
||||||
|
|
|
||||||
8
todo.txt
8
todo.txt
|
|
@ -1,6 +1,14 @@
|
||||||
version 0.9.4
|
version 0.9.4
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
- new VM:
|
||||||
|
- implement opcConv
|
||||||
|
- implement missing magics
|
||||||
|
- implement constructors
|
||||||
|
- implement the glue to replace evals.nim
|
||||||
|
- implement on the fly CSE
|
||||||
|
- implement a jump optimizer
|
||||||
|
|
||||||
- make 'bind' default for templates and introduce 'mixin'
|
- make 'bind' default for templates and introduce 'mixin'
|
||||||
- special rule for ``[]=``
|
- special rule for ``[]=``
|
||||||
- ``=`` should be overloadable; requires specialization for ``=``; general
|
- ``=`` should be overloadable; requires specialization for ``=``; general
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue