Prechádzať zdrojové kódy

Define a SwitchInstruction type in tree_ir

This type of instruction can be used when lots of cases may be generated.
When that happens, constructing a long chain of if-else statements is
not a good idea as generating code from them might cause us to run into
the max recursion limit.
jonathanvdc 8 rokov pred
rodič
commit
6be7383e26
1 zmenil súbory, kde vykonal 46 pridanie a 0 odobranie
  1. 46 0
      kernel/modelverse_jit/tree_ir.py

+ 46 - 0
kernel/modelverse_jit/tree_ir.py

@@ -366,6 +366,52 @@ class SelectInstruction(Instruction):
     def __repr__(self):
         return "SelectInstruction(%r, %r, %r)" % (self.condition, self.if_clause, self.else_clause)
 
+class SwitchInstruction(VoidInstruction):
+    """An instruction that evaluates an instruction based on which condition matches."""
+    def __init__(self, conditions_and_clauses):
+        VoidInstruction.__init__(self)
+        self.conditions_and_clauses = conditions_and_clauses
+        assert not any([cond.has_definition() for cond, _ in self.conditions_and_clauses])
+
+    def simplify_node(self):
+        """Applies basic simplification to this instruction only."""
+        if len(self.conditions_and_clauses) == 0:
+            return EmptyInstruction()
+        elif len(self.conditions_and_clauses) == 1:
+            cond, clause = next(iter(self.conditions_and_clauses))
+            return SelectInstruction(cond, IgnoreInstruction(clause), EmptyInstruction())
+        else:
+            return self
+
+    def get_children(self):
+        """Gets this instruction's sequence of child instructions."""
+        results = []
+        for cond, body in self.conditions_and_clauses:
+            results.append(cond)
+            results.append(body)
+        return results
+
+    def create(self, new_children):
+        """Creates a new instruction of this type from the given sequence of child instructions."""
+        new_pairs = []
+        for i in xrange(len(self.conditions_and_clauses)):
+            new_pairs.append((new_children[2 * i], new_children[2 * i + 1]))
+        return SwitchInstruction(new_pairs)
+
+    def generate_python_def(self, code_generator):
+        """Generates Python code for this instruction."""
+        if_keyword = 'if '
+        for condition, clause in self.conditions_and_clauses:
+            code_generator.append_line(
+                if_keyword + condition.generate_python_use(code_generator) + ':')
+            code_generator.increase_indentation()
+            clause.generate_python_def(code_generator)
+            code_generator.decrease_indentation()
+            if_keyword = 'elif '
+
+    def __repr__(self):
+        return "SwitchInstruction(%r)" % self.conditions_and_clauses
+
 class ReturnInstruction(VoidInstruction):
     """Represents a return-instruction."""
     def __init__(self, value):