diff options
author | Araq <rumpf_a@web.de> | 2013-08-03 21:14:57 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-08-03 21:14:57 +0200 |
commit | 30bb68d48a90e45b83716ab81c9ecccdb425c781 (patch) | |
tree | b9af06a619fdaa5b6d3e9f9cdfac9bbf04d661fa | |
parent | ec86d5db0f6a150db4db804876f2241451a07ffe (diff) | |
download | Nim-30bb68d48a90e45b83716ab81c9ecccdb425c781.tar.gz |
new VM: next steps
-rw-r--r-- | compiler/pretty.nim | 3 | ||||
-rw-r--r-- | compiler/vm.nim | 4 | ||||
-rw-r--r-- | compiler/vmdef.nim | 1 | ||||
-rw-r--r-- | compiler/vmgen.nim | 11 | ||||
-rw-r--r-- | doc/apis.txt | 4 | ||||
-rw-r--r-- | lib/system.nim | 69 | ||||
-rw-r--r-- | todo.txt | 8 |
7 files changed, 72 insertions, 28 deletions
diff --git a/compiler/pretty.nim b/compiler/pretty.nim index d86675412..4545e1c55 100644 --- a/compiler/pretty.nim +++ b/compiler/pretty.nim @@ -144,7 +144,8 @@ proc processSym(c: PPassContext, n: PNode): PNode = cannotRename.incl(s.id) return 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) when removeTP: # the WinAPI module is full of 'TX = X' which after the substitution diff --git a/compiler/vm.nim b/compiler/vm.nim index 7b24c3d6c..7929774ee 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -663,6 +663,10 @@ proc execute(c: PCtx, start: int) = of opcCallSite: if c.callsite != nil: regs[ra] = c.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: InternalError(c.debug[pc], "unknown opcode " & $instr.opcode) inc pc diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index 449d632b1..1a19efe5a 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -85,6 +85,7 @@ type opcNError, opcNWarning, opcNHint, + opcNLineInfo, opcEcho, opcIndCall, # dest = call regStart, n; where regStart = fn, arg1, ... diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 427f8fafe..c5bfa3095 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -540,7 +540,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = of mLtF64: genBinaryABC(c, n, dest, opcLtFloat) of mLePtr, mLeU, mLeU64: genBinaryABC(c, n, dest, opcLeu) 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 mNot: genUnaryABC(c, n, dest, opcNot) 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) of mParseStmtToAst: 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 mIs: InternalError(n.info, "cannot generate code for: " & $m) of mSlurp: genUnaryABC(c, n, dest, opcSlurp) @@ -700,9 +702,10 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest) = of mNCallSite: if dest < 0: dest = c.getTemp(n.typ) c.gABC(n, opcCallSite, dest) + of mMinI, mMaxI, mMinI64, mMaxI64, mAbsF64, mMinF64, mMaxF64, mAbsI, mAbsI64: + c.genCall(n, dest) else: - # XXX get rid of these: mMinI, mMaxI, mMinI64, mMaxI64, mMinF64, mMaxF64 - # mGCref, mGCunref, mEqCString, mAbsI, mAbsI64, mAbsF64 + # mGCref, mGCunref, InternalError(n.info, "cannot generate code for: " & $m) const diff --git a/doc/apis.txt b/doc/apis.txt index 260ce159b..67534dec8 100644 --- a/doc/apis.txt +++ b/doc/apis.txt @@ -18,6 +18,10 @@ been renamed to fit this scheme. The ultimate goal is that the programmer can ------------------- ------------ -------------------------------------- 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 something was found; for a bool result use ``contains`` diff --git a/lib/system.nim b/lib/system.nim index 9c25f2923..08e4c367b 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -581,15 +581,6 @@ proc `<` *(x, y: int32): bool {.magic: "LtI", noSideEffect.} proc `<` *(x, y: int64): bool {.magic: "LtI64", noSideEffect.} ## 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 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: "LeF64", 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 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. nil -proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} -proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.} -proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.} -proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} -proc min*(x, y: int64): int64 {.magic: "MinI64", noSideEffect.} +{.push stackTrace:off.} +proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} = + if x <= y: x else: y +proc min*(x, y: int8): int8 {.magic: "MinI", 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. + if x <= y: x else: y proc min*[T](x: varargs[T]): T = ## 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): if x[i] < result: result = x[i] -proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} -proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.} -proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.} -proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} -proc max*(x, y: int64): int64 {.magic: "MaxI64", noSideEffect.} +proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} = + if y <= x: x else: y +proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.} = + if y <= x: x else: y +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. + if y <= x: x else: y proc max*[T](x: varargs[T]): T = ## 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): 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 = ## limits the value ``x`` within the interval [a, b] 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 ## 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): {.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] else: spliceImpl(s, a, L, b) - + proc slurp*(filename: string): string {.magic: "Slurp".} ## This is an alias for ``staticRead``. diff --git a/todo.txt b/todo.txt index f213567ec..5b6cca2bb 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,14 @@ 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' - special rule for ``[]=`` - ``=`` should be overloadable; requires specialization for ``=``; general |