summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-08-03 21:14:57 +0200
committerAraq <rumpf_a@web.de>2013-08-03 21:14:57 +0200
commit30bb68d48a90e45b83716ab81c9ecccdb425c781 (patch)
treeb9af06a619fdaa5b6d3e9f9cdfac9bbf04d661fa
parentec86d5db0f6a150db4db804876f2241451a07ffe (diff)
downloadNim-30bb68d48a90e45b83716ab81c9ecccdb425c781.tar.gz
new VM: next steps
-rw-r--r--compiler/pretty.nim3
-rw-r--r--compiler/vm.nim4
-rw-r--r--compiler/vmdef.nim1
-rw-r--r--compiler/vmgen.nim11
-rw-r--r--doc/apis.txt4
-rw-r--r--lib/system.nim69
-rw-r--r--todo.txt8
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