Просмотр исходного кода

Framework with expansion of dependent function calls

Yentl Van Tendeloo 7 лет назад
Родитель
Сommit
9e907be1f7
2 измененных файлов с 68 добавлено и 45 удалено
  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)
     string_types = (str, unicode)
 
 
 class ModelverseKernel(object):
 class ModelverseKernel(object):
+    
+    counter = 0
+
     def __init__(self, root):
     def __init__(self, root):
         self.root = root
         self.root = root
         self.returnvalue = None
         self.returnvalue = None
@@ -184,32 +187,35 @@ class ModelverseKernel(object):
                 getattr(source, function_names[i]),
                 getattr(source, function_names[i]),
                 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)),
         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])]
         inst_type, = yield [("RV", [inst])]
         instruction = "(no_printer_for_%s)" % inst_type["value"]
         instruction = "(no_printer_for_%s)" % inst_type["value"]
+        prev = ""
 
 
         if inst_type["value"] == "if":
         if inst_type["value"] == "if":
             cond, true, false = yield [("RD", [inst, "cond"]),
             cond, true, false = yield [("RD", [inst, "cond"]),
                                        ("RD", [inst, "then"]),
                                        ("RD", [inst, "then"]),
                                        ("RD", [inst, "else"])]
                                        ("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:
             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:
             else:
                 false = ""
                 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":
         elif inst_type["value"] == "constant":
             node, = yield [("RD", [inst, "node"])]
             node, = yield [("RD", [inst, "node"])]
             node, = yield [("RV", [node])]
             node, = yield [("RV", [node])]
@@ -217,16 +223,18 @@ class ModelverseKernel(object):
                 instruction = "  " * indent + '"%s"' % node
                 instruction = "  " * indent + '"%s"' % node
             else:
             else:
                 instruction = "  " * indent + str(node)
                 instruction = "  " * indent + str(node)
+
         elif inst_type["value"] == "return":
         elif inst_type["value"] == "return":
             value, = yield [("RD", [inst, "value"])]
             value, = yield [("RD", [inst, "value"])]
             if 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:
             else:
                 instruction = "  " * indent + "return\n"
                 instruction = "  " * indent + "return\n"
-            #TODO fix for inline calls
+
         elif inst_type["value"] == "declare":
         elif inst_type["value"] == "declare":
             instruction = ""
             instruction = ""
+
         elif inst_type["value"] == "resolve":
         elif inst_type["value"] == "resolve":
             value, = yield [("RD", [inst, "var"])]
             value, = yield [("RD", [inst, "var"])]
             str_value, = yield [("RV", [value])]
             str_value, = yield [("RV", [value])]
@@ -234,56 +242,75 @@ class ModelverseKernel(object):
                 instruction = str_value
                 instruction = str_value
             else:
             else:
                 instruction = "var_%s" % value
                 instruction = "var_%s" % value
+
         elif inst_type["value"] == "assign":
         elif inst_type["value"] == "assign":
             var, val = yield [("RD", [inst, "var"]),
             var, val = yield [("RD", [inst, "var"]),
                               ("RD", [inst, "value"])]
                               ("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":
         elif inst_type["value"] == "call":
             func_name, = yield [("RD", [inst, "func"])]
             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_list = []
 
 
             param, = yield [("RD", [inst, "params"])]
             param, = yield [("RD", [inst, "params"])]
+            computation = ""
             while param:
             while param:
                 value, = yield [("RD", [param, "value"])]
                 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:
             if func_name in intrinsics:
-                instruction = "  " * indent + intrinsics[func_name](*param_list)
+                #instruction = "  " * indent + intrinsics[func_name](*param_list)
+                # TODO
+                pass
             else:
             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:
                 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:
                 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":
         elif inst_type["value"] == "access":
             value, = yield [("RD", [inst, "var"])]
             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":
         elif inst_type["value"] == "while":
             cond, body = yield [("RD", [inst, "cond"]),
             cond, body = yield [("RD", [inst, "cond"]),
                                 ("RD", [inst, "body"])]
                                 ("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"])]
         next_inst, = yield [("RD", [inst, "next"])]
         if next_inst:
         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:
         else:
             next_inst = ""
             next_inst = ""
 
 
-        raise primitive_functions.PrimitiveFinished(instruction + next_inst)
+        raise primitive_functions.PrimitiveFinished((prev, instruction + next_inst))
 
 
     def read_function(self, inst):
     def read_function(self, inst):
         initial_instruction = inst
         initial_instruction = inst
@@ -295,7 +322,7 @@ class ModelverseKernel(object):
             raise jit.JitCompilationFailedException("FAIL")
             raise jit.JitCompilationFailedException("FAIL")
 
 
         print("Reading function: %s" % suggested_name)
         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: ")
         print("Total printed function: ")
         func = "def " + suggested_name + "(" + ",".join(["var_%s" % param for param in params]) + "):\n" + printed
         func = "def " + suggested_name + "(" + ",".join(["var_%s" % param for param in params]) + "):\n" + printed
         print(func)
         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)
 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 author: Yentl Van Tendeloo
 Model name:   MvK Server
 Model name:   MvK Server