Przeglądaj źródła

Framework with expansion of dependent function calls

Yentl Van Tendeloo 7 lat temu
rodzic
commit
9e907be1f7
2 zmienionych plików z 68 dodań i 45 usunięć
  1. 67 40
      kernel/modelverse_kernel/main.py
  2. 1 5
      wrappers/modelverse_SCCD.py

+ 67 - 40
kernel/modelverse_kernel/main.py

@@ -15,6 +15,9 @@ else:
     string_types = (str, unicode)
 
 class ModelverseKernel(object):
+    
+    counter = 0
+
     def __init__(self, root):
         self.root = root
         self.returnvalue = None
@@ -184,32 +187,35 @@ class ModelverseKernel(object):
                 getattr(source, function_names[i]),
                 function_names[i])
 
-    def print_instruction(self, inst, indent=0):
+    def print_instruction(self, inst, indent, nested_indent=None):
+        """
         intrinsics = {"integer_addition": (lambda x, y: "(%s + %s)" % (x, y)),
-                      #"string_join": (lambda x, y: "(str(%s) + str(%s))" % (x, y)),
-                      #"dict_read": (lambda x, y: "(%s[%s])" % (x, y)),
-                      #"dict_overwrite": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)),
-                      #"dict_add_fast": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)),
-                      #"dict_add_fast": (lambda x, y, z: "(%s[%s] = %s)" % (x, y, z)),
+                      "string_join": (lambda x, y: "(str(%s) + str(%s))" % (x, y)),
                       }
+        """
+        intrinsics = {}
+
+        if nested_indent is None:
+            nested_indent = indent
 
         inst_type, = yield [("RV", [inst])]
         instruction = "(no_printer_for_%s)" % inst_type["value"]
+        prev = ""
 
         if inst_type["value"] == "if":
             cond, true, false = yield [("RD", [inst, "cond"]),
                                        ("RD", [inst, "then"]),
                                        ("RD", [inst, "else"])]
-            cond, = yield [("CALL_ARGS", [self.print_instruction, (cond, 0)])]
-            true, = yield [("CALL_ARGS", [self.print_instruction, (true, indent+1)])]
+            (prev_cond, instruction_cond), = yield [("CALL_ARGS", [self.print_instruction, (cond, 0, indent+1)])]
+            (prev_true, instruction_true), = yield [("CALL_ARGS", [self.print_instruction, (true, indent+1)])]
             if false:
-                false, = yield [("CALL_ARGS", [self.print_instruction, (false, indent+1)])]
-                false = ("  " * indent + "else:\n%s\n") % false
+                (prev_false, instruction_false), = yield [("CALL_ARGS", [self.print_instruction, (false, indent+1)])]
+                false = ("  " * indent + "else:\n%s%s\n") % (prev_false, instruction_false)
             else:
                 false = ""
 
-            instruction = "  " * indent + "if (" + cond + "):\n" + true + "\n" + false
-            #TODO fix for inline calls
+            instruction = prev_cond + "  " * indent + "if (" + instruction_cond + "):\n" + prev_true + instruction_true + "\n" + false
+
         elif inst_type["value"] == "constant":
             node, = yield [("RD", [inst, "node"])]
             node, = yield [("RV", [node])]
@@ -217,16 +223,18 @@ class ModelverseKernel(object):
                 instruction = "  " * indent + '"%s"' % node
             else:
                 instruction = "  " * indent + str(node)
+
         elif inst_type["value"] == "return":
             value, = yield [("RD", [inst, "value"])]
             if value:
-                value, = yield [("CALL_ARGS", [self.print_instruction, (value, 0)])]
-                instruction = "  " * indent + "return %s\n" % value
+                (prev_value, instruction_value), = yield [("CALL_ARGS", [self.print_instruction, (value, 0, indent)])]
+                instruction = prev_value + "  " * indent + "return %s\n" % value
             else:
                 instruction = "  " * indent + "return\n"
-            #TODO fix for inline calls
+
         elif inst_type["value"] == "declare":
             instruction = ""
+
         elif inst_type["value"] == "resolve":
             value, = yield [("RD", [inst, "var"])]
             str_value, = yield [("RV", [value])]
@@ -234,56 +242,75 @@ class ModelverseKernel(object):
                 instruction = str_value
             else:
                 instruction = "var_%s" % value
+
         elif inst_type["value"] == "assign":
             var, val = yield [("RD", [inst, "var"]),
                               ("RD", [inst, "value"])]
-            var, val = yield [("CALL_ARGS", [self.print_instruction, (var, 0)]),
-                              ("CALL_ARGS", [self.print_instruction, (val, 0)])]
-            instruction = "  " * indent + var + " = " + val + "\n"
-            #TODO fix for inline calls
+            (prev_var, instruction_var), (prev_val, instruction_val) = \
+                        yield [("CALL_ARGS", [self.print_instruction, (var, 0, indent)]),
+                               ("CALL_ARGS", [self.print_instruction, (val, 0, indent)])]
+            instruction = prev_val + "  " * indent + instruction_var + " = " + instruction_val + "\n"
+
         elif inst_type["value"] == "call":
             func_name, = yield [("RD", [inst, "func"])]
