فهرست منبع

Fix several issues with output; introduce new "FINISH" opcode

Yentl Van Tendeloo 7 سال پیش
والد
کامیت
1bce8f0e46

+ 1 - 0
bootstrap/metamodels.alt

@@ -215,6 +215,7 @@ Void function initialize_AL(scd_location : String, export_location : String):
 	instantiate_link(model, "Inheritance", "", "return", "Statement")
 	instantiate_link(model, "Inheritance", "", "call", "Statement")
 	instantiate_link(model, "Inheritance", "", "declare", "Statement")
+	instantiate_link(model, "Inheritance", "", "output", "Statement")
 	instantiate_link(model, "Inheritance", "", "call", "Expression")
 	instantiate_link(model, "Inheritance", "", "access", "Expression")
 	instantiate_link(model, "Inheritance", "", "constant", "Expression")

+ 0 - 38
kernel/modelverse_kernel/compiled.py

@@ -1,4 +1,3 @@
-from modelverse_kernel.primitives import PrimitiveFinished
 import time
 
 def get_superclasses(a, b, **remainder):
@@ -49,7 +48,6 @@ def get_superclasses(a, b, **remainder):
     result, = yield [("CN", [])]
     yield [("CD", [result, i, result]) for i in found]
 
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def reverseKeyLookupMulti(a, b, **remainder):
@@ -71,7 +69,6 @@ def reverseKeyLookupMulti(a, b, **remainder):
     edges = yield [("CE", [result, result]) for value in values]
     yield [("CE", [edge, value[1]]) for edge, value in zip(edges, values)]
 
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def reverseKeyLookup(a, b, **remainder):
@@ -84,10 +81,8 @@ def reverseKeyLookup(a, b, **remainder):
         # Select one option randomly
         out_edge = out_edges.pop()
         e, = yield [("RE", [out_edge])]
-        #raise PrimitiveFinished({'id': e[1]})
         yield [("RETURN", [{'id': e[1]}])]
     else:
-        #raise PrimitiveFinished({'value': ""})
         yield [("RETURN", [{'value': ""}])]
 
 def instantiated_name(a, b, **remainder):
@@ -97,27 +92,22 @@ def instantiated_name(a, b, **remainder):
         b['value'], = yield [("RV", [b["id"]])]
 
     if b['value'] == "":
-        #raise PrimitiveFinished({'value': "__" + str(a['id'])})
         yield [("RETURN", [{'value': "__" + str(a['id'])}])]
     else:
-        #raise PrimitiveFinished(b)
         yield [("RETURN", [b])]
 
 def set_merge(a, b, **remainder):
     keys, =         yield [("RDK", [b['id']])]
     edges =         yield [("CE", [a['id'], a['id']]) for key in keys]
     _ =             yield [("CE", [edge, key]) for edge, key in zip(edges, keys)]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def has_value(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
     if a['value'] is None:
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]
     else:
-        #raise PrimitiveFinished({'value': True})
         yield [("RETURN", [{'value': True}])]
 
 def make_reverse_dictionary(a, **remainder):
@@ -125,7 +115,6 @@ def make_reverse_dictionary(a, **remainder):
     key_nodes, = yield [("RDK", [a['id']])]
     values = yield [("RDN", [a['id'], i]) for i in key_nodes]
     yield [("CD", [reverse, str(v), k]) for k, v in zip(key_nodes, values)]
-    #raise PrimitiveFinished({'id': reverse})
     yield [("RETURN", [{'id': reverse}])]
 
 def dict_eq(a, b, **remainder):
@@ -141,7 +130,6 @@ def dict_eq(a, b, **remainder):
     values = yield [("RV", [i]) for i in values]
     b_dict = dict(list(zip(key_values, values)))
 
-    #raise PrimitiveFinished({'value': a_dict == b_dict})
     yield [("RETURN", [{'value': a_dict == b_dict}])]
 
 def string_substr(a, b, c, **remainder):
@@ -157,7 +145,6 @@ def string_substr(a, b, c, **remainder):
     except:
         new_value = ""
     
-    #raise PrimitiveFinished({'value': new_value})
     yield [("RETURN", [{'value': new_value}])]
 
 def integer_gt(a, b, **remainder):
@@ -165,13 +152,11 @@ def integer_gt(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] > b['value']})
     yield [("RETURN", [{'value': a['value'] > b['value']}])]
 
 def integer_neg(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': -a['value']})
     yield [("RETURN", [{'value': -a['value']}])]
 
 def float_gt(a, b, **remainder):
@@ -179,13 +164,11 @@ def float_gt(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] > b['value']})
     yield [("RETURN", [{'value': a['value'] > b['value']}])]
 
 def float_neg(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': -a['value']})
     yield [("RETURN", [{'value': -a['value']}])]
 
 def value_neq(a, b, **remainder):
@@ -193,15 +176,12 @@ def value_neq(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] != b['value']})
     yield [("RETURN", [{'value': a['value'] != b['value']}])]
 
 def element_neq(a, b, **remainder):
     if 'id' not in a or 'id' not in b:
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]
     else:
