add debugging commands, test + fix vm

This commit is contained in:
Jeremy Penner 2011-09-15 18:33:50 -04:00
parent e80826de9e
commit 5d01b2c047
2 changed files with 21 additions and 8 deletions

View file

@ -381,7 +381,7 @@ class SyntBinOp(SyntDesc):
try: try:
vm.Push(dgEval(left, right)) vm.Push(dgEval(left, right))
except Exception as e: except Exception as e:
Fail.Push(vm, "Failed to " + op + ": " + e, self) Fail.Push(vm, "Failed to " + op + ": " + str(e), self)
def Compile(self): def Compile(self):
return [self.left, self.right, self.Eval] return [self.left, self.right, self.Eval]
clsNew = type(stName, (cls,), {"Compile": Compile, "Eval": Eval, "op": op}) clsNew = type(stName, (cls,), {"Compile": Compile, "Eval": Eval, "op": op})
@ -437,6 +437,16 @@ class SyntSet(SyntDesc):
if not isinstance(val, Fail): if not isinstance(val, Fail):
vm.Log(vm.vars.Set(self.lvalue.syntVar, vm.Pop(), self)) vm.Log(vm.vars.Set(self.lvalue.syntVar, vm.Pop(), self))
#debug
@RegStmt
class SyntPrint(SyntDesc):
desc = [["Print"], " ", (SyntExpr, 1)]
expr = SyntDesc.DefProp(0)
def Compile(self):
return [self.expr, self.Eval]
def Eval(self, vm):
print vm.Pop()
class Fail(TPrs): class Fail(TPrs):
""" """
Failure object. Our scripting language has no exceptions; instead, if a failure object is involved in a calculation, Failure object. Our scripting language has no exceptions; instead, if a failure object is involved in a calculation,
@ -448,12 +458,12 @@ class Fail(TPrs):
self.stFailure = stFailure self.stFailure = stFailure
self.synt = synt self.synt = synt
@staticmethod @staticmethod
def Push(cls, vm, stFailure, synt): def Push(vm, stFailure, synt):
fail = Fail(stFailure, synt) fail = Fail(stFailure, synt)
vm.Push(fail) vm.Push(fail)
vm.Log(fail) vm.Log(fail)
@staticmethod @staticmethod
def Log(cls, vm, stFailure, synt): def Log(vm, stFailure, synt):
vm.Log(Fail(stFailure, synt)) vm.Log(Fail(stFailure, synt))
# projection cursor # projection cursor
@ -871,6 +881,9 @@ class Pov(TokenClient):
def run(self): def run(self):
while True: while True:
key = self.client.evKey.receive(self) key = self.client.evKey.receive(self)
if key == ansi.K_PGDN:
Vm().RunSynt(self.block)
continue
psel = self.pselstate.PselByClient(self.client) psel = self.pselstate.PselByClient(self.client)
pwSel = psel.PwSelected(self.PwProjected()) pwSel = psel.PwSelected(self.PwProjected())
while pwSel != None: while pwSel != None:

10
vm.py
View file

@ -1,5 +1,5 @@
from tpers import * from tpers import *
from scripting import Fail, Synt from scripting import Fail
class Vars(TPrs): class Vars(TPrs):
def InitPersistent(self): def InitPersistent(self):
@ -55,7 +55,7 @@ class Vm(TPrs):
if len(rNew) == 0: # no-op optimization if len(rNew) == 0: # no-op optimization
return (r, ip) return (r, ip)
if ip < len(r): # tail call optimization if ip < len(r): # tail call optimization
self.rstack.append(r, ip) self.rstack.append((r, ip))
return (rNew, 0) return (rNew, 0)
def RunSynt(self, synt): def RunSynt(self, synt):
@ -65,15 +65,15 @@ class Vm(TPrs):
if ip < len(r): if ip < len(r):
instr = r[ip] instr = r[ip]
ip += 1 ip += 1
if isinstance(instr, Synt): if hasattr(instr, "Compile"):
(r, ip) = self.CallI(instr, r, ip) (r, ip) = self.CallI(instr, r, ip)
elif callable(instr): elif callable(instr):
synt = instr(self) synt = instr(self)
if synt != None: if synt != None:
(r, ip) = self.CallI(instr, r, ip) (r, ip) = self.CallI(instr, r, ip)
else: else:
assert False, "invalid opcode" assert False, "invalid instr " + str(instr)
else: else:
if len(rstack) == 0: if len(self.rstack) == 0:
break break
(r, ip) = self.rstack.pop() (r, ip) = self.rstack.pop()