1.1 --- a/common.py Tue Dec 13 19:19:23 2016 +0100
1.2 +++ b/common.py Tue Dec 13 22:46:52 2016 +0100
1.3 @@ -160,13 +160,16 @@
1.4
1.5 # Constant reference naming.
1.6
1.7 - def get_constant_name(self, value):
1.8 + def get_constant_name(self, value, value_type):
1.9
1.10 - "Add a new constant to the current namespace for 'value'."
1.11 + """
1.12 + Add a new constant to the current namespace for 'value' with
1.13 + 'value_type'.
1.14 + """
1.15
1.16 path = self.get_namespace_path()
1.17 init_item(self.constants, path, dict)
1.18 - return "$c%d" % add_counter_item(self.constants[path], value)
1.19 + return "$c%d" % add_counter_item(self.constants[path], (value, value_type))
1.20
1.21 # Literal reference naming.
1.22
1.23 @@ -230,7 +233,7 @@
1.24
1.25 "Return a constant reference for the given 'ref' type and 'value'."
1.26
1.27 - constant_name = self.get_constant_name(value)
1.28 + constant_name = self.get_constant_name(value, ref.get_origin())
1.29
1.30 # Return a reference for the constant.
1.31
1.32 @@ -249,7 +252,7 @@
1.33 type with the given 'origin'.
1.34 """
1.35
1.36 - constant_name = self.get_constant_name(value)
1.37 + constant_name = self.get_constant_name(value, origin)
1.38 objpath = self.get_object_path(constant_name)
1.39 self._reserve_constant(objpath, value, origin)
1.40
2.1 --- a/generator.py Tue Dec 13 19:19:23 2016 +0100
2.2 +++ b/generator.py Tue Dec 13 22:46:52 2016 +0100
2.3 @@ -341,8 +341,8 @@
2.4
2.5 # Generate literal constants.
2.6
2.7 - for value, n in self.optimiser.constants.items():
2.8 - self.make_literal_constant(f_decls, f_defs, n, value)
2.9 + for constant, n in self.optimiser.constants.items():
2.10 + self.make_literal_constant(f_decls, f_defs, n, constant)
2.11
2.12 # Finish the main source file.
2.13
2.14 @@ -433,23 +433,20 @@
2.15 f_signatures.close()
2.16 f_code.close()
2.17
2.18 - def make_literal_constant(self, f_decls, f_defs, n, value):
2.19 + def make_literal_constant(self, f_decls, f_defs, n, constant):
2.20
2.21 """
2.22 Write literal constant details to 'f_decls' (to declare a structure) and
2.23 to 'f_defs' (to define the contents) for the constant with the number
2.24 - 'n' with the given literal 'value'.
2.25 + 'n' with the given 'constant'.
2.26 """
2.27
2.28 + value, value_type = constant
2.29 +
2.30 const_path = encode_literal_constant(n)
2.31 structure_name = encode_literal_reference(n)
2.32
2.33 - # NOTE: This makes assumptions about the __builtins__ structure.
2.34 -
2.35 - typename = get_builtin_type(value.__class__.__name__)
2.36 - modname = get_builtin_module(typename)
2.37 - ref = Reference("<instance>", "__builtins__.%s.%s" % (modname, typename))
2.38 -
2.39 + ref = Reference("<instance>", value_type)
2.40 self.make_constant(f_decls, f_defs, ref, const_path, structure_name, value)
2.41
2.42 def make_predefined_constant(self, f_decls, f_defs, path, name):
2.43 @@ -491,7 +488,7 @@
2.44
2.45 # Also set a key for dynamic attribute lookup, if a string.
2.46
2.47 - if cls == self.string_type:
2.48 + if attrs.has_key("__key__"):
2.49 if data in self.optimiser.all_attrnames:
2.50 attrs["__key__"] = data
2.51 else:
2.52 @@ -890,6 +887,7 @@
2.53
2.54 elif attrname in ("__file__", "__fname__", "__mname__", "__name__"):
2.55 path = ref.get_origin()
2.56 + value_type = self.string_type
2.57
2.58 if attrname == "__file__":
2.59 module = self.importer.get_module(path)
2.60 @@ -897,7 +895,7 @@
2.61 else:
2.62 value = path
2.63
2.64 - local_number = self.importer.all_constants[path][value]
2.65 + local_number = self.importer.all_constants[path][(value, value_type)]
2.66 constant_name = "$c%d" % local_number
2.67 attr_path = "%s.%s" % (path, constant_name)
2.68 constant_number = self.optimiser.constant_numbers[attr_path]
3.1 --- a/modules.py Tue Dec 13 19:19:23 2016 +0100
3.2 +++ b/modules.py Tue Dec 13 22:46:52 2016 +0100
3.3 @@ -611,14 +611,15 @@
3.4 last_path = None
3.5 n = None
3.6 while line:
3.7 - path, constant = self._get_fields(line)
3.8 + path, value_type, value = self._get_fields(line, 3)
3.9 if path != last_path:
3.10 n = 0
3.11 last_path = path
3.12 else:
3.13 n += 1
3.14 init_item(self.constants, path, dict)
3.15 - self.constants[path][eval(constant)] = n
3.16 + value = eval(value)
3.17 + self.constants[path][(value, value_type)] = n
3.18 line = f.readline().rstrip()
3.19
3.20 def _get_constant_values(self, f):
3.21 @@ -756,7 +757,7 @@
3.22 "attribute access modifiers:"
3.23 zero or more: qualified function name " " local/global variable name " " attribute name " " access modifiers
3.24 "constant literals:"
3.25 - zero or more: qualified scope name " " constant literal
3.26 + zero or more: qualified scope name " " value type " " constant literal
3.27 "constant values:"
3.28 zero or more: qualified name " " value type " " constant literal
3.29
3.30 @@ -973,10 +974,12 @@
3.31 paths = self.constants.keys()
3.32 paths.sort()
3.33 for path in paths:
3.34 - constants = [(v, k) for (k, v) in self.constants[path].items()]
3.35 + constants = []
3.36 + for (value, value_type), n in self.constants[path].items():
3.37 + constants.append((n, value_type, value))
3.38 constants.sort()
3.39 - for n, constant in constants:
3.40 - print >>f, path, repr(constant)
3.41 + for n, value_type, value in constants:
3.42 + print >>f, path, value_type, repr(value)
3.43
3.44 print >>f
3.45 print >>f, "constant values:"
4.1 --- a/optimiser.py Tue Dec 13 19:19:23 2016 +0100
4.2 +++ b/optimiser.py Tue Dec 13 22:46:52 2016 +0100
4.3 @@ -274,10 +274,12 @@
4.4
4.5 f = open(join(self.output, "constants"), "w")
4.6 try:
4.7 - constants = [(n, value) for (value, n) in self.constants.items()]
4.8 + constants = []
4.9 + for (value, value_type), n in self.constants.items():
4.10 + constants.append((n, value_type, value))
4.11 constants.sort()
4.12 - for n, value in constants:
4.13 - print >>f, repr(value)
4.14 + for n, value_type, value in constants:
4.15 + print >>f, value_type, repr(value)
4.16
4.17 finally:
4.18 f.close()
4.19 @@ -644,16 +646,17 @@
4.20 self.constants = {}
4.21
4.22 for path, constants in self.importer.all_constants.items():
4.23 - for constant, n in constants.items():
4.24
4.25 - # Record constants and obtain a number for them.
4.26 + # Record constants and obtain a number for them.
4.27 + # Each constant is actually (value, value_type).
4.28
4.29 + for constant, n in constants.items():
4.30 add_counter_item(self.constants, constant)
4.31
4.32 self.constant_numbers = {}
4.33
4.34 - for name, (value, value_type) in self.importer.all_constant_values.items():
4.35 - self.constant_numbers[name] = self.constants[value]
4.36 + for name, constant in self.importer.all_constant_values.items():
4.37 + self.constant_numbers[name] = self.constants[constant]
4.38
4.39 def combine_rows(a, b):
4.40 c = []
5.1 --- a/translator.py Tue Dec 13 19:19:23 2016 +0100
5.2 +++ b/translator.py Tue Dec 13 22:46:52 2016 +0100
5.3 @@ -322,7 +322,8 @@
5.4 # NOTE: This makes assumptions about the __builtins__ structure.
5.5
5.6 modname = get_builtin_module(name)
5.7 - return self.importer.get_object("__builtins__.%s.%s" % (modname, name))
5.8 + typename = get_builtin_type(name)
5.9 + return self.importer.get_object("__builtins__.%s.%s" % (modname, typename))
5.10
5.11 def is_method(self, path):
5.12
5.13 @@ -422,8 +423,10 @@
5.14 return self.process_literal_sequence_node(n, name, ref, TrLiteralSequenceRef)
5.15 else:
5.16 value = self.get_constant_value(n.value)
5.17 + value_type = ref.get_origin()
5.18 +
5.19 path = self.get_namespace_path()
5.20 - local_number = self.importer.all_constants[path][value]
5.21 + local_number = self.importer.all_constants[path][(value, value_type)]
5.22 constant_name = "$c%d" % local_number
5.23 objpath = self.get_object_path(constant_name)
5.24 number = self.optimiser.constant_numbers[objpath]