-        #raise PrimitiveFinished({'value': a['id'] != b['id']})
         yield [("RETURN", [{'value': a['id'] != b['id']}])]
 
 def list_append(a, b, **remainder):
@@ -209,7 +189,6 @@ def list_append(a, b, **remainder):
         b['id'], = yield [("CNV", [b['value']])]
     a_outgoing, = yield [("RO", [a['id']])]
     _ = yield [("CD", [a['id'], len(a_outgoing), b['id']])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def list_read(a, b, **remainder):
@@ -218,13 +197,11 @@ def list_read(a, b, **remainder):
     result, = yield [("RD", [a['id'], b['value']])]
     if result is None:
         raise Exception("List read out of bounds: %s" % b['value'])
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def list_len(a, **remainder):
     outgoings, = yield [("RO", [a['id']])]
     result, = yield [("CNV", [len(outgoings)])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def dict_add(a, b, c, **remainder):
@@ -234,12 +211,10 @@ def dict_add(a, b, c, **remainder):
         c['id'], = yield [("CNV", [c['value']])]
     new_edge, = yield [("CE", [a['id'], c['id']])]
     yield [("CE", [new_edge, b['id']])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def dict_len(a, **remainder):
     outgoings, = yield [("RO", [a['id']])]
-    #raise PrimitiveFinished({'value': len(outgoings)})
     yield [("RETURN", [{'value': len(outgoings)}])]
 
 def set_add(a, b, **remainder):
@@ -248,7 +223,6 @@ def set_add(a, b, **remainder):
     is_in, =    yield [("RD", [a['id'], b['value']])]
     if not is_in:
         _, =    yield [("CD", [a['id'], b['value'], a['id']])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def set_add_node(a, b, **remainder):
@@ -258,7 +232,6 @@ def set_add_node(a, b, **remainder):
     if not is_in:
         edge, = yield [("CE", [a['id'], a['id']])]
         _, =    yield [("CE", [edge, b['id']])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def set_pop(a, **remainder):
@@ -268,27 +241,22 @@ def set_pop(a, **remainder):
         new_outgoing, = yield [("RO", [outgoing])]
         new_outgoing = new_outgoing[0]
         edge, _ = yield [("RE", [new_outgoing]), ("DE", [outgoing])]
-        #raise PrimitiveFinished({'id': edge[1]})
         yield [("RETURN", [{'id': edge[1]}])]
     else:
         raise Exception("POP from empty set")
         print("Pop from empty set!")
-        #raise PrimitiveFinished({'id': remainder["root"]})
         yield [("RETURN", [{'id': remainder["root"]}])]
 
 def set_create(**remainder):
     result, = yield [("CN", [])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def list_create(**remainder):
     result, = yield [("CN", [])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def dict_create(**remainder):
     result, = yield [("CN", [])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def create_tuple(a, b, **remainder):
@@ -301,7 +269,6 @@ def create_tuple(a, b, **remainder):
     _, _ =    yield [("CD", [result, 0, a['id']]),
                      ("CD", [result, 1, b['id']]),
                     ]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def set_overlap(a, b, **remainder):
@@ -312,7 +279,6 @@ def set_overlap(a, b, **remainder):
     result = set(a_values) & set(b_values)
     yield [("CD", [res, value, res]) for value in result]
 
-    #raise PrimitiveFinished({'id': res})
     yield [("RETURN", [{'id': res}])]
 
 def list_pop_final(a, **remainder):
@@ -321,7 +287,6 @@ def list_pop_final(a, **remainder):
     result, result_edge = yield [("RD", [a['id'], length - 1]),
                                  ("RDE", [a['id'], length -1])]
     _, = yield [("DE", [result_edge])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def instantiate_node(a, b, c, **remainder):
@@ -346,7 +311,6 @@ def instantiate_node(a, b, c, **remainder):
     yield [("CD", [dict_entry, name, node])]
     yield [("CD", [typing, name, b['id']])]
 
-    #raise PrimitiveFinished(name_node)
     yield [("RETURN", [name_node])]
 
 def list_insert(a, b, c, **remainder):
@@ -365,7 +329,6 @@ def list_insert(a, b, c, **remainder):
     yield [("CD", [a['id'], c['value'], b['id']])] + \
           [("CD", [a['id'], c['value'] + 1 + index, value]) for index, value in enumerate(values)] + \
           [("DE", [i]) for i in edges]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def list_delete(a, b, **remainder):
@@ -381,5 +344,4 @@ def list_delete(a, b, **remainder):
 
     yield [("CD", [a['id'], b['value'] + index, value]) for index, value in enumerate(values[1:])] + \
           [("DE", [i]) for i in edges]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]

+ 1 - 4
kernel/modelverse_kernel/jit.py

@@ -8,9 +8,7 @@ class ModelverseJit(object):
     def __init__(self):
         self.todo_entry_points = set()
         self.jitted_parameters = {}
-        self.jit_globals = {
-            'PrimitiveFinished' : primitive_functions.PrimitiveFinished,
-        }
+        self.jit_globals = {}
         # jitted_entry_points maps body ids to values in jit_globals.
         self.jitted_entry_points = {}
         # global_functions maps global value names to body ids.
@@ -155,7 +153,6 @@ class ModelverseJit(object):
                 param_names = [i[0] for i in lst]
                 self.jitted_parameters[body_id] = (param_vars, param_names, is_mutable)
 
-        #raise primitive_functions.PrimitiveFinished(self.jitted_parameters[body_id])
         yield [("RETURN", [self.jitted_parameters[body_id]])]
 
     def check_jittable(self, body_id, suggested_name=None):

+ 35 - 11
kernel/modelverse_kernel/main.py

@@ -92,6 +92,8 @@ class ModelverseKernel(object):
 
             yield [("CALL", [gen])]
 
+        yield [("FINISH", [])]
+
     def get_inst_phase_generator(self, inst_v, phase_v, task_root):
         """Gets a generator for the given instruction in the given phase,
            for the specified task root."""
@@ -103,6 +105,7 @@ class ModelverseKernel(object):
     ##########################
     def load_primitives(self, taskname):
         yield [("CALL_ARGS", [self.load_primitives_from, (taskname, 'primitives', primitive_functions)])]
+        yield [("FINISH", [])]
 
     def load_primitives_from(self, taskname, source_name, source):
         hierarchy, = yield [("RD", [self.root, "__hierarchy"])]
@@ -113,6 +116,7 @@ class ModelverseKernel(object):
         bodies = yield [("RD", [f, "body"]) for f in signatures]
         for i in range(len(keys)):
             self.jit.register_compiled(bodies[i], getattr(source, function_names[i]), function_names[i])
+        yield [("RETURN", [None])]
 
     def print_instruction(self, inst, indent, nested_indent=None):
         """
@@ -169,10 +173,8 @@ class ModelverseKernel(object):
             value, = yield [("RD", [inst, "value"])]
             if value:
                 (prev_value, instruction_value), = yield [("CALL_ARGS", [self.print_instruction, (value, 0, indent)])]
-                #instruction = prev_value + "  " * indent + "raise PrimitiveFinished(%s)\n" % instruction_value
                 instruction = prev_value + "  " * indent + "yield [('RETURN', [%s])]\n" % instruction_value
             else:
-                #instruction = "  " * indent + "raise PrimitiveFinished(None)\n"
                 instruction = "  " * indent + "yield [('RETURN', [None])]\n"
 
         elif inst_type["value"] == "declare":
@@ -204,12 +206,12 @@ class ModelverseKernel(object):
 
         elif inst_type["value"] == "output":
             value, = yield [("RD", [inst, "value"])]
-            (prev, inst), = yield [("CALL_ARGS", [self.print_instruction, (value, 0, indent)])]
+            (prev, instruction), = yield [("CALL_ARGS", [self.print_instruction, (value, 0, indent)])]
             instruction = prev + \
-                          "  " * indent + "if 'id' not in %s:\n" % inst + \
-                          "  " * (indent + 1) + "%s['id'], = yield [('CNV', [%s['value']])]\n" % (inst, inst) + \
+                          "  " * indent + "if 'id' not in %s:\n" % instruction + \
+                          "  " * (indent + 1) + "%s['id'], = yield [('CNV', [%s['value']])]\n" % (instruction, instruction) + \
                           "  " * indent + "_outputs, _outputs_e = yield [('RD', [_root, 'last_output']), ('RDE', [_root, 'last_output'])]\n" + \
-                          "  " * indent + "_, _new = yield [('CD', [_outputs, 'value', %s['id']]), ('CN', [])]\n" % inst+ \
+                          "  " * indent + "_, _new = yield [('CD', [_outputs, 'value', %s['id']]), ('CN', [])]\n" % instruction + \
                           "  " * indent + "yield [('CD', [_outputs, 'next', _new]), ('DE', [_outputs_e]), ('CD', [_root, 'last_output', _new])]\n"
 
         elif inst_type["value"] == "resolve":
@@ -320,7 +322,6 @@ class ModelverseKernel(object):
         else:
             next_inst = ""
 
-        #raise primitive_functions.PrimitiveFinished((prev, instruction + next_inst))
         yield [('RETURN', [(prev, instruction + next_inst)])]
 
     def read_function(self, inst, suggested_name):
@@ -350,7 +351,6 @@ class ModelverseKernel(object):
         with open('/tmp/junk/%s' % suggested_name, 'w') as f:
             f.write(func)
 
-        #raise primitive_functions.PrimitiveFinished(func)
         yield [("RETURN", [func])]
 
     def jit_compile(self, task_root, inst):
@@ -363,7 +363,6 @@ class ModelverseKernel(object):
             raise ValueError('body_id cannot be None: ' + str(suggested_name))
 
         elif inst in self.jit.jitted_entry_points:
-            #raise primitive_functions.PrimitiveFinished(self.jit.jit_globals[self.jit.jitted_entry_points[inst]])
             yield [("RETURN", [self.jit.jit_globals[self.jit.jitted_entry_points[inst]]])]
         else:
             compiled_func = self.jit.lookup_compiled_body(inst)
@@ -377,7 +376,6 @@ class ModelverseKernel(object):
                 compiled_func = self.jit.jit_globals[suggested_name]
                 self.jit.register_compiled(inst, compiled_func, suggested_name)
 
-            #raise primitive_functions.PrimitiveFinished(compiled_func)
             yield [("RETURN", [compiled_func])]
 
     def execute_jit(self, task_root, inst, taskname, params = {}, store=False, resolve=True):
@@ -462,8 +460,8 @@ class ModelverseKernel(object):
                                       ]
 
         else:
-            #raise primitive_functions.PrimitiveFinished(result)
             yield [("RETURN", [result])]
+        yield [("RETURN", [None])]
 
     ########################################
     ### Execute input and output methods ###
@@ -487,6 +485,7 @@ class ModelverseKernel(object):
             self.returnvalue = rv_value
             self.success = True
             #print("OUTPUT: (%s, %s)" % (taskname, self.returnvalue))
+        yield [("FINISH", [])]
 
     def set_input(self, taskname, value):
         task_root, =        yield [("RD", [self.root, taskname])]
@@ -503,6 +502,7 @@ class ModelverseKernel(object):
                                   ]
         #print("INPUT: (%s, %s)" % (taskname, value))
         self.returnvalue = {"id": 100, "value": "success"}
+        yield [("FINISH", [])]
 
     #############################################
     ### Transformation rules for instructions ###
@@ -550,6 +550,7 @@ class ModelverseKernel(object):
                                    ("DE", [old_phase_link]),
                                    ("DE", [old_evalstack_phase_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def break_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -593,6 +594,7 @@ class ModelverseKernel(object):
                                    ("DE", [old_phase_link]),
                                    ("DE", [old_evalstack_phase_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def if_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -617,6 +619,7 @@ class ModelverseKernel(object):
                                    ("DE", [evalstack_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def if_cond(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -679,6 +682,7 @@ class ModelverseKernel(object):
                                    ("DE", [ip_link]),
                                    ("DE", [phase_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def while_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -702,6 +706,7 @@ class ModelverseKernel(object):
                                    ("DE", [evalstack_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def while_cond(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -746,6 +751,7 @@ class ModelverseKernel(object):
             _, _ =          yield [("CD", [task_frame, "phase", new_phase]),
                                    ("DE", [phase_link])
                                   ]
+        yield [("RETURN", [None])]
 
     def access_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -769,6 +775,7 @@ class ModelverseKernel(object):
                                    ("DE", [evalstack_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def access_eval(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -785,6 +792,7 @@ class ModelverseKernel(object):
                                    ("DE", [phase_link]),
                                    ("DE", [returnvalue_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def resolve_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -849,6 +857,7 @@ class ModelverseKernel(object):
                                    ("DE", [phase_link]),
                                    ("DE", [returnvalue_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def assign_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -872,6 +881,7 @@ class ModelverseKernel(object):
                                    ("DE", [evalstack_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def assign_value(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -902,6 +912,7 @@ class ModelverseKernel(object):
                                    ("DE", [phase_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def assign_assign(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -921,6 +932,7 @@ class ModelverseKernel(object):
                                    ("DE", [value_link]),
                                    ("DE", [phase_link]),
                                   ]
+        yield [("RETURN", [None])]
                     
     def return_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -963,6 +975,7 @@ class ModelverseKernel(object):
                                    ("DE", [evalstack_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def return_eval(self, task_root):
         if self.debug_info[self.taskname]:
@@ -992,6 +1005,7 @@ class ModelverseKernel(object):
                 ("CD", [prev_frame, "returnvalue", returnvalue]),
                 ("DE", [old_returnvalue_link]),
                 ("DN", [task_frame])]
+        yield [("RETURN", [None])]
 
     def constant_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -1008,6 +1022,7 @@ class ModelverseKernel(object):
                                    ("DE", [returnvalue_link]),
                                    ("DE", [phase_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def helper_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -1048,6 +1063,7 @@ class ModelverseKernel(object):
                                    ("DE", [ip_link]),
                                    ("DE", [phase_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def call_init(self, task_root):
         task_frame, =       yield [("RD", [task_root, "frame"])]
@@ -1087,6 +1103,7 @@ class ModelverseKernel(object):
                                    ("DE", [evalstack_link]),
                                    ("DE", [ip_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def call_call(self, task_root):
         self.debug_info[self.taskname].append("None")
@@ -1160,6 +1177,7 @@ class ModelverseKernel(object):
                                    ("DE", [frame_link]),
                                    ("DE", [phase_link]),
                                   ]
+        yield [("RETURN", [None])]
 
     def find_overlapping(self, a, b):
         newer_frames = set(a)
@@ -1298,6 +1316,7 @@ class ModelverseKernel(object):
                                ("DE", [ip_link]),
                                ("DE", [evalstack_link]),
                               ]
+        yield [("RETURN", [None])]
 
     def input_init(self, task_root):
         task_frame, =   yield [("RD", [task_root, "frame"])]
@@ -1330,6 +1349,7 @@ class ModelverseKernel(object):
             self.input_value = None
             ex = primitive_functions.SleepKernel(0.1, True)
             raise ex
+        yield [("RETURN", [None])]
 
     def output_init(self, task_root):
         task_frame, =   yield [("RD", [task_root, "frame"])]
@@ -1353,6 +1373,7 @@ class ModelverseKernel(object):
                                ("DE", [evalstack_link]),
                                ("DE", [ip_link]),
                               ]
+        yield [("RETURN", [None])]
 
     def output_output(self, task_root):
         task_frame, =   yield [("RD", [task_root, "frame"])]
@@ -1373,6 +1394,7 @@ class ModelverseKernel(object):
                                ("DE", [last_output_link]),
                                ("DE", [phase_link]),
                               ]
+        yield [("RETURN", [None])]
 
     def declare_init(self, task_root):
         task_frame, =   yield [("RD", [task_root, "frame"])]
@@ -1393,6 +1415,7 @@ class ModelverseKernel(object):
         _, _ =          yield [("CD", [task_frame, "phase", new_phase]),
                                ("DE", [phase_link]),
                               ]
+        yield [("RETURN", [None])]
 
     def global_init(self, task_root):
         task_frame, =   yield [("RD", [task_root, "frame"])]
@@ -1416,3 +1439,4 @@ class ModelverseKernel(object):
         _, _ =          yield [("CD", [task_frame, "phase", new_phase]),
                                ("DE", [phase_link])
                               ]
+        yield [("RETURN", [None])]

+ 0 - 74
kernel/modelverse_kernel/primitives.py

@@ -2,12 +2,6 @@ import time as python_time
 import json
 import sys
 
-class PrimitiveFinished(Exception):
-    """Exception to indicate the result value of a primitive, as a return cannot be used."""
-    def __init__(self, value):
-        Exception.__init__(self)
-        self.result = value
-
 class InterpretedFunctionFinished(Exception):
     """Exception to indicate the result value of an interpreted function, as a return
        cannot be used."""
@@ -23,7 +17,6 @@ class SleepKernel(Exception):
         self.interruptable = interruptable
 
 # Functions annotated with __exception_return use the JIT's calling convention instead of
-# the kernel's: returns are handled by throwing a PrimitiveFinished exception; the caller's
 # returnvalue is not modified.
 #
 # ### Rationale for __exception_return
@@ -46,7 +39,6 @@ def integer_subtraction(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] - b['value']})
     yield [("RETURN", [{'value': a['value'] - b['value']}])]
 
 def integer_addition(a, b, **remainder):
@@ -54,7 +46,6 @@ def integer_addition(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] + b['value']})
     yield [("RETURN", [{'value': a['value'] + b['value']}])]
 
 def integer_multiplication(a, b, **remainder):
@@ -62,7 +53,6 @@ def integer_multiplication(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] * b['value']})
     yield [("RETURN", [{'value': a['value'] * b['value']}])]
 
 def integer_division(a, b, **remainder):
@@ -70,7 +60,6 @@ def integer_division(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': int(a['value']) // b['value']})
     yield [("RETURN", [{'value': int(a['value']) // b['value']}])]
 
 def integer_lt(a, b, **remainder):
@@ -78,7 +67,6 @@ def integer_lt(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] < b['value']})
     yield [("RETURN", [{'value': a['value'] < b['value']}])]
 
 def bool_and(a, b, **remainder):
@@ -86,7 +74,6 @@ def bool_and(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] and b['value']})
     yield [("RETURN", [{'value': a['value'] and b['value']}])]
 
 def bool_or(a, b, **remainder):
@@ -94,13 +81,11 @@ def bool_or(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] or b['value']})
     yield [("RETURN", [{'value': a['value'] or b['value']}])]
 
 def bool_not(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': not a['value']})
     yield [("RETURN", [{'value': not a['value']}])]
 
 def float_subtraction(a, b, **remainder):
@@ -108,7 +93,6 @@ def float_subtraction(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] - b['value']})
     yield [("RETURN", [{'value': a['value'] - b['value']}])]
 
 def float_addition(a, b, **remainder):
@@ -116,7 +100,6 @@ def float_addition(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] + b['value']})
     yield [("RETURN", [{'value': a['value'] + b['value']}])]
 
 def float_multiplication(a, b, **remainder):
@@ -124,7 +107,6 @@ def float_multiplication(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] * b['value']})
     yield [("RETURN", [{'value': a['value'] * b['value']}])]
 
 def float_division(a, b, **remainder):
@@ -132,7 +114,6 @@ def float_division(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': float(a['value']) / float(b['value'])})
     yield [("RETURN", [{'value': float(a['value']) / b['value']}])]
 
 def float_lt(a, b, **remainder):
@@ -140,7 +121,6 @@ def float_lt(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] < b['value']})
     yield [("RETURN", [{'value': a['value'] < b['value']}])]
 
 def string_join(a, b, **remainder):
@@ -148,7 +128,6 @@ def string_join(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': str(a['value']) + str(b['value'])})
     yield [("RETURN", [{'value': str(a['value']) + str(b['value'])}])]
 
 def string_split(a, b, **remainder):
@@ -161,7 +140,6 @@ def string_split(a, b, **remainder):
     elems = yield [("CN", [])] + [("CNV", [v]) for v in result]
     new_val = elems[0]
     yield [("CD", [new_val, i, v]) for i, v in enumerate(elems[1:])]
-    #raise PrimitiveFinished({'id': new_val})
     yield [("RETURN", [{'id': new_val}])]
 
 def string_get(a, b, **remainder):
@@ -169,13 +147,11 @@ def string_get(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'][b['value']]})
     yield [("RETURN", [{'value': a['value'][b['value']]}])]
 
 def string_len(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': len(a['value'])})
     yield [("RETURN", [{'value': len(a['value'])}])]
 
 def value_eq(a, b, **remainder):
@@ -183,7 +159,6 @@ def value_eq(a, b, **remainder):
         a['value'], = yield [("RV", [a['id']])]
     if 'value' not in b:
         b['value'], = yield [("RV", [b['id']])]
-    #raise PrimitiveFinished({'value': a['value'] == b['value']})
     yield [("RETURN", [{'value': a['value'] == b['value']}])]
 
 def element_eq(a, b, **remainder):
@@ -193,52 +168,43 @@ def element_eq(a, b, **remainder):
     if "id" not in b:
         #print("MATERIALIZING B element_eq")
         b['id'], = yield [("CNV", [b['value']])]
-    #raise PrimitiveFinished({'value': a['id'] == b['id']})
     yield [("RETURN", [{'value': a['id'] == b['id']}])]
 
 def cast_string(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
     if isinstance(a['value'], dict):
-        #raise PrimitiveFinished({'value': str(a['value']['value'])})
         yield [("RETURN", [{'value': str(a['value']['value'])}])]
     else:
-        #raise PrimitiveFinished({'value': str(a['value'])})
         yield [("RETURN", [{'value': str(a['value'])}])]
 
 def cast_float(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': float(a['value'])})
     yield [("RETURN", [{'value': float(a['value'])}])]
 
 def cast_boolean(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': bool(a['value'])})
     yield [("RETURN", [{'value': bool(a['value'])}])]
 
 def cast_integer(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': int(a['value'])})
     yield [("RETURN", [{'value': int(a['value'])}])]
 
 def cast_value(a, **remainder):
     if 'value' not in a:
         a['value'], = yield [("RV", [a['id']])]
     if isinstance(a['value'], dict):
-        #raise PrimitiveFinished({'value': str(a['value']['value'])})
         yield [("RETURN", [{'value': str(a['value']['value'])}])]
     else:
-        #raise PrimitiveFinished({'value': json.dumps(a['value'])})
         yield [("RETURN", [{'value': json.dumps(a['value'])}])]
 
 def cast_id(a, **remainder):
     if "id" not in a:
         #print("MATERIALIZING A cast_id")
         a['id'], = yield [("CNV", [a['value']])]
-    #raise PrimitiveFinished({'value': str(a['id'])})
     yield [("RETURN", [{'value': str(a['id'])}])]
 
 def dict_add_fast(a, b, c, **remainder):
@@ -250,7 +216,6 @@ def dict_add_fast(a, b, c, **remainder):
         c['id'], = yield [("CNV", [c['value']])]
 
     yield [("CD", [a['id'], b['value'], c['id']])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def dict_delete(a, b, **remainder):
@@ -265,7 +230,6 @@ def dict_delete(a, b, **remainder):
         print("Keys: " + str(keys))
         raise Exception()
     yield [("DE", [edge])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def dict_delete_node(a, b, **remainder):
@@ -273,98 +237,81 @@ def dict_delete_node(a, b, **remainder):
     if edge is None:
         print("Failed dict_delete_node!")
     yield [("DE", [edge])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def dict_read(a, b, **remainder):
     if "value" not in b:
         b['value'], = yield [("RV", [b['id']])]
     result, = yield [("RD", [a['id'], b['value']])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def dict_read_edge(a, b, **remainder):
     if "value" not in b:
         b['value'], = yield [("RV", [b['id']])]
     result, = yield [("RDE", [a['id'], b['value']])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def dict_read_node(a, b, **remainder):
     result, = yield [("RDN", [a['id'], b['id']])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def dict_in(a, b, **remainder):
     if "value" not in b:
         b['value'], = yield [("RV", [b['id']])]
     value, = yield [("RD", [a['id'], b['value']])]
-    #raise PrimitiveFinished({'value': value is not None})
     yield [("RETURN", [{'value': value is not None}])]
 
 def dict_in_node(a, b, **remainder):
     if "id" not in b:
         # Not even allocated the node, so it is certain not to be in the dictionary
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]
     value, = yield [("RDN", [a['id'], b['id']])]
-    #raise PrimitiveFinished({'value': value is not None})
     yield [("RETURN", [{'value': value is not None}])]
 
 def dict_keys(a, **remainder):
     keys, result = yield [("RDK", [a['id']]), ("CN", [])]
     edges = yield [("CE", [result, result]) for _ in keys]
     _ = yield [("CE", [edge, key]) for edge, key in zip(edges, keys)]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def is_physical_int(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
     try:
-        #raise PrimitiveFinished({'value': isinstance(a['value'], int) or isinstance(a['value'], long)})
         yield [("RETURN", [{'value': isinstance(a['value'], int) or isinstance(a['value'], long)}])]
     except NameError:
-        #raise PrimitiveFinished({'value': isinstance(a['value'], int)})
         yield [("RETURN", [{'value': isinstance(a['value'], int)}])]
 
 def is_physical_string(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
     try:
-        #raise PrimitiveFinished({'value': isinstance(a['value'], str) or isinstance(a['value'], unicode)})
         yield [("RETURN", [{'value': isinstance(a['value'], str) or isinstance(a['value'], unicode)}])]
     except NameError:
-        #raise PrimitiveFinished({'value': isinstance(a['value'], str)})
         yield [("RETURN", [{'value': isinstance(a['value'], str)}])]
 
 def is_physical_float(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': isinstance(a['value'], float)})
     yield [("RETURN", [{'value': isinstance(a['value'], float)}])]
 
 def is_physical_boolean(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': isinstance(a['value'], bool)})
     yield [("RETURN", [{'value': isinstance(a['value'], bool)}])]
 
 def is_physical_action(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': isinstance(a['value'], dict) and a['value']["value"] in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]})
     yield [("RETURN", [{'value': isinstance(a['value'], dict) and a['value']["value"] in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]}])]
 
 def is_physical_none(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': isinstance(a['value'], dict) and a['value']["value"] == "none"})
     yield [("RETURN", [{'value': isinstance(a['value'], dict) and a['value']["value"] == "none"}])]
 
 def create_node(**remainder):
     result, = yield [("CN", [])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def create_edge(a, b, **remainder):
@@ -375,20 +322,17 @@ def create_edge(a, b, **remainder):
         #print("MATERIALIZING B create_edge")
         b['id'], = yield [("CNV", [b['value']])]
     result, = yield [("CE", [a['id'], b['id']])]
-    #raise PrimitiveFinished({'id': result})
     yield [("RETURN", [{'id': result}])]
 
 def create_value(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
-    #raise PrimitiveFinished({'value': a['value']})
     yield [("RETURN", [{'value': a['value']}])]
 
 def read_nr_out(a, **remainder):
     if "id" not in a:
         a['id'], = yield [("CNV", [a['value']])]
     outgoing, = yield [("RO", [a['id']])]
-    #raise PrimitiveFinished({'value': len(outgoing)})
     yield [("RETURN", [{'value': len(outgoing)}])]
 
 def read_out(a, b, root, **remainder):
@@ -398,14 +342,12 @@ def read_out(a, b, root, **remainder):
         b['value'], = yield [("RV", [b['id']])]
 
     outgoing, = yield [("RO", [a['id']])]
-    #raise PrimitiveFinished({'id': sorted(outgoing)[b['value']] if len(outgoing) > b['value'] else root})
     yield [("RETURN", [{'id': sorted(outgoing)[b['value']] if len(outgoing) > b['value'] else root}])]
 
 def read_nr_in(a, **remainder):
     if "id" not in a:
         a['id'], = yield [("CNV", [a['value']])]
     incoming, = yield [("RI", [a['id']])]
-    #raise PrimitiveFinished({'value': len(incoming)})
     yield [("RETURN", [{'value': len(incoming)}])]
 
 def read_in(a, b, root, **remainder):
@@ -415,61 +357,49 @@ def read_in(a, b, root, **remainder):
         b['value'], = yield [("RV", [b['id']])]
 
     incoming, = yield [("RI", [a['id']])]
-    #raise PrimitiveFinished({'id': sorted(incoming)[b['value']] if len(incoming) > b['value'] else root})
     yield [("RETURN", [{'id': sorted(incoming)[b['value']] if len(incoming) > b['value'] else root}])]
 
 def read_edge_src(a, **remainder):
     result, = yield [("RE", [a['id']])]
-    #raise PrimitiveFinished({'id': result[0]})
     yield [("RETURN", [{'id': result[0]}])]
 
 def read_edge_dst(a, **remainder):
     result, = yield [("RE", [a['id']])]
-    #raise PrimitiveFinished({'id': result[1]})
     yield [("RETURN", [{'id': result[1]}])]
 
 def delete_element(a, **remainder):
     if "id" not in a:
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]
 
     edge, = yield [("RE", [a['id']])]
     if edge[0] is None:
         # Not an edge:
         yield [("DN", [a['id']])]
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]
     else:
         yield [("DE", [a['id']])]
-        #raise PrimitiveFinished({'value': True})
         yield [("RETURN", [{'value': True}])]
 
 def read_root(root, **remainder):
-    #raise PrimitiveFinished({'id': root})
     yield [("RETURN", [{'id': root}])]
 
 def is_edge(a, **remainder):
     if "id" not in a:
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]
 
     edge, = yield [("RE", [a['id']])]
-    #raise PrimitiveFinished({'value': edge[0] is not None})
     yield [("RETURN", [{'value': edge[0] is not None}])]
 
 def log(a, **remainder):
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
     print("== LOG == " + str(a['value']))
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def read_taskroot(task_root, **remainder):
-    #raise PrimitiveFinished({'id': task_root})
     yield [("RETURN", [{'id': task_root}])]
 
 def time(**remainder):
-    #raise PrimitiveFinished({'value': python_time.time()})
     yield [("RETURN", [{'value': python_time.time()}])]
 
 def hash(a, **remainder):
@@ -481,7 +411,6 @@ def hash(a, **remainder):
         value = hashlib.sha512(a['value']).hexdigest()
     except TypeError:
         value = hashlib.sha512(a['value'].encode()).hexdigest()
-    #raise PrimitiveFinished({'value': value})
     yield [("RETURN", [{'value': value}])]
 
 def __sleep(a, b, **remainder):
@@ -492,13 +421,10 @@ def __sleep(a, b, **remainder):
     timeout = a['value']
     interruptable = b['value']
     yield [("SLEEP", [timeout, interruptable])]
-    #raise PrimitiveFinished(a)
     yield [("RETURN", [a])]
 
 def is_error(a, **remainder):
     if a['id'] is None:
-        #raise PrimitiveFinished({'value': True})
         yield [("RETURN", [{'value': True}])]
     else:
-        #raise PrimitiveFinished({'value': False})
         yield [("RETURN", [{'value': False}])]

+ 20 - 17
kernel/modelverse_kernel/request_handler.py

@@ -6,10 +6,11 @@ from collections import defaultdict
 class RequestHandler(object):
     def __init__(self):
         self.generator_stack = []
-        self.handlers = {"CALL": lambda i: i[0],
-                         "CALL_ARGS": lambda i: i[0](*(i[1])),
-                         "CALL_KWARGS": lambda i: i[0](**(i[1])),
+        self.handlers = {"CALL": self.execute_call,
+                         "CALL_ARGS": self.execute_call_args,
+                         "CALL_KWARGS": self.execute_call_kwargs,
                          "RETURN": self.execute_return,
+                         "FINISH": self.execute_finish,
                          "SLEEP": self.execute_sleep}
 
     def push_generator(self, gen):
@@ -23,34 +24,36 @@ class RequestHandler(object):
 
                 # Generated new request, so process
                 if requests and requests[0][0] in self.handlers:
-                    self.generator_stack.append(None)
                     # This next command potentially raises a finished message already, meaning that we should stop already
                     # We avoid an extra try/except block by putting the None on the stack already
                     self.reply = None
-                    self.generator_stack[-1] = self.handlers[requests[0][0]](requests[0][1])
+                    self.handlers[requests[0][0]](requests[0][1])
                 else:
                     # MvS request, so forward that instead
                     return requests
 
             except StopIteration:
                 # Exception, so finished execution of this generator, passing on None to the caller
+                #print("STOP for " + str(self.generator_stack))
                 del self.generator_stack[-1]
                 self.reply = [None]
                 
-            except primitive_functions.SleepKernel:
-                # Processing sleep, so pop its generator and reraise
-                del self.generator_stack[-1]
-                raise
-
-            except primitive_functions.PrimitiveFinished as ex:
-                # Exception, so finished execution of this generator, passing on ex.result to the caller
-                del self.generator_stack[-1]
-                self.reply = [ex.result]
-
+    def execute_finish(self, request_args):
+        del self.generator_stack[-1]
+        self.reply = [None]
+        
     def execute_sleep(self, request_args):
         raise primitive_functions.SleepKernel(request_args[0], request_args[1])
 
     def execute_return(self, request_args):
-        del self.generator_stack[-2:]
+        del self.generator_stack[-1]
         self.reply = [request_args[0]]
-        return self.generator_stack[-1]
+
+    def execute_call(self, request_args):
+        self.generator_stack.append(request_args[0])
+
+    def execute_call_args(self, request_args):
+        self.generator_stack.append(request_args[0](*(request_args[1])))
+
+    def execute_call_kwargs(self, request_args):
+        self.generator_stack.append(request_args[0](**(request_args[1])))

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Wed May  2 10:11:54 2018
+Date:   Wed May  2 11:10:29 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server