|
@@ -0,0 +1,996 @@
|
|
|
+"""A legacy version of the Modelverse kernel. This kernel can be used as a baseline for the
|
|
|
+performance of newer kernels."""
|
|
|
+
|
|
|
+import modelverse_kernel.primitives as primitive_functions
|
|
|
+import modelverse_kernel.compiled_legacy as compiled_functions
|
|
|
+from collections import defaultdict
|
|
|
+import sys
|
|
|
+import time
|
|
|
+
|
|
|
+if sys.version > '3': # pragma: no cover
|
|
|
+ string_types = (str,)
|
|
|
+else:
|
|
|
+ string_types = (str, unicode)
|
|
|
+
|
|
|
+class ModelverseKernel(object):
|
|
|
+ def __init__(self, root):
|
|
|
+ self.root = root
|
|
|
+ self.primitives = {}
|
|
|
+ self.compiled = {}
|
|
|
+ self.returnvalue = None
|
|
|
+ self.success = True
|
|
|
+ self.generators = {}
|
|
|
+ self.allow_compiled = True
|
|
|
+ #self.allow_compiled = False
|
|
|
+ self.debug_info = defaultdict(list)
|
|
|
+
|
|
|
+ def execute_yields(self, username, operation, params, reply):
|
|
|
+ try:
|
|
|
+ self.success = True
|
|
|
+ self.username = username
|
|
|
+ if username not in self.generators:
|
|
|
+ self.generators[username] = {}
|
|
|
+ if operation not in self.generators[username]:
|
|
|
+ # Create the generator for the function to execute
|
|
|
+ self.generators[username][operation] = getattr(self, operation)(username, *params)
|
|
|
+
|
|
|
+ if reply is not None:
|
|
|
+ return self.generators[username][operation].send(reply)
|
|
|
+ else:
|
|
|
+ return self.generators[username][operation].next()
|
|
|
+ except StopIteration:
|
|
|
+ # Done, so remove the generator
|
|
|
+ del self.generators[username][operation]
|
|
|
+ return None
|
|
|
+ except:
|
|
|
+ print("Unknown error @ %s" % self.debug_info[username])
|
|
|
+ raise
|
|
|
+
|
|
|
+ def execute_rule(self, username):
|
|
|
+ user_root, = yield [("RD", [self.root, username])]
|
|
|
+ if user_root is None:
|
|
|
+ self.success = False
|
|
|
+ self.returnvalue = None
|
|
|
+ yield None
|
|
|
+ else:
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ self.inst, phase = yield [("RD", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "phase"]),
|
|
|
+ ]
|
|
|
+ self.new_debug, self.phase_v, inst_v = \
|
|
|
+ yield [("RD", [self.inst, "__debug"]),
|
|
|
+ ("RV", [phase]),
|
|
|
+ ("RV", [self.inst]),
|
|
|
+ ]
|
|
|
+ if self.new_debug is not None:
|
|
|
+ if self.debug_info[username]:
|
|
|
+ self.debug_info[username][-1], = yield [("RV", [self.new_debug])]
|
|
|
+
|
|
|
+ if self.phase_v == "finish":
|
|
|
+ gen = self.helper_init(user_root)
|
|
|
+ elif self.inst is None:
|
|
|
+ raise Exception("Instruction pointer could not be found!")
|
|
|
+ elif isinstance(self.phase_v, string_types):
|
|
|
+ if self.phase_v == "init" and self.inst in self.compiled:
|
|
|
+ #print("%-30s(%s)" % ("COMPILED " + str(self.compiled[self.inst]), self.phase_v))
|
|
|
+ gen = self.execute_primitive(user_root, self.inst, username)
|
|
|
+ elif inst_v is None:
|
|
|
+ raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info[username], inst_v, self.phase_v))
|
|
|
+ else:
|
|
|
+ #print("%-30s(%s) -- %s" % (inst_v["value"], self.phase_v, username))
|
|
|
+ gen = getattr(self, "%s_%s" % (inst_v["value"], self.phase_v))(user_root)
|
|
|
+ elif inst_v is None:
|
|
|
+ raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info[username], inst_v, self.phase_v))
|
|
|
+ elif inst_v["value"] == "call":
|
|
|
+ #print("%-30s(%s)" % ("call", "param"))
|
|
|
+ gen = self.call_param(user_root)
|
|
|
+ else:
|
|
|
+ raise Exception("%s: error understanding command (%s, %s)" % (self.debug_info[username], inst_v, self.phase_v))
|
|
|
+
|
|
|
+ try:
|
|
|
+ inp = None
|
|
|
+ while 1:
|
|
|
+ inp = yield gen.send(inp)
|
|
|
+ except StopIteration:
|
|
|
+ pass
|
|
|
+
|
|
|
+ ##########################
|
|
|
+ ### Process primitives ###
|
|
|
+ ##########################
|
|
|
+ def load_primitives(self, username):
|
|
|
+ hierarchy, = yield [("RD", [self.root, "__hierarchy"])]
|
|
|
+ primitives, = yield [("RD", [hierarchy, "primitives"])]
|
|
|
+ keys, = yield [("RDK", [primitives])]
|
|
|
+ function_names = yield [("RV", [f]) for f in keys]
|
|
|
+ signatures = yield [("RDN", [primitives, f]) for f in keys]
|
|
|
+ bodies = yield [("RD", [f, "body"]) for f in signatures]
|
|
|
+ for i in range(len(keys)):
|
|
|
+ self.primitives[bodies[i]] = getattr(primitive_functions, function_names[i])
|
|
|
+ self.compiled.update(self.primitives)
|
|
|
+
|
|
|
+ def execute_primitive(self, user_root, inst, username):
|
|
|
+ # execute_primitive
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ symbols, = yield [("RD", [user_frame, "symbols"])]
|
|
|
+ all_links, = yield [("RO", [symbols])]
|
|
|
+ containers = yield [("RE", [v]) for v in all_links]
|
|
|
+ outgoings = yield [("RO", [v]) for v in all_links]
|
|
|
+ dict_values = yield [("RD", [v[1], "value"]) for v in containers]
|
|
|
+ formals_1 = yield [("RE", [v[0]]) for v in outgoings]
|
|
|
+ dict_keys_ref = yield [("RD", [v[1], "name"]) for v in formals_1]
|
|
|
+ dict_keys = yield [("RV", [v]) for v in dict_keys_ref]
|
|
|
+ parameters = dict(zip(dict_keys, dict_values))
|
|
|
+
|
|
|
+ parameters["root"] = self.root
|
|
|
+ parameters["user_root"] = user_root
|
|
|
+ parameters["username"] = username
|
|
|
+ parameters["mvk"] = self
|
|
|
+
|
|
|
+ # prim is a generator itself!
|
|
|
+ try:
|
|
|
+ # Forward the message we get to this generator
|
|
|
+ # Sometimes it might not even be a generator, in which case this should already be in the except block (i.e., for the Read Root operation)
|
|
|
+ prim = self.compiled[inst](**parameters)
|
|
|
+ inp = None
|
|
|
+ while 1:
|
|
|
+ inp = yield prim.send(inp)
|
|
|
+ except StopIteration:
|
|
|
+ # Execution has ended without return value, so we have no idea what to do
|
|
|
+ raise Exception("%s: primitive finished without returning a value!" % (self.debug_info[username]))
|
|
|
+ except primitive_functions.PrimitiveFinished as e:
|
|
|
+ # Execution has ended with a returnvalue, so read it out from the exception being thrown
|
|
|
+ result = e.result
|
|
|
+
|
|
|
+ #if result is None:
|
|
|
+ # raise Exception("Primitive raised exception: value of None for operation %s with parameters %s" % (self.compiled[inst], str(parameters)))
|
|
|
+
|
|
|
+ # Clean up the current stack, as if a return happened
|
|
|
+ old_frame, = yield [("RD", [user_frame, "prev"])]
|
|
|
+ lnk, = yield [("RDE", [old_frame, "returnvalue"])]
|
|
|
+ _, _, _, _ = yield [("CD", [old_frame, "returnvalue", result]),
|
|
|
+ ("CD", [user_root, "frame", old_frame]),
|
|
|
+ ("DE", [lnk]),
|
|
|
+ ("DN", [user_frame]),
|
|
|
+ ]
|
|
|
+ if self.debug_info[self.username]:
|
|
|
+ self.debug_info[self.username].pop()
|
|
|
+
|
|
|
+ ########################################
|
|
|
+ ### Execute input and output methods ###
|
|
|
+ ########################################
|
|
|
+ def get_output(self, username):
|
|
|
+ user_root, = yield [("RD", [self.root, username])]
|
|
|
+ first_output, = yield [("RD", [user_root, "output"])]
|
|
|
+ next_output, rv = yield [("RD", [first_output, "next"]),
|
|
|
+ ("RD", [first_output, "value"]),
|
|
|
+ ]
|
|
|
+ if next_output is None:
|
|
|
+ self.success = False
|
|
|
+ self.returnvalue = None
|
|
|
+ else:
|
|
|
+ rv_value, = yield [("RV", [rv])]
|
|
|
+ _, _ = yield [("CD", [user_root, "output", next_output]),
|
|
|
+ ("DN", [first_output]),
|
|
|
+ ]
|
|
|
+ self.returnvalue = rv_value
|
|
|
+
|
|
|
+ def set_input(self, username, value):
|
|
|
+ user_root, = yield [("RD", [self.root, username])]
|
|
|
+ old_input, link = yield [("RD", [user_root, "last_input"]),
|
|
|
+ ("RDE", [user_root, "last_input"]),
|
|
|
+ ]
|
|
|
+ new_input, = yield [("CN", [])]
|
|
|
+ _, _ = yield [("CD", [user_root, "last_input", new_input]),
|
|
|
+ ("CD", [old_input, "next", new_input]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ new_value, = yield [("CNV", [value])]
|
|
|
+ _, _ = yield [("CD", [old_input, "value", new_value]),
|
|
|
+ ("DE", [link])
|
|
|
+ ]
|
|
|
+ self.returnvalue = {"id": 100, "value": "success"}
|
|
|
+
|
|
|
+ #############################################
|
|
|
+ ### Transformation rules for instructions ###
|
|
|
+ #############################################
|
|
|
+ def break_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ phase_link, ip_link = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_frame, "IP"])
|
|
|
+ ]
|
|
|
+ inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
+ while_inst, new_phase = \
|
|
|
+ yield [("RD", [inst, "while"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "IP", while_inst]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def continue_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ ip_link, inst = yield [("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ while_inst, = yield [("RD", [inst, "while"])]
|
|
|
+ _, _ = yield [("CD", [user_frame, "IP", while_inst]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def if_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ evalstack, evalstack_link = \
|
|
|
+ yield [("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ]
|
|
|
+ inst, ip_link = yield [("RD", [user_frame, "IP"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ cond, = yield [("RD", [inst, "cond"])]
|
|
|
+ new_evalstack, new_phase = \
|
|
|
+ yield [("CN", []),
|
|
|
+ ("CNV", ["cond"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [user_frame, "IP", cond]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", new_phase]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def if_cond(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ returnvalue, inst = yield [("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ returnvalue_v, = yield [("RV", [returnvalue])]
|
|
|
+ _else, = yield [("RD", [inst, "else"])]
|
|
|
+
|
|
|
+ if returnvalue_v:
|
|
|
+ phase_link, evalstack, evalstack_link, ip_link, _then, new_evalstack, evalstack_phase, new_phase = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [inst, "then"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [user_frame, "IP", _then]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+ elif _else is None:
|
|
|
+ phase_link, new_phase = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ phase_link, evalstack, evalstack_link, ip_link = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ new_evalstack, new_phase, evalstack_phase = \
|
|
|
+ yield [("CN", []),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [user_frame, "IP", _else]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def while_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ evalstack, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ cond, new_evalstack, new_phase = \
|
|
|
+ yield [("RD", [inst, "cond"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["cond"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [user_frame, "IP", cond]),
|
|
|
+ ("CD", [evalstack, "phase", new_phase]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def while_cond(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ returnvalue, = yield [("RD", [user_frame, "returnvalue"])]
|
|
|
+ returnvalue_v, = yield [("RV", [returnvalue])]
|
|
|
+
|
|
|
+ if returnvalue_v:
|
|
|
+ phase_link, evalstack, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ body, = yield [("RD", [inst, "body"])]
|
|
|
+ new_evalstack, new_phase, evalstack_phase = \
|
|
|
+ yield [("CN", []),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "IP", body]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ phase_link, new_phase = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [phase_link])
|
|
|
+ ]
|
|
|
+
|
|
|
+ def access_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ evalstack, evalstack_link, inst, ip_link = \
|
|
|
+ yield [("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ var, new_evalstack, new_phase = \
|
|
|
+ yield [("RD", [inst, "var"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["eval"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "IP", var]),
|
|
|
+ ("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", new_phase]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def access_eval(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ phase_link, returnvalue_link, returnvalue = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_frame, "returnvalue"]),
|
|
|
+ ]
|
|
|
+ value, new_phase = yield [("RD", [returnvalue, "value"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "returnvalue", value]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [returnvalue_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def resolve_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ symbols, evalstack, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RD", [user_frame, "symbols"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ var, = yield [("RD", [inst, "var"])]
|
|
|
+ variable, = yield [("RDN", [symbols, var])]
|
|
|
+
|
|
|
+ if variable is None:
|
|
|
+ phase_link, returnvalue_link, _globals, var_name = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_root, "globals"]),
|
|
|
+ ("RV", [var]),
|
|
|
+ ]
|
|
|
+ variable, new_phase = \
|
|
|
+ yield [("RD", [_globals, var_name]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ if variable is None:
|
|
|
+ raise Exception("Not found as global: %s" % var_name)
|
|
|
+
|
|
|
+ # Resolved a global, so this is a string
|
|
|
+ # Potentially, this might even be a function that we have precompiled already!
|
|
|
+ # So check whether this is the case or not
|
|
|
+ if self.allow_compiled:
|
|
|
+ compiled_function = getattr(compiled_functions, var_name, None)
|
|
|
+ if compiled_function is not None:
|
|
|
+ # We have a compiled function ready!
|
|
|
+ # Now we have to bind the ID to the compiled functions
|
|
|
+ # For this, we read out the body of the resolved data
|
|
|
+ compiler_val, = yield [("RD", [variable, "value"])]
|
|
|
+ compiler_body, = yield [("RD", [compiler_val, "body"])]
|
|
|
+ self.compiled[compiler_body] = compiled_function
|
|
|
+
|
|
|
+ else:
|
|
|
+ phase_link, returnvalue_link, new_phase = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_frame, "returnvalue"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "returnvalue", variable]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [returnvalue_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def assign_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ evalstack, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ var, new_evalstack, new_phase = \
|
|
|
+ yield [("RD", [inst, "var"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["value"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "IP", var]),
|
|
|
+ ("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", new_phase]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def assign_value(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ phase_link, evalstack, returnvalue, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ value, new_evalstack, new_phase, evalstack_phase = \
|
|
|
+ yield [("RD", [inst, "value"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ("CNV", ["assign"]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ _, _, _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "variable", returnvalue]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("CD", [user_frame, "IP", value]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def assign_assign(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ phase_link, returnvalue, variable_link, variable = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RDE", [user_frame, "variable"]),
|
|
|
+ ("RD", [user_frame, "variable"]),
|
|
|
+ ]
|
|
|
+ value_link, new_phase = \
|
|
|
+ yield [("RDE", [variable, "value"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [variable, "value", returnvalue]),
|
|
|
+ ("DE", [variable_link]),
|
|
|
+ ("DE", [value_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def return_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
+ value, = yield [("RD", [inst, "value"])]
|
|
|
+
|
|
|
+ if value is None:
|
|
|
+ prev_frame, = yield [("RD", [user_frame, "prev"])]
|
|
|
+ if prev_frame is None:
|
|
|
+ _, = yield [("DN", [user_root])]
|
|
|
+ del self.debug_info[self.username]
|
|
|
+ else:
|
|
|
+ if self.debug_info[self.username]:
|
|
|
+ self.debug_info[self.username].pop()
|
|
|
+ _, _ = yield [("CD", [user_root, "frame", prev_frame]),
|
|
|
+ ("DN", [user_frame]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ evalstack, evalstack_link, ip_link, new_evalstack, evalstack_phase = \
|
|
|
+ yield [("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["eval"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("CD", [user_frame, "IP", value]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def return_eval(self, user_root):
|
|
|
+ if self.debug_info[self.username]:
|
|
|
+ self.debug_info[self.username].pop()
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ prev_frame, = yield [("RD", [user_frame, "prev"])]
|
|
|
+ returnvalue, old_returnvalue_link = \
|
|
|
+ yield [("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RDE", [prev_frame, "returnvalue"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = yield [("CD", [user_root, "frame", prev_frame]),
|
|
|
+ ("CD", [prev_frame, "returnvalue", returnvalue]),
|
|
|
+ ("DE", [old_returnvalue_link]),
|
|
|
+ ("DN", [user_frame]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def constant_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ phase_link, returnvalue_link, inst = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ node, new_phase = yield [("RD", [inst, "node"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "returnvalue", node]),
|
|
|
+ ("DE", [returnvalue_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def helper_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
+ next, = yield [("RD", [inst, "next"])]
|
|
|
+
|
|
|
+ if next is None:
|
|
|
+ ip_link, phase_link, evalstack_top = \
|
|
|
+ yield [("RDE", [user_frame, "IP"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ]
|
|
|
+ evalstack, = yield [("RD", [evalstack_top, "prev"])]
|
|
|
+ evalstack_inst, evalstack_phase, evalstack_inst_link, evalstack_phase_link = \
|
|
|
+ yield [("RD", [evalstack, "inst"]),
|
|
|
+ ("RD", [evalstack, "phase"]),
|
|
|
+ ("RDE", [evalstack, "inst"]),
|
|
|
+ ("RDE", [evalstack, "phase"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", evalstack]),
|
|
|
+ ("CD", [user_frame, "IP", evalstack_inst]),
|
|
|
+ ("CD", [user_frame, "phase", evalstack_phase]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [evalstack_inst_link]),
|
|
|
+ ("DE", [evalstack_phase_link]),
|
|
|
+ ("DN", [evalstack_top]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ ip_link, phase_link, new_phase = \
|
|
|
+ yield [("RDE", [user_frame, "IP"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = yield [("CD", [user_frame, "IP", next]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def call_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ symbols, evalstack, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RD", [user_frame, "symbols"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ func, params = yield [("RD", [inst, "func"]),
|
|
|
+ ("RD", [inst, "params"]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ if params is None:
|
|
|
+ new_evalstack, evalstack_phase = \
|
|
|
+ yield [("CN", []),
|
|
|
+ ("CNV", ["call"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("CD", [user_frame, "IP", func]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ new_evalstack,= yield [("CN", [])]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", params]),
|
|
|
+ ("CD", [user_frame, "IP", func]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def call_call(self, user_root):
|
|
|
+ self.debug_info[self.username].append("None")
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
+ param, = yield [("RD", [inst, "last_param"])]
|
|
|
+
|
|
|
+ if param is None:
|
|
|
+ returnvalue, = yield [("RD", [user_frame, "returnvalue"])]
|
|
|
+ body, phase_link, frame_link, prev_phase, new_phase, new_frame, new_evalstack, new_symbols, new_returnvalue = \
|
|
|
+ yield [("RD", [returnvalue, "body"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_root, "frame"]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_root, "frame", new_frame]),
|
|
|
+ ("CD", [new_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_frame, "symbols", new_symbols]),
|
|
|
+ ("CD", [new_frame, "returnvalue", new_returnvalue]),
|
|
|
+ ("CD", [new_frame, "caller", inst]),
|
|
|
+ ("CD", [new_frame, "phase", new_phase]),
|
|
|
+ ("CD", [new_frame, "IP", body]),
|
|
|
+ ("CD", [new_frame, "prev", user_frame]),
|
|
|
+ ("CD", [user_frame, "phase", prev_phase]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [frame_link]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ newer_frames, invoking_frames = \
|
|
|
+ yield [("RRD", [user_frame, "prev"]),
|
|
|
+ ("RRD", [inst, "caller"]),
|
|
|
+ ]
|
|
|
+ new_frame = self.find_overlapping(newer_frames, invoking_frames)
|
|
|
+ phase_link, frame_link, new_symbols, new_IP = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_root, "frame"]),
|
|
|
+ ("RD", [new_frame, "symbols"]),
|
|
|
+ ("RD", [new_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ signature, = yield [("RRD", [new_IP, "body"])]
|
|
|
+ signature = signature[0]
|
|
|
+ sig_params, last_param = \
|
|
|
+ yield [("RD", [signature, "params"]),
|
|
|
+ ("RD", [inst, "last_param"]),
|
|
|
+ ]
|
|
|
+ name, = yield [("RD", [last_param, "name"])]
|
|
|
+ name_value, = yield [("RV", [name])]
|
|
|
+ returnvalue, formal_parameter, new_phase, variable = \
|
|
|
+ yield [("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [sig_params, name_value]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ("CN", []),
|
|
|
+ ]
|
|
|
+ _, _, _, t1 = yield [("CD", [user_root, "frame", new_frame]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [variable, "value", returnvalue]),
|
|
|
+ ("CE", [new_symbols, variable]),
|
|
|
+ ]
|
|
|
+ _, _, _ = yield [("CE", [t1, formal_parameter]),
|
|
|
+ ("DE", [frame_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def find_overlapping(self, a, b):
|
|
|
+ newer_frames = set(a)
|
|
|
+ invoking_frames = set(b)
|
|
|
+ matches = list(newer_frames.intersection(invoking_frames))
|
|
|
+ if len(matches) == 1:
|
|
|
+ return matches[0]
|
|
|
+ elif len(matches) > 1:
|
|
|
+ raise Exception("Error: multiple overlapping elements")
|
|
|
+ else:
|
|
|
+ raise Exception("Error: could not find any overlap")
|
|
|
+
|
|
|
+ def call_param(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ inst, phase = yield [("RD", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "phase"]),
|
|
|
+ ]
|
|
|
+ params, last_param = \
|
|
|
+ yield [("RD", [inst, "params"]),
|
|
|
+ ("RD", [inst, "last_param"]),
|
|
|
+ ]
|
|
|
+ next_param, = yield [("RD", [params, "next_param"])]
|
|
|
+
|
|
|
+ if params == phase:
|
|
|
+ phase_link, ip_link, returnvalue, param_value, evalstack, evalstack_link = \
|
|
|
+ yield [("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [params, "value"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ]
|
|
|
+ body, = yield [("RD", [returnvalue, "body"])]
|
|
|
+ new_frame, prev_evalstack, new_phase, prev_phase, new_evalstack, new_symbols, new_returnvalue = \
|
|
|
+ yield [("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ("CNV", ["init"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [new_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_frame, "symbols", new_symbols]),
|
|
|
+ ("CD", [new_frame, "returnvalue", new_returnvalue]),
|
|
|
+ ("CD", [new_frame, "caller", inst]),
|
|
|
+ ("CD", [new_frame, "phase", new_phase]),
|
|
|
+ ("CD", [new_frame, "IP", body]),
|
|
|
+ ("CD", [new_frame, "prev", user_frame]),
|
|
|
+ ("CD", [user_frame, "phase", prev_phase]),
|
|
|
+ ("CD", [user_frame, "IP", param_value]),
|
|
|
+ ("CD", [prev_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [user_frame, "evalstack", prev_evalstack]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+ if next_param is not None:
|
|
|
+ _ = yield [("CD", [evalstack, "phase", next_param])]
|
|
|
+ else:
|
|
|
+ evalstack_phase, = \
|
|
|
+ yield [("CNV", ["call"])]
|
|
|
+ _ = yield [("CD", [evalstack, "phase", evalstack_phase])]
|
|
|
+ else:
|
|
|
+ frame_link, phase_link, newer_frames, invoking_frames = \
|
|
|
+ yield [("RDE", [user_root, "frame"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("RRD", [user_frame, "prev"]),
|
|
|
+ ("RRD", [inst, "caller"]),
|
|
|
+ ]
|
|
|
+ new_frame = self.find_overlapping(newer_frames, invoking_frames)
|
|
|
+ ip_link, evalstack, evalstack_link, new_symbols, new_IP = \
|
|
|
+ yield [("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RD", [new_frame, "symbols"]),
|
|
|
+ ("RD", [new_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ signature, = yield [("RRD", [new_IP, "body"])]
|
|
|
+ signature = signature[0]
|
|
|
+ sig_params, = yield [("RD", [signature, "params"])]
|
|
|
+
|
|
|
+ if last_param == phase:
|
|
|
+ prev_param, = \
|
|
|
+ yield [("RRD", [last_param, "next_param"])]
|
|
|
+ prev_param = prev_param[0]
|
|
|
+ name, = yield [("RD", [prev_param, "name"])]
|
|
|
+ name_value, = \
|
|
|
+ yield [("RV", [name])]
|
|
|
+ evalstack_phase, = \
|
|
|
+ yield [("CNV", ["call"])]
|
|
|
+ _ = yield [("CD", [evalstack, "phase", evalstack_phase])]
|
|
|
+ formal_parameter, param_value = \
|
|
|
+ yield [("RD", [sig_params, name_value]),
|
|
|
+ ("RD", [last_param, "value"]),
|
|
|
+ ]
|
|
|
+ else:
|
|
|
+ param_b, = yield [("RD", [user_frame, "phase"])]
|
|
|
+ param_c, param_a = \
|
|
|
+ yield [("RD", [param_b, "next_param"]),
|
|
|
+ ("RRD", [param_b, "next_param"]),
|
|
|
+ ]
|
|
|
+ param_a = param_a[0]
|
|
|
+ name, param_value = \
|
|
|
+ yield [("RD", [param_a, "name"]),
|
|
|
+ ("RD", [param_b, "value"]),
|
|
|
+ ]
|
|
|
+ name_value, = \
|
|
|
+ yield [("RV", [name])]
|
|
|
+ formal_parameter, _ = \
|
|
|
+ yield [("RD", [sig_params, name_value]),
|
|
|
+ ("CD", [evalstack, "phase", param_c]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ new_phase, new_evalstack, variable, returnvalue = \
|
|
|
+ yield [("CNV", ["init"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CN", []),
|
|
|
+ ("RD", [user_frame, "returnvalue"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("CD", [user_frame, "IP", param_value]),
|
|
|
+ ("CD", [variable, "value", returnvalue]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ t1, = yield [("CE", [new_symbols, variable])]
|
|
|
+ _, _, _, _ = \
|
|
|
+ yield [("CE", [t1, formal_parameter]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def input_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ returnvalue_link, _input = \
|
|
|
+ yield [("RDE", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_root, "input"]),
|
|
|
+ ]
|
|
|
+ value, next, phase_link = \
|
|
|
+ yield [("RD", [_input, "value"]),
|
|
|
+ ("RD", [_input, "next"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ if value is not None:
|
|
|
+ v = yield [("RV", [value])]
|
|
|
+ _, _, finish = \
|
|
|
+ yield [("CD", [user_frame, "returnvalue", value]),
|
|
|
+ ("CD", [user_root, "input", next]),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "phase", finish]),
|
|
|
+ ("DN", [_input]),
|
|
|
+ ("DE", [returnvalue_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+ self.input_value = value
|
|
|
+ else:
|
|
|
+ # No input yet, so just wait and don't advance IP or phase
|
|
|
+ self.input_value = None
|
|
|
+ self.success = False
|
|
|
+
|
|
|
+ def output_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ evalstack, evalstack_link, ip_link, inst = \
|
|
|
+ yield [("RD", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "evalstack"]),
|
|
|
+ ("RDE", [user_frame, "IP"]),
|
|
|
+ ("RD", [user_frame, "IP"]),
|
|
|
+ ]
|
|
|
+ value, new_evalstack, evalstack_phase = \
|
|
|
+ yield [("RD", [inst, "value"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["output"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [user_frame, "evalstack", new_evalstack]),
|
|
|
+ ("CD", [new_evalstack, "prev", evalstack]),
|
|
|
+ ("CD", [evalstack, "inst", inst]),
|
|
|
+ ("CD", [evalstack, "phase", evalstack_phase]),
|
|
|
+ ("CD", [user_frame, "IP", value]),
|
|
|
+ ("DE", [evalstack_link]),
|
|
|
+ ("DE", [ip_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def output_output(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ returnvalue_link, returnvalue, last_output, phase_link, last_output_link, new_last_output, finish = \
|
|
|
+ yield [("RDE", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_frame, "returnvalue"]),
|
|
|
+ ("RD", [user_root, "last_output"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("RDE", [user_root, "last_output"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+ _, _, _, _, _, _ = \
|
|
|
+ yield [("CD", [last_output, "value", returnvalue]),
|
|
|
+ ("CD", [last_output, "next", new_last_output]),
|
|
|
+ ("CD", [user_root, "last_output", new_last_output]),
|
|
|
+ ("CD", [user_frame, "phase", finish]),
|
|
|
+ ("DE", [last_output_link]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def declare_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
+ new_var, symbols, phase_link, empty_node, new_phase = \
|
|
|
+ yield [("RD", [inst, "var"]),
|
|
|
+ ("RD", [user_frame, "symbols"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ exists, = yield [("RDN", [symbols, new_var])]
|
|
|
+ if exists is None:
|
|
|
+ new_edge, = yield [("CE", [symbols, empty_node])]
|
|
|
+ _ = yield [("CE", [new_edge, new_var])]
|
|
|
+
|
|
|
+ _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [phase_link]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ def global_init(self, user_root):
|
|
|
+ user_frame, = yield [("RD", [user_root, "frame"])]
|
|
|
+ inst, = yield [("RD", [user_frame, "IP"])]
|
|
|
+ new_var, global_symbols, phase_link, empty_node, new_phase = \
|
|
|
+ yield [("RD", [inst, "var"]),
|
|
|
+ ("RD", [user_root, "globals"]),
|
|
|
+ ("RDE", [user_frame, "phase"]),
|
|
|
+ ("CN", []),
|
|
|
+ ("CNV", ["finish"]),
|
|
|
+ ]
|
|
|
+
|
|
|
+ value, = yield [("RV", [new_var])]
|
|
|
+ exists, = yield [("RD", [global_symbols, value])]
|
|
|
+
|
|
|
+ if exists is None:
|
|
|
+ yield [("CD", [global_symbols, value, empty_node])]
|
|
|
+
|
|
|
+ _, _ = yield [("CD", [user_frame, "phase", new_phase]),
|
|
|
+ ("DE", [phase_link])
|
|
|
+ ]
|