mung/language.py
2010-11-13 07:55:35 +00:00

121 lines
No EOL
2.6 KiB
Python

import time
from builtins import builtin_map
from language_types import coerce, uncoerce
class VirtualMachine(object):
def __init__(self, db):
self.db = db
self.active_task_id = None
self.sleepytime = None
self.stack = []
self.contexts = []
self.tasks = {}
self.task_sequence = []
self.ticks_used = 0
def pop(self, count=1):
return [uncoerce(self.stack.pop()) for x in range(count)]
def push(self, value):
self.stack.append(coerce(value))
def setvar(self, varname, val):
self.contexts[-1][varname] = val
def getvar(self, varname):
return self.contexts[-1][varname]
def push_context(self):
self.contexts.append({})
def pop_context(self):
self.contexts.pop()
def suspend_start_next(self, delay):
now = time.time()
newtask = heapq.heappushpop(self.task_sequence, (now+max(0.0,delay), self.stack, self.contexts, self.ticks_used))
return activate_task(newtask)
def finished_start_next(self):
now = time.time()
newtask = heapq.heappop(self.task_sequence)
return activate_task(newtask)
def activate_task(self, task):
if now < task[0]:
"task isn't ready to execute yet"
self.sleepytime = task[0] - now
heapq.heappush(self.task_sequence, task[0])
return False
self.active_task_id = task[0]
self.stack = task[1]
self.contexts = task[2]
self.ticks_used = task[3]
def get_next_task(self):
heapq.heappop(self.task_sequence)
def run_active_task
def run(self):
self.sleepytime = None
if self.active_task_id == None:
finished_start_next()
if self.active_task_id == None:
return
class CodeOp(object):
def __init__(self):
pass
class GetProperty(CodeOp):
def execute(self, vm):
prop, obj = vm.pop(2)
vm.stack.append(vm.db.get_property(obj, prop))
class SetProperty(CodeOp):
def execute(self, vm):
val, prop, obj = vm.pop(3)
vm.db.set_property(obj, prop, val)
class GetFile(CodeOp):
def execute(self, vm):
prop, obj = vm.pop(2)
vm.stack.append(vm.db.get_file(obj, prop))
class SetFile(CodeOp):
def execute(self, vm):
val, prop, obj = vm.pop(3)
vm.db.set_file(obj, prop, val)
class SetVariable(CodeOp):
def execute(self, vm):
val, varname = vm.pop(2)
vm.setvar(varname, val)
class GetVariable(CodeOp):
def execute(self, vm):
varname, = vm.pop(1)
vm.push(vm.getvar(varname))
class CallBuiltin(CodeOp):
def __init__(self):
pass
def execute(self, vm):
funcname, = vm.pop(1)
builtin_map[funcname](vm)
class StartContext(CodeOp):
def execute(self, vm):
vm.push_context()
class EndContext(CodeOp):
def execute(self, vm):
vm.pop_context()