# HG changeset patch # User Paul Boddie # Date 1477656414 -7200 # Node ID 45dfa7227ebc1ea8001ae30be3c577ad05c28381 # Parent 37644d46a4142a4cdc8e616cb44f9249beb3cedd Fixed static object loading and added initial support for boolean tests. diff -r 37644d46a414 -r 45dfa7227ebc encoders.py --- a/encoders.py Thu Oct 27 17:55:28 2016 +0200 +++ b/encoders.py Fri Oct 28 14:06:54 2016 +0200 @@ -185,6 +185,10 @@ "__encode_callable", ) +static_ops = ( + "__load_static", + ) + def encode_access_instruction(instruction, subs): """ @@ -239,6 +243,11 @@ op = "__load_function" a = [kind == "" and encode_instantiator_pointer(origin) or encode_function_pointer(origin)] + # Obtain addresses of static objects. + + elif op in static_ops: + a[0] = "&%s" % a[0] + argstr = "(%s)" % ", ".join(a) # Substitute the first element of the instruction, which may not be an diff -r 37644d46a414 -r 45dfa7227ebc tests/logical.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/logical.py Fri Oct 28 14:06:54 2016 +0200 @@ -0,0 +1,14 @@ +def f(a, b, c): + return a and b and c + +def g(a, b, c): + return a or b or c + +def h(a, b, c): + return a and b or c + +def i(a, b, c): + return a or b and c + +def j(a, b, c): + return f(a, b, c) and g(a, b, c) or c diff -r 37644d46a414 -r 45dfa7227ebc translator.py --- a/translator.py Thu Oct 27 17:55:28 2016 +0200 +++ b/translator.py Fri Oct 28 14:06:54 2016 +0200 @@ -104,7 +104,7 @@ elif static_name: parent = ref.parent() - context = ref.has_kind("") and parent or None + context = ref.has_kind("") and encode_path(parent) or None return "((__attr) {&%s, &%s})" % (context or "0", static_name) else: @@ -166,6 +166,16 @@ def __repr__(self): return "PredefinedConstantRef(%r)" % self.value +class BooleanResult(Expression, TranslationResult): + + "A expression producing a boolean result." + + def __str__(self): + return "__builtins___bool_bool(%s)" % self.s + + def __repr__(self): + return "BooleanResult(%r)" % self.s + def make_expression(expr): "Make a new expression from the existing 'expr'." @@ -744,7 +754,7 @@ continue if name_ref: - defaults.append("__SETDEFAULT(%s, %s, %s)" % (encode_path(instance_name), i, name_ref)) + defaults.append("__SETDEFAULT(&%s, %s, %s)" % (encode_path(instance_name), i, name_ref)) return defaults @@ -917,18 +927,33 @@ def process_logical_node(self, n): - "Process the given operator node 'n'." + """ + Process the given operator node 'n'. + + Convert ... to ... + + and + (__tmp_result = , !__BOOL(__tmp_result)) ? __tmp_result : + + or + (__tmp_result = , __BOOL(__tmp_result)) ? __tmp_result : + """ if isinstance(n, compiler.ast.And): - op = " && " + op = "!" else: - op = " || " + op = "" + + results = [] - # NOTE: This needs to evaluate whether the operands are true or false - # NOTE: according to Python rules. + for node in n.nodes[:-1]: + expr = self.process_structure_node(node) + results.append("(__tmp_result = %s, %s__BOOL(__tmp_result)) ? __tmp_result : " % (expr, op)) - results = [("(%s)" % self.process_structure_node(node)) for node in n.nodes] - return make_expression("(%s)" % op.join(results)) + expr = self.process_structure_node(n.nodes[-1]) + results.append(str(expr)) + + return make_expression("(%s)" % "".join(results)) def process_name_node(self, n, expr=None): @@ -1103,7 +1128,7 @@ print >>self.out, "{" self.indent += 1 self.writeline("__ref __tmp_context, __tmp_value;") - self.writeline("__attr __tmp_target;") + self.writeline("__attr __tmp_target, __tmp_result;") # Obtain local names from parameters.