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):
|