-            func_name, = yield [("CALL_ARGS", [self.print_instruction, (func_name, 0)])]
+            (prev_func_name, func_name), = yield [("CALL_ARGS", [self.print_instruction, (func_name, 0, nested_indent)])]
+            print("Visit call to " + str(func_name) + " with indents: (%s,%s)" % (indent, nested_indent))
             param_list = []
 
             param, = yield [("RD", [inst, "params"])]
+            computation = ""
             while param:
                 value, = yield [("RD", [param, "value"])]
-                res, param = yield [("CALL_ARGS", [self.print_instruction, (value, 0)]),
-                                    ("RD", [param, "next_param"])]
-                param_list.append(res)
+                (prev_res, instruction_res), param = \
+                        yield [("CALL_ARGS", [self.print_instruction, (value, 0, nested_indent)]),
+                               ("RD", [param, "next_param"])]
+                computation += prev_res
+                param_list.append(instruction_res)
 
             if func_name in intrinsics:
-                instruction = "  " * indent + intrinsics[func_name](*param_list)
+                #instruction = "  " * indent + intrinsics[func_name](*param_list)
+                # TODO
+                pass
             else:
-                instruction = "  " * indent + func_name + "(" + ", ".join(param_list) + ")"
-                """
+                value = "func_result_" + str(ModelverseKernel.counter)
+                ModelverseKernel.counter += 1
+                if len(param_list) == 1:
+                    actual_computation = "%s, = yield [('CALL_ARGS', [%s, (%s,)])]\n" % (value, func_name, param_list[0])
+                else:
+                    actual_computation = "%s, = yield [('CALL_ARGS', [%s, (%s)])]\n" % (value, func_name, ", ".join(param_list))
+
                 if indent == 0:
-                    #TODO fix for inline calls
-                    instruction = 'result, = yield [("CALL_ARGS", (%s, (' % func_name + ",".join(param_list) + ',)))]'
+                    # No indent, meaning that we use it inline
+                    # Therefore, we output the prev and value individually
+                    prev, instruction = computation + "  " * nested_indent + actual_computation, value
                 else:
-                    instruction = "  " * indent + 'yield [("CALL_ARGS", (%s, (' % func_name + ",".join(param_list) + ',)))]'
-                """
-            if indent:
-                instruction += "\n"
+                    # Some indentation, meaning that we don't even use the return value
+                    # Therefore, we only do the yield
+                    prev, instruction = computation, "  " * indent + actual_computation
+
         elif inst_type["value"] == "access":
             value, = yield [("RD", [inst, "var"])]
-            instruction, = yield [("CALL_ARGS", [self.print_instruction, (value, 0)])]
+            (prev_instruction, instruction), = yield [("CALL_ARGS", [self.print_instruction, (value, 0, indent)])]
+
         elif inst_type["value"] == "while":
             cond, body = yield [("RD", [inst, "cond"]),
                                 ("RD", [inst, "body"])]
-            cond, body = yield [("CALL_ARGS", [self.print_instruction, (cond, 0)]),
-                                ("CALL_ARGS", [self.print_instruction, (body, indent+1)])]
-            instruction = "  " * indent + "while (%s):\n" % cond + body
-            #TODO fix for inline calls
+            (prev_cond, instruction_cond), (prev_body, instruction_body) = \
+                        yield [("CALL_ARGS", [self.print_instruction, (cond, indent+1)]),
+                               ("CALL_ARGS", [self.print_instruction, (body, indent+1)])]
+            instruction = "  " * indent + "while 1:\n" + prev_cond + \
+                          "  " * (indent + 1) + "if not (" + instruction_cond + "):\n" + \
+                          "  " * (indent + 2) + "break\n" + \
+                          prev_body + instruction_body
 
         next_inst, = yield [("RD", [inst, "next"])]
         if next_inst:
-            next_inst, = yield [("CALL_ARGS", [self.print_instruction, (next_inst, indent)])]
+            (prev_next, inst_next), = yield [("CALL_ARGS", [self.print_instruction, (next_inst, indent)])]
+            next_inst = prev_next + inst_next
         else:
             next_inst = ""
 
-        raise primitive_functions.PrimitiveFinished(instruction + next_inst)
+        raise primitive_functions.PrimitiveFinished((prev, instruction + next_inst))
 
     def read_function(self, inst):
         initial_instruction = inst
@@ -295,7 +322,7 @@ class ModelverseKernel(object):
             raise jit.JitCompilationFailedException("FAIL")
 
         print("Reading function: %s" % suggested_name)
-        printed, = yield [("CALL_ARGS", [self.print_instruction, (inst, 1)])]
+        (_, printed), = yield [("CALL_ARGS", [self.print_instruction, (inst, 1)])]
         print("Total printed function: ")
         func = "def " + suggested_name + "(" + ",".join(["var_%s" % param for param in params]) + "):\n" + printed
         print(func)

+ 1 - 5
wrappers/modelverse_SCCD.py

@@ -1,11 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-<<<<<<< HEAD
-Date:   Wed Mar 28 08:08:55 2018
-=======
-Date:   Thu Apr  5 09:43:06 2018
->>>>>>> testing
+Date:   Thu Apr  5 11:43:13 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server