|
@@ -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())
|