# HG changeset patch # User Paul Boddie # Date 1488297626 -3600 # Node ID f0fb5ec36d9911ef44a5434876b928c73e4965e7 # Parent 11c6d30e098da863d9b28b69b3b3c45747f41a58 Added a means of discarding temporary variables from directly-tested results. diff -r 11c6d30e098d -r f0fb5ec36d99 results.py --- a/results.py Tue Feb 28 00:00:09 2017 +0100 +++ b/results.py Tue Feb 28 17:00:26 2017 +0100 @@ -45,6 +45,9 @@ def context_identity(self): return None + def discards_temporary(self, test=True): + return None + def get_name(self): return None diff -r 11c6d30e098d -r f0fb5ec36d99 tests/logical_simple.py --- a/tests/logical_simple.py Tue Feb 28 00:00:09 2017 +0100 +++ b/tests/logical_simple.py Tue Feb 28 17:00:26 2017 +0100 @@ -9,20 +9,44 @@ e = not a print e # False +f = 0 + if a and b: print "a and b" # a and b +else: + print "! (a and b)" + +if a and f: + print "a and f" +else: + print "! (a and f)" # ! (a and f) if not (a and b): - print "not (a and b)" # + print "not (a and b)" +else: + print "! (not (a and b))" # ! (not (a and b)) if not not (a and b): print "not not (a and b)" # not not (a and b) +else: + print "! (not not (a and b))" if a or b: print "a or b" # a or b +else: + print "! (a or b)" if not (a or b): - print "not (a or b)" # + print "not (a or b)" +else: + print "! (not (a or b))" # ! (not (a or b)) if not not (a or b): print "not not (a or b)" # not not (a or b) +else: + print "! (not not (a or b))" + +if a and b or f: + print "a and b or f" # a and b or f +else: + print "! (a and b or f)" diff -r 11c6d30e098d -r f0fb5ec36d99 translator.py --- a/translator.py Tue Feb 28 00:00:09 2017 +0100 +++ b/translator.py Tue Feb 28 17:00:26 2017 +0100 @@ -1627,6 +1627,18 @@ # Special variable usage. + def get_temp_path(self): + + """ + Return the appropriate namespace path for temporary names in the current + namespace. + """ + + if self.in_function: + return self.get_namespace_path() + else: + return self.name + def record_temp(self, name): """ @@ -1636,13 +1648,23 @@ program. """ - if self.in_function: - path = self.get_namespace_path() - else: - path = self.name - - init_item(self.temp_usage, path, set) - self.temp_usage[path].add(name) + path = self.get_temp_path() + + init_item(self.temp_usage, path, list) + self.temp_usage[path].append(name) + + def remove_temps(self, names): + + """ + Remove 'names' from temporary storage allocations, each instance + removing each request for storage. + """ + + path = self.get_temp_path() + + for name in names: + if self.uses_temp(path, name): + self.temp_usage[path].remove(name) def uses_temp(self, path, name): @@ -1816,6 +1838,9 @@ if isinstance(test_ref, LogicalResult): self.writeline("%s %s" % (statement, test_ref.apply_test())) + temps = test_ref.discards_temporary() + if temps: + self.remove_temps(temps) else: self.writeline("%s (__BOOL(%s))" % (statement, test_ref)) diff -r 11c6d30e098d -r f0fb5ec36d99 transresults.py --- a/transresults.py Tue Feb 28 00:00:09 2017 +0100 +++ b/transresults.py Tue Feb 28 17:00:26 2017 +0100 @@ -37,9 +37,25 @@ "A general expression." def __init__(self, s): - self.s = s + if isinstance(s, Result): + self.s = str(s) + self.expr = s + else: + self.s = s + self.expr = None + + def discards_temporary(self, test=True): + + """ + Return a list of temporary names that can be discarded if 'test' is + specified as a true value (or omitted). + """ + + return self.expr and self.expr.discards_temporary(False) + def __str__(self): return self.s + def __repr__(self): return "Expression(%r)" % self.s @@ -261,6 +277,15 @@ expr = self._convert(self.expr) return "(!%s)" % expr + def discards_temporary(self, test=True): + + """ + Return a list of temporary names that can be discarded if 'test' is + specified as a true value (or omitted). + """ + + return self.expr.discards_temporary(test) + def __str__(self): return "(%s ? %s : %s)" % ( self._convert(self.expr), @@ -301,6 +326,25 @@ else: return "(%s)" % " || ".join(results) + def discards_temporary(self, test=True): + + """ + Return a list of temporary names that can be discarded if 'test' is + specified as a true value (or omitted). + """ + + if not test: + return None + + temps = ["__tmp_result"] + + for expr in self.exprs: + t = expr.discards_temporary(test) + if t: + temps += t + + return temps + def __str__(self): """