1.1 --- a/generator.py Wed Dec 14 16:40:00 2016 +0100
1.2 +++ b/generator.py Wed Dec 14 17:22:07 2016 +0100
1.3 @@ -445,13 +445,13 @@
1.4 'n' with the given 'constant'.
1.5 """
1.6
1.7 - value, value_type = constant
1.8 + value, value_type, encoding = constant
1.9
1.10 const_path = encode_literal_constant(n)
1.11 structure_name = encode_literal_reference(n)
1.12
1.13 ref = Reference("<instance>", value_type)
1.14 - self.make_constant(f_decls, f_defs, ref, const_path, structure_name, value)
1.15 + self.make_constant(f_decls, f_defs, ref, const_path, structure_name, value, encoding)
1.16
1.17 def make_predefined_constant(self, f_decls, f_defs, path, name):
1.18
1.19 @@ -469,13 +469,16 @@
1.20
1.21 self.make_constant(f_decls, f_defs, ref, attr_path, structure_name)
1.22
1.23 - def make_constant(self, f_decls, f_defs, ref, const_path, structure_name, data=None):
1.24 + def make_constant(self, f_decls, f_defs, ref, const_path, structure_name, data=None, encoding=None):
1.25
1.26 """
1.27 Write constant details to 'f_decls' (to declare a structure) and to
1.28 'f_defs' (to define the contents) for the constant described by 'ref'
1.29 having the given 'path' and 'structure_name' (for the constant structure
1.30 itself).
1.31 +
1.32 + The additional 'data' and 'encoding' are used to describe specific
1.33 + values.
1.34 """
1.35
1.36 # Obtain the attributes.
1.37 @@ -501,7 +504,23 @@
1.38 # Define Unicode constant encoding details.
1.39
1.40 if cls == self.unicode_type:
1.41 - attrs["encoding"] = Reference("<instance>", self.none_type)
1.42 +
1.43 + # Reference the encoding's own constant value.
1.44 +
1.45 + if encoding:
1.46 + n = self.optimiser.constants[(encoding, self.string_type, None)]
1.47 +
1.48 + # Employ a special alias that will be tested specifically in
1.49 + # encode_member.
1.50 +
1.51 + encoding_ref = Reference("<instance>", self.string_type, "$c%d" % n)
1.52 +
1.53 + # Use None where no encoding was indicated.
1.54 +
1.55 + else:
1.56 + encoding_ref = Reference("<instance>", self.none_type)
1.57 +
1.58 + attrs["encoding"] = encoding_ref
1.59
1.60 # Define the structure details. An object is created for the constant,
1.61 # but an attribute is provided, referring to the object, for access to
1.62 @@ -904,7 +923,9 @@
1.63 else:
1.64 value = path
1.65
1.66 - local_number = self.importer.all_constants[path][(value, value_type)]
1.67 + encoding = None
1.68 +
1.69 + local_number = self.importer.all_constants[path][(value, value_type, encoding)]
1.70 constant_name = "$c%d" % local_number
1.71 attr_path = "%s.%s" % (path, constant_name)
1.72 constant_number = self.optimiser.constant_numbers[attr_path]
1.73 @@ -918,6 +939,8 @@
1.74 structure.append("{0, &%s}" % encode_path(decode_type_attribute(attrname)))
1.75 continue
1.76
1.77 + # All other kinds of members.
1.78 +
1.79 structure.append(self.encode_member(origin, attrname, attr, kind))
1.80
1.81 def encode_member(self, path, name, ref, structure_type):
1.82 @@ -935,11 +958,17 @@
1.83 if kind == "<instance>" and ref.is_constant_alias():
1.84 alias = ref.get_name()
1.85
1.86 + # Use the alias directly if appropriate.
1.87 +
1.88 + if alias.startswith("$c"):
1.89 + constant_value = encode_literal_constant(int(alias[2:]))
1.90 + return "%s /* %s */" % (constant_value, name)
1.91 +
1.92 # Obtain a constant value directly assigned to the attribute.
1.93
1.94 if self.optimiser.constant_numbers.has_key(alias):
1.95 constant_number = self.optimiser.constant_numbers[alias]
1.96 - constant_value = "__const%d" % constant_number
1.97 + constant_value = encode_literal_constant(constant_number)
1.98 return "%s /* %s */" % (constant_value, name)
1.99
1.100 # Usage of predefined constants, currently only None supported.