1.1 --- a/results.py Tue Feb 28 00:00:09 2017 +0100
1.2 +++ b/results.py Tue Feb 28 17:00:26 2017 +0100
1.3 @@ -45,6 +45,9 @@
1.4 def context_identity(self):
1.5 return None
1.6
1.7 + def discards_temporary(self, test=True):
1.8 + return None
1.9 +
1.10 def get_name(self):
1.11 return None
1.12
2.1 --- a/tests/logical_simple.py Tue Feb 28 00:00:09 2017 +0100
2.2 +++ b/tests/logical_simple.py Tue Feb 28 17:00:26 2017 +0100
2.3 @@ -9,20 +9,44 @@
2.4 e = not a
2.5 print e # False
2.6
2.7 +f = 0
2.8 +
2.9 if a and b:
2.10 print "a and b" # a and b
2.11 +else:
2.12 + print "! (a and b)"
2.13 +
2.14 +if a and f:
2.15 + print "a and f"
2.16 +else:
2.17 + print "! (a and f)" # ! (a and f)
2.18
2.19 if not (a and b):
2.20 - print "not (a and b)" #
2.21 + print "not (a and b)"
2.22 +else:
2.23 + print "! (not (a and b))" # ! (not (a and b))
2.24
2.25 if not not (a and b):
2.26 print "not not (a and b)" # not not (a and b)
2.27 +else:
2.28 + print "! (not not (a and b))"
2.29
2.30 if a or b:
2.31 print "a or b" # a or b
2.32 +else:
2.33 + print "! (a or b)"
2.34
2.35 if not (a or b):
2.36 - print "not (a or b)" #
2.37 + print "not (a or b)"
2.38 +else:
2.39 + print "! (not (a or b))" # ! (not (a or b))
2.40
2.41 if not not (a or b):
2.42 print "not not (a or b)" # not not (a or b)
2.43 +else:
2.44 + print "! (not not (a or b))"
2.45 +
2.46 +if a and b or f:
2.47 + print "a and b or f" # a and b or f
2.48 +else:
2.49 + print "! (a and b or f)"
3.1 --- a/translator.py Tue Feb 28 00:00:09 2017 +0100
3.2 +++ b/translator.py Tue Feb 28 17:00:26 2017 +0100
3.3 @@ -1627,6 +1627,18 @@
3.4
3.5 # Special variable usage.
3.6
3.7 + def get_temp_path(self):
3.8 +
3.9 + """
3.10 + Return the appropriate namespace path for temporary names in the current
3.11 + namespace.
3.12 + """
3.13 +
3.14 + if self.in_function:
3.15 + return self.get_namespace_path()
3.16 + else:
3.17 + return self.name
3.18 +
3.19 def record_temp(self, name):
3.20
3.21 """
3.22 @@ -1636,13 +1648,23 @@
3.23 program.
3.24 """
3.25
3.26 - if self.in_function:
3.27 - path = self.get_namespace_path()
3.28 - else:
3.29 - path = self.name
3.30 -
3.31 - init_item(self.temp_usage, path, set)
3.32 - self.temp_usage[path].add(name)
3.33 + path = self.get_temp_path()
3.34 +
3.35 + init_item(self.temp_usage, path, list)
3.36 + self.temp_usage[path].append(name)
3.37 +
3.38 + def remove_temps(self, names):
3.39 +
3.40 + """
3.41 + Remove 'names' from temporary storage allocations, each instance
3.42 + removing each request for storage.
3.43 + """
3.44 +
3.45 + path = self.get_temp_path()
3.46 +
3.47 + for name in names:
3.48 + if self.uses_temp(path, name):
3.49 + self.temp_usage[path].remove(name)
3.50
3.51 def uses_temp(self, path, name):
3.52
3.53 @@ -1816,6 +1838,9 @@
3.54
3.55 if isinstance(test_ref, LogicalResult):
3.56 self.writeline("%s %s" % (statement, test_ref.apply_test()))
3.57 + temps = test_ref.discards_temporary()
3.58 + if temps:
3.59 + self.remove_temps(temps)
3.60 else:
3.61 self.writeline("%s (__BOOL(%s))" % (statement, test_ref))
3.62
4.1 --- a/transresults.py Tue Feb 28 00:00:09 2017 +0100
4.2 +++ b/transresults.py Tue Feb 28 17:00:26 2017 +0100
4.3 @@ -37,9 +37,25 @@
4.4 "A general expression."
4.5
4.6 def __init__(self, s):
4.7 - self.s = s
4.8 + if isinstance(s, Result):
4.9 + self.s = str(s)
4.10 + self.expr = s
4.11 + else:
4.12 + self.s = s
4.13 + self.expr = None
4.14 +
4.15 + def discards_temporary(self, test=True):
4.16 +
4.17 + """
4.18 + Return a list of temporary names that can be discarded if 'test' is
4.19 + specified as a true value (or omitted).
4.20 + """
4.21 +
4.22 + return self.expr and self.expr.discards_temporary(False)
4.23 +
4.24 def __str__(self):
4.25 return self.s
4.26 +
4.27 def __repr__(self):
4.28 return "Expression(%r)" % self.s
4.29
4.30 @@ -261,6 +277,15 @@
4.31 expr = self._convert(self.expr)
4.32 return "(!%s)" % expr
4.33
4.34 + def discards_temporary(self, test=True):
4.35 +
4.36 + """
4.37 + Return a list of temporary names that can be discarded if 'test' is
4.38 + specified as a true value (or omitted).
4.39 + """
4.40 +
4.41 + return self.expr.discards_temporary(test)
4.42 +
4.43 def __str__(self):
4.44 return "(%s ? %s : %s)" % (
4.45 self._convert(self.expr),
4.46 @@ -301,6 +326,25 @@
4.47 else:
4.48 return "(%s)" % " || ".join(results)
4.49
4.50 + def discards_temporary(self, test=True):
4.51 +
4.52 + """
4.53 + Return a list of temporary names that can be discarded if 'test' is
4.54 + specified as a true value (or omitted).
4.55 + """
4.56 +
4.57 + if not test:
4.58 + return None
4.59 +
4.60 + temps = ["__tmp_result"]
4.61 +
4.62 + for expr in self.exprs:
4.63 + t = expr.discards_temporary(test)
4.64 + if t:
4.65 + temps += t
4.66 +
4.67 + return temps
4.68 +
4.69 def __str__(self):
4.70
4.71 """