1.1 --- a/generator.py Tue Oct 25 00:12:34 2016 +0200
1.2 +++ b/generator.py Tue Oct 25 00:20:22 2016 +0200
1.3 @@ -21,7 +21,8 @@
1.4
1.5 from common import CommonOutput
1.6 from encoders import encode_bound_reference, encode_function_pointer, \
1.7 - encode_instantiator_pointer, encode_path, encode_symbol
1.8 + encode_instantiator_pointer, encode_path, encode_symbol, \
1.9 + encode_type_attribute
1.10 from os import listdir
1.11 from os.path import isdir, join, split
1.12 from referencing import Reference
1.13 @@ -106,6 +107,7 @@
1.14 """
1.15 print >>f_defs, """\
1.16 #include "progtypes.h"
1.17 +#include "progops.h"
1.18 #include "main.h"
1.19 """
1.20 print >>f_signatures, """\
1.21 @@ -154,15 +156,17 @@
1.22
1.23 if path.endswith(".__init__"):
1.24 path = path[:-len(".__init__")]
1.25 - min_sizes[path] = argmin - 1
1.26 - max_sizes[path] = argmax - 1
1.27
1.28 self.write_size_constants(f_consts, "pmin", min_sizes, 0)
1.29 self.write_size_constants(f_consts, "pmax", max_sizes, 0)
1.30
1.31 + # Generate parameter codes.
1.32 +
1.33 + self.write_code_constants(f_consts, self.optimiser.all_paramnames, self.optimiser.arg_locations, "pcode", "ppos")
1.34 +
1.35 # Generate attribute codes.
1.36
1.37 - self.write_code_constants(f_consts, self.optimiser.all_attrnames, self.optimiser.locations)
1.38 + self.write_code_constants(f_consts, self.optimiser.all_attrnames, self.optimiser.locations, "code", "pos")
1.39
1.40 # Generate table and structure data.
1.41
1.42 @@ -254,20 +258,22 @@
1.43
1.44 if parent_kind == "<class>":
1.45
1.46 + # A bound version of a method.
1.47 +
1.48 + structure = self.populate_function(path, function_instance_attrs, False)
1.49 + self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure,
1.50 + encode_bound_reference(path))
1.51 +
1.52 # An unbound version of a method.
1.53
1.54 structure = self.populate_function(path, function_instance_attrs, True)
1.55 self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure)
1.56
1.57 - # A bound version of a method.
1.58 + else:
1.59 + # A normal function.
1.60
1.61 structure = self.populate_function(path, function_instance_attrs, False)
1.62 - self.write_structure(f_decls, f_defs, encode_bound_reference(path), table_name, structure_size, structure)
1.63 -
1.64 - # A normal function.
1.65 -
1.66 - structure = self.populate_function(path, function_instance_attrs, False)
1.67 - self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure)
1.68 + self.write_structure(f_decls, f_defs, path, table_name, structure_size, structure)
1.69
1.70 # Write function declarations.
1.71 # Signature: __attr <name>(__attr[]);
1.72 @@ -339,24 +345,24 @@
1.73 f_consts.write(" %s = %d" % (encode_size(size_prefix, path), size + padding))
1.74 print >>f_consts, "\n };"
1.75
1.76 - def write_code_constants(self, f_consts, attrnames, locations):
1.77 + def write_code_constants(self, f_consts, attrnames, locations, code_prefix, pos_prefix):
1.78
1.79 """
1.80 Write code constants to 'f_consts' for the given 'attrnames' and
1.81 attribute 'locations'.
1.82 """
1.83
1.84 - print >>f_consts, "enum %s {" % encode_symbol("code")
1.85 + print >>f_consts, "enum %s {" % encode_symbol(code_prefix)
1.86 first = True
1.87 for i, attrname in enumerate(attrnames):
1.88 if not first:
1.89 print >>f_consts, ","
1.90 else:
1.91 first = False
1.92 - f_consts.write(" %s = %d" % (encode_symbol("code", attrname), i))
1.93 + f_consts.write(" %s = %d" % (encode_symbol(code_prefix, attrname), i))
1.94 print >>f_consts, "\n };"
1.95
1.96 - print >>f_consts, "enum %s {" % encode_symbol("pos")
1.97 + print >>f_consts, "enum %s {" % encode_symbol(pos_prefix)
1.98 first = True
1.99 for i, attrnames in enumerate(locations):
1.100 for attrname in attrnames:
1.101 @@ -364,7 +370,7 @@
1.102 print >>f_consts, ","
1.103 else:
1.104 first = False
1.105 - f_consts.write(" %s = %d" % (encode_symbol("pos", attrname), i))
1.106 + f_consts.write(" %s = %d" % (encode_symbol(pos_prefix, attrname), i))
1.107 print >>f_consts, "\n };"
1.108
1.109 def write_table(self, f_decls, f_defs, table_name, structure_size, table):
1.110 @@ -399,7 +405,7 @@
1.111 table_name, structure_size,
1.112 ",\n ".join([("{%s, %s}" % t) for t in table]))
1.113
1.114 - def write_structure(self, f_decls, f_defs, path, table_name, structure_size, structure):
1.115 + def write_structure(self, f_decls, f_defs, path, table_name, structure_size, structure, copy=None):
1.116
1.117 """
1.118 Write the declarations to 'f_decls' and definitions to 'f_defs' for
1.119 @@ -419,21 +425,35 @@
1.120 unsigned int pos;
1.121 __attr attrs[%s];
1.122 } %s;
1.123 -""" % (structure_size, encode_symbol("obj", path))
1.124 +""" % (structure_size, encode_symbol("obj", copy or path))
1.125
1.126 # Write the corresponding definition.
1.127
1.128 - print >>f_defs, "__obj %s = {\n &%s,\n %s,\n {\n %s\n }};\n" % (
1.129 - encode_path(path), table_name, encode_symbol("pos", path),
1.130 + is_class = self.importer.get_object(path).has_kind("<class>")
1.131 + pos = is_class and encode_symbol("pos", encode_type_attribute(path)) or "0"
1.132 +
1.133 + print >>f_defs, """\
1.134 +__obj %s = {
1.135 + &%s,
1.136 + %s,
1.137 + {
1.138 + %s
1.139 + }};
1.140 +""" % (
1.141 + encode_path(copy or path), table_name, pos,
1.142 ",\n ".join(structure))
1.143
1.144 - def get_parameters(self, ref):
1.145 - return self.importer.function_parameters[ref.get_origin()]
1.146 + def get_argument_limits(self, path):
1.147
1.148 - def get_argument_limits(self, path):
1.149 + """
1.150 + Return the argument minimum and maximum for the callable at 'path',
1.151 + adding an argument position for a universal context.
1.152 + """
1.153 +
1.154 parameters = self.importer.function_parameters[path]
1.155 defaults = self.importer.function_defaults.get(path)
1.156 - return len(parameters) - (defaults and len(defaults) or 0), len(parameters)
1.157 + num_parameters = len(parameters) + 1
1.158 + return num_parameters - (defaults and len(defaults) or 0), num_parameters
1.159
1.160 def get_attribute_names(self, indexes):
1.161
1.162 @@ -599,11 +619,11 @@
1.163 else:
1.164 attr = encode_function_pointer(attr)
1.165
1.166 - structure.append("{%s, .fn=%s}" % (bound_attr and ".b=%s" % bound_attr or "0", attr))
1.167 + structure.append("{%s, .fn=%s}" % (bound_attr and ".b=&%s" % bound_attr or "0", attr))
1.168 continue
1.169
1.170 elif attrname == "__args__":
1.171 - structure.append("{.min=%s, .ptable=%s}" % (attr, encode_tablename("Function", origin)))
1.172 + structure.append("{.min=%s, .ptable=&%s}" % (attr, encode_tablename("Function", origin)))
1.173 continue
1.174
1.175 structure.append(self.encode_member(origin, attrname, attr, kind))
1.176 @@ -665,23 +685,18 @@
1.177 NOTE: where __call__ is provided by the class.
1.178 """
1.179
1.180 - parameters = self.get_parameters(init_ref)
1.181 - arg_copy = "memcpy(&__tmp_args[1], args, %d * sizeof(__attr));" % (len(parameters) - 1)
1.182 + parameters = self.importer.function_parameters[init_ref.get_origin()]
1.183
1.184 print >>f_code, """\
1.185 -__attr %s(__attr args[])
1.186 +__attr %s(__attr __args[])
1.187 {
1.188 - __attr __tmp_args[%d];
1.189 - __tmp_args[0] = __new(&%s, &%s, sizeof(%s));
1.190 + __args[0] = __new(&%s, &%s, sizeof(%s));
1.191 %s
1.192 - %s(__tmp_args);
1.193 - return __tmp_args[0];
1.194 + return __args[0];
1.195 }
1.196 """ % (
1.197 encode_instantiator_pointer(path),
1.198 - len(parameters),
1.199 encode_tablename("Instance", path), encode_path(path), encode_symbol("obj", path),
1.200 - len(parameters) - 1 and arg_copy or "",
1.201 encode_function_pointer(init_ref.get_origin())
1.202 )
1.203