123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import modelverse_kernel.primitives as primitive_functions
- import modelverse_kernel.compiled as compiled_functions
- from collections import defaultdict
- import sys
- import time
- class ModelverseKernel(object):
- def __init__(self, root):
- self.root = root
- self.primitives = {}
- self.returnvalue = None
- self.success = True
- self.generators = {}
- def execute_yields(self, taskname, operation, params, reply):
- try:
- self.success = True
- self.taskname = taskname
- if taskname not in self.generators:
- self.generators[taskname] = {}
- if operation not in self.generators[taskname]:
- # Create the generator for the function to execute
- self.generators[taskname][operation] = getattr(self, operation)(taskname, *params)
- if reply is not None:
- return self.generators[taskname][operation].send(reply)
- else:
- return self.generators[taskname][operation].next()
- except StopIteration:
- # Done, so remove the generator
- del self.generators[taskname][operation]
- return None
- except:
- raise
- ##########################
- ### Process primitives ###
- ##########################
- def load_primitives(self, taskname):
- 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])
- def execute_primitive(self, task_root, inst, taskname):
- # execute_primitive
- task_frame, = yield [("RD", [task_root, "frame"])]
- symbols, = yield [("RD", [task_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["task_root"] = task_root
- parameters["taskname"] = taskname
- 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.primitives[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("Primitive finished without returning a value!")
- 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", [task_frame, "prev"])]
- lnk, = yield [("RDE", [old_frame, "returnvalue"])]
- _, _, _, _ = yield [("CD", [old_frame, "returnvalue", result]),
- ("CD", [task_root, "frame", old_frame]),
- ("DE", [lnk]),
- ("DN", [task_frame]),
- ]
- ########################################
- ### Execute input and output methods ###
- ########################################
- def get_output(self, taskname):
- task_root, = yield [("RD", [self.root, taskname])]
- first_output, = yield [("RD", [task_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", [task_root, "output", next_output]),
- ("DN", [first_output]),
- ]
- self.returnvalue = rv_value
- def set_input(self, taskname, value):
- task_root, = yield [("RD", [self.root, taskname])]
- old_input, link = yield [("RD", [task_root, "last_input"]),
- ("RDE", [task_root, "last_input"]),
- ]
- new_input, = yield [("CN", [])]
- _, _ = yield [("CD", [task_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"}
- ### Generated rules
- def execute_rule(self, taskname):
|