# HG changeset patch # User Paul Boddie # Date 1481665612 -3600 # Node ID 0be168e888a9d4d66b363354585afd5e222182ba # Parent 3130610deb6787ec0cafef5a39c0ffc8fa795aef Added type information to constant records so that Unicode constants can be distinguished from plain string constants and thus be generated correctly. diff -r 3130610deb67 -r 0be168e888a9 common.py --- a/common.py Tue Dec 13 19:19:23 2016 +0100 +++ b/common.py Tue Dec 13 22:46:52 2016 +0100 @@ -160,13 +160,16 @@ # Constant reference naming. - def get_constant_name(self, value): + def get_constant_name(self, value, value_type): - "Add a new constant to the current namespace for 'value'." + """ + Add a new constant to the current namespace for 'value' with + 'value_type'. + """ path = self.get_namespace_path() init_item(self.constants, path, dict) - return "$c%d" % add_counter_item(self.constants[path], value) + return "$c%d" % add_counter_item(self.constants[path], (value, value_type)) # Literal reference naming. @@ -230,7 +233,7 @@ "Return a constant reference for the given 'ref' type and 'value'." - constant_name = self.get_constant_name(value) + constant_name = self.get_constant_name(value, ref.get_origin()) # Return a reference for the constant. @@ -249,7 +252,7 @@ type with the given 'origin'. """ - constant_name = self.get_constant_name(value) + constant_name = self.get_constant_name(value, origin) objpath = self.get_object_path(constant_name) self._reserve_constant(objpath, value, origin) diff -r 3130610deb67 -r 0be168e888a9 generator.py --- a/generator.py Tue Dec 13 19:19:23 2016 +0100 +++ b/generator.py Tue Dec 13 22:46:52 2016 +0100 @@ -341,8 +341,8 @@ # Generate literal constants. - for value, n in self.optimiser.constants.items(): - self.make_literal_constant(f_decls, f_defs, n, value) + for constant, n in self.optimiser.constants.items(): + self.make_literal_constant(f_decls, f_defs, n, constant) # Finish the main source file. @@ -433,23 +433,20 @@ f_signatures.close() f_code.close() - def make_literal_constant(self, f_decls, f_defs, n, value): + def make_literal_constant(self, f_decls, f_defs, n, constant): """ Write literal constant details to 'f_decls' (to declare a structure) and to 'f_defs' (to define the contents) for the constant with the number - 'n' with the given literal 'value'. + 'n' with the given 'constant'. """ + value, value_type = constant + const_path = encode_literal_constant(n) structure_name = encode_literal_reference(n) - # NOTE: This makes assumptions about the __builtins__ structure. - - typename = get_builtin_type(value.__class__.__name__) - modname = get_builtin_module(typename) - ref = Reference("", "__builtins__.%s.%s" % (modname, typename)) - + ref = Reference("", value_type) self.make_constant(f_decls, f_defs, ref, const_path, structure_name, value) def make_predefined_constant(self, f_decls, f_defs, path, name): @@ -491,7 +488,7 @@ # Also set a key for dynamic attribute lookup, if a string. - if cls == self.string_type: + if attrs.has_key("__key__"): if data in self.optimiser.all_attrnames: attrs["__key__"] = data else: @@ -890,6 +887,7 @@ elif attrname in ("__file__", "__fname__", "__mname__", "__name__"): path = ref.get_origin() + value_type = self.string_type if attrname == "__file__": module = self.importer.get_module(path) @@ -897,7 +895,7 @@ else: value = path - local_number = self.importer.all_constants[path][value] + local_number = self.importer.all_constants[path][(value, value_type)] constant_name = "$c%d" % local_number attr_path = "%s.%s" % (path, constant_name) constant_number = self.optimiser.constant_numbers[attr_path] diff -r 3130610deb67 -r 0be168e888a9 modules.py --- a/modules.py Tue Dec 13 19:19:23 2016 +0100 +++ b/modules.py Tue Dec 13 22:46:52 2016 +0100 @@ -611,14 +611,15 @@ last_path = None n = None while line: - path, constant = self._get_fields(line) + path, value_type, value = self._get_fields(line, 3) if path != last_path: n = 0 last_path = path else: n += 1 init_item(self.constants, path, dict) - self.constants[path][eval(constant)] = n + value = eval(value) + self.constants[path][(value, value_type)] = n line = f.readline().rstrip() def _get_constant_values(self, f): @@ -756,7 +757,7 @@ "attribute access modifiers:" zero or more: qualified function name " " local/global variable name " " attribute name " " access modifiers "constant literals:" - zero or more: qualified scope name " " constant literal + zero or more: qualified scope name " " value type " " constant literal "constant values:" zero or more: qualified name " " value type " " constant literal @@ -973,10 +974,12 @@ paths = self.constants.keys() paths.sort() for path in paths: - constants = [(v, k) for (k, v) in self.constants[path].items()] + constants = [] + for (value, value_type), n in self.constants[path].items(): + constants.append((n, value_type, value)) constants.sort() - for n, constant in constants: - print >>f, path, repr(constant) + for n, value_type, value in constants: + print >>f, path, value_type, repr(value) print >>f print >>f, "constant values:" diff -r 3130610deb67 -r 0be168e888a9 optimiser.py --- a/optimiser.py Tue Dec 13 19:19:23 2016 +0100 +++ b/optimiser.py Tue Dec 13 22:46:52 2016 +0100 @@ -274,10 +274,12 @@ f = open(join(self.output, "constants"), "w") try: - constants = [(n, value) for (value, n) in self.constants.items()] + constants = [] + for (value, value_type), n in self.constants.items(): + constants.append((n, value_type, value)) constants.sort() - for n, value in constants: - print >>f, repr(value) + for n, value_type, value in constants: + print >>f, value_type, repr(value) finally: f.close() @@ -644,16 +646,17 @@ self.constants = {} for path, constants in self.importer.all_constants.items(): - for constant, n in constants.items(): - # Record constants and obtain a number for them. + # Record constants and obtain a number for them. + # Each constant is actually (value, value_type). + for constant, n in constants.items(): add_counter_item(self.constants, constant) self.constant_numbers = {} - for name, (value, value_type) in self.importer.all_constant_values.items(): - self.constant_numbers[name] = self.constants[value] + for name, constant in self.importer.all_constant_values.items(): + self.constant_numbers[name] = self.constants[constant] def combine_rows(a, b): c = [] diff -r 3130610deb67 -r 0be168e888a9 translator.py --- a/translator.py Tue Dec 13 19:19:23 2016 +0100 +++ b/translator.py Tue Dec 13 22:46:52 2016 +0100 @@ -322,7 +322,8 @@ # NOTE: This makes assumptions about the __builtins__ structure. modname = get_builtin_module(name) - return self.importer.get_object("__builtins__.%s.%s" % (modname, name)) + typename = get_builtin_type(name) + return self.importer.get_object("__builtins__.%s.%s" % (modname, typename)) def is_method(self, path): @@ -422,8 +423,10 @@ return self.process_literal_sequence_node(n, name, ref, TrLiteralSequenceRef) else: value = self.get_constant_value(n.value) + value_type = ref.get_origin() + path = self.get_namespace_path() - local_number = self.importer.all_constants[path][value] + local_number = self.importer.all_constants[path][(value, value_type)] constant_name = "$c%d" % local_number objpath = self.get_object_path(constant_name) number = self.optimiser.constant_numbers[objpath]