Browse Source

Define LiteralInstruction, Instruction.has_definition

jonathanvdc 8 years ago
parent
commit
16fd903ba6
1 changed files with 49 additions and 25 deletions
  1. 49 25
      kernel/modelverse_jit/ir.py

+ 49 - 25
kernel/modelverse_jit/ir.py

@@ -8,14 +8,20 @@ class Instruction(object):
 
     def has_result(self):
         """Tells if this instruction computes a result."""
+        return True
 
+    def has_definition(self):
+        """Tells if this instruction requires a definition."""
         return True
 
     def generate_python_def(self, code_generator):
         """Generates a Python statement that executes this instruction.
            The statement is appended immediately to the code generator."""
 
-        raise NotImplementedError
+        if self.has_definition():
+            raise NotImplementedError
+        else:
+            code_generator.append_line('pass')
 
     def generate_python_use(self, code_generator):
         """Generates a Python expression that retrieves this instruction's
@@ -95,14 +101,14 @@ class VoidInstruction(Instruction):
 
     def has_result(self):
         """Tells if this instruction computes a result."""
-
         return False
 
 class EmptyInstruction(VoidInstruction):
     """Represents the empty instruction, which does nothing."""
 
-    def generate_python_def(self, code_generator):
-        code_generator.append_line('pass')
+    def has_definition(self):
+        """Tells if this instruction requires a definition."""
+        return False
 
 class SelectInstruction(Instruction):
     """Represents a select-instruction: an instruction that defines one of two
@@ -116,22 +122,22 @@ class SelectInstruction(Instruction):
 
     def has_result(self):
         """Tells if this instruction computes a result."""
-
         return self.if_clause.has_result() or self.else_clause.has_result()
 
     def simplify(self):
         """Applies basic simplification to this instruction and its children."""
-
         simple_cond = self.condition.simplify()
         simple_if = self.if_clause.simplify()
         simple_else = self.else_clause.simplify()
-        return SelectInstruction(simple_cond, simple_if, simple_else)
+        if isinstance(simple_cond, LiteralInstruction):
+            return simple_if if simple_cond.literal else simple_else
+        else:
+            return SelectInstruction(simple_cond, simple_if, simple_else)
 
     def generate_python_def(self, code_generator):
         """Generates Python code for this instruction."""
-
         if_has_result = self.has_result()
-        if not isinstance(self.condition, EmptyInstruction):
+        if self.condition.has_definition():
             self.condition.generate_python_def(code_generator)
 
         code_generator.append_line(
@@ -141,7 +147,7 @@ class SelectInstruction(Instruction):
         if if_has_result:
             code_generator.append_definition(self, self.if_clause)
         code_generator.decrease_indentation()
-        if not isinstance(self.else_clause, EmptyInstruction) or if_has_result:
+        if self.else_clause.has_definition() or if_has_result:
             code_generator.append_line('else:')
             code_generator.increase_indentation()
             self.else_clause.generate_python_def(code_generator)
@@ -205,46 +211,64 @@ class ContinueInstruction(VoidInstruction):
 
         code_generator.append_line('continue')
 
-class CompoundInstruction(VoidInstruction):
+class CompoundInstruction(Instruction):
     """Represents an instruction that evaluates two other instructions
-       in order."""
+       in order, and returns the second instruction's result."""
 
     def __init__(self, first, second):
         Instruction.__init__(self)
         self.first = first
         self.second = second
 
+    def has_result(self):
+        """Tells if this instruction has a result."""
+        return self.second.has_result()
+
     def simplify(self):
         """Applies basic simplification to this instruction and its children."""
 
         simple_fst, simple_snd = self.first.simplify(), self.second.simplify()
-        if isinstance(simple_snd, EmptyInstruction):
-            return simple_fst
-        elif isinstance(simple_snd, EmptyInstruction):
+        if not simple_fst.has_definition():
             return simple_snd
+        elif (not simple_snd.has_definition()) and (not simple_snd.has_result()):
+            return simple_fst
         else:
             return CompoundInstruction(simple_fst, simple_snd)
 
     def generate_python_def(self, code_generator):
         """Generates Python code for this instruction."""
+        self.first.generate_python_def(code_generator)
+        self.second.generate_python_def(code_generator)
+        if self.has_result():
+            code_generator.append_definition(self, self.second)
 
-        if isinstance(self.second, EmptyInstruction):
-            self.first.generate_python_def(code_generator)
-        elif isinstance(self.first, EmptyInstruction):
-            self.second.generate_python_def(code_generator)
-        else:
-            self.first.generate_python_def(code_generator)
-            self.second.generate_python_def(code_generator)
+class LiteralInstruction(Instruction):
+    """Represents an integer, floating-point, string or Boolean literal."""
+    def __init__(self, literal):
+        Instruction.__init__(self)
+        self.literal = literal
+
+    def has_definition(self):
+        """Tells if this instruction requires a definition."""
+        return False
+
+    def generate_python_use(self, code_generator):
+        """Generates a Python expression that retrieves this instruction's
+           result. The expression is returned as a string."""
+        return repr(self.literal)
 
 if __name__ == "__main__":
     exampleTree = SelectInstruction(
-        EmptyInstruction(),
+        LiteralInstruction(True),
         LoopInstruction(
             CompoundInstruction(
                 BreakInstruction(),
-                ContinueInstruction()
+                CompoundInstruction(
+                    EmptyInstruction(),
+                    ContinueInstruction()
+                )
             )
         ),
         ReturnInstruction(
             EmptyInstruction()))
-    print(exampleTree)
+    print(exampleTree.simplify())