summary refs log tree commit diff stats
path: root/compiler/vm.nim
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-07-29 01:21:32 +0200
committerAraq <rumpf_a@web.de>2013-07-29 01:21:32 +0200
commitef975d277a368ba9d9b85451bb0b054c87d5d782 (patch)
treeef0061c4e9b4e8a985b8a236dc4c64ed636d3c11 /compiler/vm.nim
parent27b7ecbbff073ad8df0a663960f69a87f10e1e35 (diff)
downloadNim-ef975d277a368ba9d9b85451bb0b054c87d5d782.tar.gz
new vm: further progress
Diffstat (limited to 'compiler/vm.nim')
-rw-r--r--compiler/vm.nim91
1 files changed, 88 insertions, 3 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 642bfd94c..7b24c3d6c 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -11,7 +11,8 @@
 ## An instruction is 1-2 int32s in memory, it is a register based VM.
 
 import
-  strutils, ast, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned
+  strutils, ast, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, unsigned,
+  parser, vmdeps
 
 from semfold import leValueConv
 
@@ -73,6 +74,10 @@ template decodeBC(k: expr) {.immediate, dirty.} =
   let rc = instr.regC
   ensureKind(k)
 
+template declBC() {.immediate, dirty.} =
+  let rb = instr.regB
+  let rc = instr.regC
+
 template decodeBImm(k: expr) {.immediate, dirty.} =
   let rb = instr.regB
   let imm = instr.regC - byteExcess
@@ -283,7 +288,8 @@ proc execute(c: PCtx, start: int) =
       regs[ra].intVal = regs[rb].intVal - imm
     of opcLenSeq:
       decodeBImm(nkIntLit)
-      assert regs[rb].kind == nkBracket
+      #assert regs[rb].kind == nkBracket
+      # also used by mNLen
       regs[ra].intVal = regs[rb].len - imm
     of opcLenStr:
       decodeBImm(nkIntLit)
@@ -578,6 +584,85 @@ proc execute(c: PCtx, start: int) =
       # trivial implementation:
       let rb = instr.regB
       regs[ra] = regs[rb].sons[1]
+    of opcNChild:
+      let rb = instr.regB
+      let rc = instr.regC
+      regs[ra] = regs[rb].sons[regs[rc].intVal.int]
+    of opcNSetChild:
+      let rb = instr.regB
+      let rc = instr.regC
+      regs[ra].sons[regs[rb].intVal.int] = regs[rc]
+    of opcNAdd:
+      declBC()
+      regs[rb].add(regs[rb])
+      regs[ra] = regs[rb]
+    of opcNAddMultiple:
+      declBC()
+      let x = regs[rc]
+      # XXX can be optimized:
+      for i in 0.. <x.len: regs[rb].add(x.sons[i])
+      regs[ra] = regs[rb]
+    of opcNKind:
+      decodeB(nkIntLit)
+      regs[ra].intVal = ord(regs[rb].kind)
+    of opcNIntVal:
+      decodeB(nkIntLit)
+      let a = regs[rb]
+      case a.kind
+      of nkCharLit..nkInt64Lit: regs[ra].intVal = a.intVal
+      else: stackTrace(c, tos, pc, errFieldXNotFound, "intVal")
+    of opcNFloatVal:
+      decodeB(nkFloatLit)
+      let a = regs[rb]
+      case a.kind
+      of nkFloatLit..nkFloat64Lit: regs[ra].floatVal = a.floatVal
+      else: stackTrace(c, tos, pc, errFieldXNotFound, "floatVal")
+    of opcNSymbol:
+      let rb = instr.regB
+      if regs[rb].kind != nkSym: 
+        stackTrace(c, tos, pc, errFieldXNotFound, "symbol")
+      regs[ra] = regs[rb]
+    of opcNIdent:
+      let rb = instr.regB
+      if regs[rb].kind != nkIdent: 
+        stackTrace(c, tos, pc, errFieldXNotFound, "ident")
+      regs[ra] = regs[rb]
+    of opcNGetType:
+      InternalError(c.debug[pc], "unknown opcode " & $instr.opcode)      
+    of opcNStrVal:
+      decodeB(nkStrLit)
+      let a = regs[rb]
+      case a.kind
+      of nkStrLit..nkTripleStrLit: regs[ra].strVal = a.strVal
+      else: stackTrace(c, tos, pc, errFieldXNotFound, "strVal")
+    of opcSlurp:
+      decodeB(nkStrLit)
+      regs[ra].strVal = opSlurp(regs[rb].strVal, c.debug[pc], c.module)
+    of opcGorge:
+      decodeBC(nkStrLit)
+      regs[ra].strVal = opGorge(regs[rb].strVal, regs[rc].strVal)
+    of opcNError:
+      stackTrace(c, tos, pc, errUser, regs[ra].strVal)
+    of opcNWarning:
+      Message(c.debug[pc], warnUser, regs[ra].strVal)
+    of opcNHint:
+      Message(c.debug[pc], hintUser, regs[ra].strVal)
+    of opcParseExprToAst:
+      let rb = instr.regB
+      # c.debug[pc].line.int - countLines(regs[rb].strVal) ?
+      let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename,
+                            c.debug[pc].line.int)
+      if sonsLen(ast) != 1:
+        GlobalError(c.debug[pc], errExprExpected, "multiple statements")
+      regs[ra] = ast.sons[0]
+    of opcParseStmtToAst:
+      let rb = instr.regB
+      let ast = parseString(regs[rb].strVal, c.debug[pc].toFilename,
+                            c.debug[pc].line.int)
+      regs[ra] = ast
+    of opcCallSite:
+      if c.callsite != nil: regs[ra] = c.callsite
+      else: stackTrace(c, tos, pc, errFieldXNotFound, "callsite")
     else:
       InternalError(c.debug[pc], "unknown opcode " & $instr.opcode)
     inc pc
@@ -596,7 +681,7 @@ proc myOpen(module: PSym): PPassContext =
   #var c = newEvalContext(module, emRepl)
   #c.features = {allowCast, allowFFI, allowInfiniteLoops}
   #pushStackFrame(c, newStackFrame())
-  result = newCtx()
+  result = newCtx(module)
 
 var oldErrorCount: int