Commit e16c66a0 authored by Fabian Kosmale's avatar Fabian Kosmale
Browse files

avoid even more global state

parent 16ba970c
......@@ -89,11 +89,15 @@ class UnaryOperator(Enum):
Not = "!"
class ReplacementCounter(): # pylint: disable=too-few-public-methods
"""A mutable int..."""
def __init__(self, count):
self.count = count
class BaseExpression(ASTNode, metaclass=abc.ABCMeta):
"""Base class for expressions in TinyPseuCo"""
_replacement_counter = 0
def __init__(self):
super().__init__()
self.read_global_variables: typing.List[str] = []
......@@ -103,15 +107,15 @@ class BaseExpression(ASTNode, metaclass=abc.ABCMeta):
def pseuco_type(self) -> PseuCoType:
"""Computes the type of an expression"""
def extract_global_read(self, tt: "TypeTable"):
def extract_global_read(self, tt: "TypeTable", replacement_counter: ReplacementCounter):
"""Replaces global reads with local ones by extracting the global reads
into temporary variables"""
extracted = []
replacements: DefaultDict[str, Deque[str]] = defaultdict(deque)
for variable in self.read_global_variables:
var_type = tt.lookup_type(variable)
new_variable = "$%d" % BaseExpression._replacement_counter
BaseExpression._replacement_counter += 1
new_variable = "$%d" % replacement_counter.count
replacement_counter.count += 1
replacements[variable].append(new_variable)
new_decl = VariableDeclaration(
None,
......@@ -366,7 +370,7 @@ class Statement(ASTNode, metaclass=abc.ABCMeta):
return [self]
@abc.abstractmethod
def simplify(self, tt: "TypeTable") -> List["Statement"]:
def simplify(self, tt: "TypeTable", replacement_counter: ReplacementCounter) -> List["Statement"]:
"""Converts a TinyPseuCo statement into a μPseuCo one"""
@abc.abstractmethod
......@@ -391,7 +395,7 @@ class EmptyStatement(Statement):
def __repr__(self):
return ";"
def simplify(self, tt):
def simplify(self, tt, replacement_counter):
return [self]
def get_cfg_exit_nodes(self): # pylint: disable=useless-super-delegation
......@@ -417,9 +421,9 @@ class SimpleStatement(Statement):
def create_node_data(self, cfg_predecessors): # pylint: disable=useless-super-delegation
return super().create_node_data(cfg_predecessors)
def simplify(self, tt):
reads, replacements = self.expression.extract_global_read(tt)
self.expression.replace_globals(replacements)
def simplify(self, tt, replacement_counter):
reads, replacements = self.expression.extract_global_read(tt, replacement_counter)
self.expression.replace_globals(replacements, replacement_counter)
reads.append(self)
return reads
......@@ -430,8 +434,8 @@ class MultiStatement(Statement):
super().__init__()
self.statements = tokens
def simplify(self, tt):
simplified = (statement.simplify(tt) for statement in self.statements)
def simplify(self, tt, replacement_counter):
simplified = (statement.simplify(tt, replacement_counter) for statement in self.statements)
return [MultiStatement(list(itertools.chain.from_iterable(simplified)))]
def _set_id(self, id_):
......@@ -465,8 +469,9 @@ class SimpleAgent(ASTNode):
self.agentName, functionBody, *empty = tokens
self.local_environment = type_table.close_fresh_environment()
statements = []
replacement_counter = ReplacementCounter(0)
for statement in functionBody.statements:
statements.extend(statement.simplify(type_table))
statements.extend(statement.simplify(type_table, replacement_counter))
id_ = 0
for statement in statements:
id_ = statement._set_id(id_)
......@@ -520,17 +525,17 @@ class ITE(Statement):
ret += " else {{ \n {} \n }}".format(self.alternative)
return ret
def simplify(self, tt):
assignments, replacements = self.condition.extract_global_read(tt)
def simplify(self, tt, replacement_counter):
assignments, replacements = self.condition.extract_global_read(tt, replacement_counter)
self.condition.replace_globals(replacements)
consequence = self.consequence.simplify(tt)
consequence = self.consequence.simplify(tt, replacement_counter)
assert consequence
if len(consequence) > 1:
self.consequence = MultiStatement(consequence)
else:
self.consequence = consequence[0]
if self.alternative:
alternative = self.alternative.simplify(tt)
alternative = self.alternative.simplify(tt, replacement_counter)
if len(alternative) > 1:
self.alternative = MultiStatement(alternative)
else:
......@@ -577,7 +582,7 @@ class PrintlnStatement(Statement):
def create_node_data(self, cfg_predecessors): # pylint: disable=useless-super-delegation
return super().create_node_data(cfg_predecessors)
def simplify(self, tt):
def simplify(self, tt, replacement_counter):
if len(self.expressions) > 1:
raise NotImplementedError("simplify println")
else:
......@@ -648,12 +653,12 @@ class VariableDeclaration(Statement):
"global_read_{}".format(self.initial_value.read_global_variables[0])
]
def simplify(self, tt):
def simplify(self, tt, replacement_counter):
if isinstance(self.initial_value, VariableUsage):
# do not attempt to simplfy expression when it already is a simple
# read of a global
return [self]
reads, replacements = self.initial_value.extract_global_read(tt)
reads, replacements = self.initial_value.extract_global_read(tt, replacement_counter)
self.initial_value.replace_globals(replacements)
reads.append(self)
return reads
......@@ -687,8 +692,8 @@ class VariableAssignment(Statement):
s, l,
"local variable {} must be constant!".format(self.var_name))
def simplify(self, tt):
reads, replacements = self.assignment_expression.extract_global_read(tt)
def simplify(self, tt, replacement_counter):
reads, replacements = self.assignment_expression.extract_global_read(tt, replacement_counter)
self.assignment_expression.replace_globals(replacements)
reads.append(self)
return reads
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment