1.1 --- a/translator.py Fri Nov 25 18:36:45 2016 +0100
1.2 +++ b/translator.py Fri Nov 25 19:20:37 2016 +0100
1.3 @@ -587,6 +587,11 @@
1.4 name_ref = self.process_name_node(n, self.process_structure_node(expr))
1.5 self.statement(name_ref)
1.6
1.7 + # Employ guards after assignments if required.
1.8 +
1.9 + if expr and name_ref.is_name():
1.10 + self.generate_guard(name_ref.name)
1.11 +
1.12 elif isinstance(n, compiler.ast.AssAttr):
1.13 in_assignment = self.in_assignment
1.14 self.in_assignment = self.process_structure_node(expr)
1.15 @@ -772,28 +777,7 @@
1.16 # Process any guards defined for the parameters.
1.17
1.18 for name in self.importer.function_parameters.get(function_name):
1.19 -
1.20 - # Get the accessor details and any guards defined for it.
1.21 -
1.22 - location = self.get_accessor_location(name)
1.23 - test = self.deducer.accessor_guard_tests.get(location)
1.24 - if test:
1.25 - guard, guard_type = test
1.26 -
1.27 - if guard == "specific":
1.28 - ref = first(self.deducer.accessor_all_types[location])
1.29 - argstr = "&%s" % encode_path(ref.get_origin())
1.30 - elif guard == "common":
1.31 - ref = first(self.deducer.accessor_all_general_types[location])
1.32 - typeattr = encode_type_attribute(ref.get_origin())
1.33 - argstr = "%s, %s" % (encode_symbol("pos", typeattr), encode_symbol("code", typeattr))
1.34 - else:
1.35 - continue
1.36 -
1.37 - # Write a test that raises a TypeError upon failure.
1.38 -
1.39 - self.writestmt("if (!__test_%s_%s(%s->value, %s)) __raise_type_error();" % (
1.40 - guard, guard_type, name, argstr))
1.41 + self.generate_guard(name)
1.42
1.43 # Produce the body and any additional return statement.
1.44
1.45 @@ -805,6 +789,38 @@
1.46
1.47 self.end_function(function_name)
1.48
1.49 + def generate_guard(self, name):
1.50 +
1.51 + """
1.52 + Get the accessor details for 'name', found in the current namespace, and
1.53 + generate any guards defined for it.
1.54 + """
1.55 +
1.56 + # Obtain the location, keeping track of assignment versions.
1.57 +
1.58 + location = self.get_accessor_location(name)
1.59 + test = self.deducer.accessor_guard_tests.get(location)
1.60 +
1.61 + # Generate any guard from the deduced information.
1.62 +
1.63 + if test:
1.64 + guard, guard_type = test
1.65 +
1.66 + if guard == "specific":
1.67 + ref = first(self.deducer.accessor_all_types[location])
1.68 + argstr = "&%s" % encode_path(ref.get_origin())
1.69 + elif guard == "common":
1.70 + ref = first(self.deducer.accessor_all_general_types[location])
1.71 + typeattr = encode_type_attribute(ref.get_origin())
1.72 + argstr = "%s, %s" % (encode_symbol("pos", typeattr), encode_symbol("code", typeattr))
1.73 + else:
1.74 + return
1.75 +
1.76 + # Write a test that raises a TypeError upon failure.
1.77 +
1.78 + self.writestmt("if (!__test_%s_%s(%s->value, %s)) __raise_type_error();" % (
1.79 + guard, guard_type, name, argstr))
1.80 +
1.81 def process_function_node(self, n):
1.82
1.83 """