1.1 --- a/generator.py Mon Feb 20 18:50:16 2017 +0100
1.2 +++ b/generator.py Tue Feb 21 00:20:43 2017 +0100
1.3 @@ -19,7 +19,7 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from common import CommonOutput
1.8 +from common import CommonOutput, copy
1.9 from encoders import encode_function_pointer, \
1.10 encode_instantiator_pointer, \
1.11 encode_literal_constant, encode_literal_constant_member, \
1.12 @@ -31,24 +31,10 @@
1.13 encode_symbol, encode_tablename, \
1.14 encode_type_attribute, decode_type_attribute, \
1.15 is_type_attribute
1.16 -from os import listdir, mkdir
1.17 -from os.path import exists, isdir, join, split
1.18 +from os import listdir, mkdir, remove
1.19 +from os.path import exists, isdir, join, split, splitext
1.20 from referencing import Reference
1.21
1.22 -def copy(source, target):
1.23 -
1.24 - "Copy a text file from 'source' to 'target'."
1.25 -
1.26 - if isdir(target):
1.27 - target = join(target, split(source)[-1])
1.28 - infile = open(source)
1.29 - outfile = open(target, "w")
1.30 - try:
1.31 - outfile.write(infile.read())
1.32 - finally:
1.33 - outfile.close()
1.34 - infile.close()
1.35 -
1.36 class Generator(CommonOutput):
1.37
1.38 "A code generator."
1.39 @@ -124,9 +110,34 @@
1.40 if not exists(target):
1.41 mkdir(target)
1.42
1.43 - for filename in listdir(pathname):
1.44 + existing = listdir(target)
1.45 + needed = listdir(pathname)
1.46 +
1.47 + # Determine which files are superfluous by comparing their
1.48 + # basenames (without extensions) to those of the needed
1.49 + # filenames. This should preserve object files for needed source
1.50 + # files, only discarding completely superfluous files from the
1.51 + # target directory.
1.52 +
1.53 + needed_basenames = set()
1.54 + for filename in needed:
1.55 + needed_basenames.add(splitext(filename)[0])
1.56 +
1.57 + superfluous = []
1.58 + for filename in existing:
1.59 + if splitext(filename)[0] not in needed_basenames:
1.60 + superfluous.append(filename)
1.61 +
1.62 + # Copy needed files.
1.63 +
1.64 + for filename in needed:
1.65 copy(join(pathname, filename), target)
1.66
1.67 + # Remove superfluous files.
1.68 +
1.69 + for filename in superfluous:
1.70 + remove(join(target, filename))
1.71 +
1.72 def write_structures(self):
1.73
1.74 "Write structures used by the program."
1.75 @@ -522,7 +533,7 @@
1.76 # Employ a special alias that will be tested specifically in
1.77 # encode_member.
1.78
1.79 - encoding_ref = Reference("<instance>", self.string_type, "$c%d" % n)
1.80 + encoding_ref = Reference("<instance>", self.string_type, "$c%s" % n)
1.81
1.82 # Use None where no encoding was indicated.
1.83
1.84 @@ -959,7 +970,7 @@
1.85 constant_name = "$c%d" % local_number
1.86 attr_path = "%s.%s" % (path, constant_name)
1.87 constant_number = self.optimiser.constant_numbers[attr_path]
1.88 - constant_value = "__const%d" % constant_number
1.89 + constant_value = "__const%s" % constant_number
1.90 structure.append("%s /* %s */" % (constant_value, attrname))
1.91 continue
1.92
1.93 @@ -1021,7 +1032,7 @@
1.94 # Use the alias directly if appropriate.
1.95
1.96 if alias.startswith("$c"):
1.97 - constant_value = encode_literal_constant(int(alias[2:]))
1.98 + constant_value = encode_literal_constant(alias[2:])
1.99 return "%s /* %s */" % (constant_value, name)
1.100
1.101 # Obtain a constant value directly assigned to the attribute.