1.1 --- a/encoders.py Thu Oct 27 17:55:28 2016 +0200
1.2 +++ b/encoders.py Fri Oct 28 14:06:54 2016 +0200
1.3 @@ -185,6 +185,10 @@
1.4 "__encode_callable",
1.5 )
1.6
1.7 +static_ops = (
1.8 + "__load_static",
1.9 + )
1.10 +
1.11 def encode_access_instruction(instruction, subs):
1.12
1.13 """
1.14 @@ -239,6 +243,11 @@
1.15 op = "__load_function"
1.16 a = [kind == "<class>" and encode_instantiator_pointer(origin) or encode_function_pointer(origin)]
1.17
1.18 + # Obtain addresses of static objects.
1.19 +
1.20 + elif op in static_ops:
1.21 + a[0] = "&%s" % a[0]
1.22 +
1.23 argstr = "(%s)" % ", ".join(a)
1.24
1.25 # Substitute the first element of the instruction, which may not be an
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tests/logical.py Fri Oct 28 14:06:54 2016 +0200
2.3 @@ -0,0 +1,14 @@
2.4 +def f(a, b, c):
2.5 + return a and b and c
2.6 +
2.7 +def g(a, b, c):
2.8 + return a or b or c
2.9 +
2.10 +def h(a, b, c):
2.11 + return a and b or c
2.12 +
2.13 +def i(a, b, c):
2.14 + return a or b and c
2.15 +
2.16 +def j(a, b, c):
2.17 + return f(a, b, c) and g(a, b, c) or c
3.1 --- a/translator.py Thu Oct 27 17:55:28 2016 +0200
3.2 +++ b/translator.py Fri Oct 28 14:06:54 2016 +0200
3.3 @@ -104,7 +104,7 @@
3.4
3.5 elif static_name:
3.6 parent = ref.parent()
3.7 - context = ref.has_kind("<function>") and parent or None
3.8 + context = ref.has_kind("<function>") and encode_path(parent) or None
3.9 return "((__attr) {&%s, &%s})" % (context or "0", static_name)
3.10
3.11 else:
3.12 @@ -166,6 +166,16 @@
3.13 def __repr__(self):
3.14 return "PredefinedConstantRef(%r)" % self.value
3.15
3.16 +class BooleanResult(Expression, TranslationResult):
3.17 +
3.18 + "A expression producing a boolean result."
3.19 +
3.20 + def __str__(self):
3.21 + return "__builtins___bool_bool(%s)" % self.s
3.22 +
3.23 + def __repr__(self):
3.24 + return "BooleanResult(%r)" % self.s
3.25 +
3.26 def make_expression(expr):
3.27
3.28 "Make a new expression from the existing 'expr'."
3.29 @@ -744,7 +754,7 @@
3.30 continue
3.31
3.32 if name_ref:
3.33 - defaults.append("__SETDEFAULT(%s, %s, %s)" % (encode_path(instance_name), i, name_ref))
3.34 + defaults.append("__SETDEFAULT(&%s, %s, %s)" % (encode_path(instance_name), i, name_ref))
3.35
3.36 return defaults
3.37
3.38 @@ -917,18 +927,33 @@
3.39
3.40 def process_logical_node(self, n):
3.41
3.42 - "Process the given operator node 'n'."
3.43 + """
3.44 + Process the given operator node 'n'.
3.45 +
3.46 + Convert ... to ...
3.47 +
3.48 + <a> and <b>
3.49 + (__tmp_result = <a>, !__BOOL(__tmp_result)) ? __tmp_result : <b>
3.50 +
3.51 + <a> or <b>
3.52 + (__tmp_result = <a>, __BOOL(__tmp_result)) ? __tmp_result : <b>
3.53 + """
3.54
3.55 if isinstance(n, compiler.ast.And):
3.56 - op = " && "
3.57 + op = "!"
3.58 else:
3.59 - op = " || "
3.60 + op = ""
3.61 +
3.62 + results = []
3.63
3.64 - # NOTE: This needs to evaluate whether the operands are true or false
3.65 - # NOTE: according to Python rules.
3.66 + for node in n.nodes[:-1]:
3.67 + expr = self.process_structure_node(node)
3.68 + results.append("(__tmp_result = %s, %s__BOOL(__tmp_result)) ? __tmp_result : " % (expr, op))
3.69
3.70 - results = [("(%s)" % self.process_structure_node(node)) for node in n.nodes]
3.71 - return make_expression("(%s)" % op.join(results))
3.72 + expr = self.process_structure_node(n.nodes[-1])
3.73 + results.append(str(expr))
3.74 +
3.75 + return make_expression("(%s)" % "".join(results))
3.76
3.77 def process_name_node(self, n, expr=None):
3.78
3.79 @@ -1103,7 +1128,7 @@
3.80 print >>self.out, "{"
3.81 self.indent += 1
3.82 self.writeline("__ref __tmp_context, __tmp_value;")
3.83 - self.writeline("__attr __tmp_target;")
3.84 + self.writeline("__attr __tmp_target, __tmp_result;")
3.85
3.86 # Obtain local names from parameters.
3.87