1.1 --- a/generator.py Sun Oct 30 22:33:22 2016 +0100
1.2 +++ b/generator.py Mon Oct 31 18:26:36 2016 +0100
1.3 @@ -23,7 +23,8 @@
1.4 from encoders import encode_bound_reference, encode_function_pointer, \
1.5 encode_instantiator_pointer, \
1.6 encode_literal_constant, encode_literal_constant_member, \
1.7 - encode_literal_constant_value, encode_literal_reference, \
1.8 + encode_literal_constant_value, \
1.9 + encode_literal_instantiator, encode_literal_reference, \
1.10 encode_path, \
1.11 encode_predefined_reference, encode_size, \
1.12 encode_symbol, encode_tablename, \
1.13 @@ -61,6 +62,12 @@
1.14 ("__builtins__.notimplemented", "NotImplemented"),
1.15 )
1.16
1.17 + literal_instantiator_types = (
1.18 + "__builtins__.dict.dict",
1.19 + "__builtins__.list.list",
1.20 + "__builtins__.tuple.tuple",
1.21 + )
1.22 +
1.23 def __init__(self, importer, optimiser, output):
1.24 self.importer = importer
1.25 self.optimiser = optimiser
1.26 @@ -120,7 +127,9 @@
1.27 """
1.28 print >>f_code, """\
1.29 #include <string.h>
1.30 +#include <stdio.h>
1.31 #include "types.h"
1.32 +#include "exceptions.h"
1.33 #include "ops.h"
1.34 #include "progconsts.h"
1.35 #include "progtypes.h"
1.36 @@ -201,13 +210,9 @@
1.37
1.38 init_ref = attrs["__init__"]
1.39
1.40 - # Signature: __attr __new_<name>(__attr[]);
1.41 -
1.42 - print >>f_signatures, "__attr %s(__attr[]);" % encode_instantiator_pointer(path)
1.43 -
1.44 # Write instantiator definitions.
1.45
1.46 - self.write_instantiator(f_code, path, init_ref)
1.47 + self.write_instantiator(f_code, f_signatures, path, init_ref)
1.48
1.49 # Write parameter table.
1.50
1.51 @@ -797,11 +802,12 @@
1.52 for name, default in self.importer.function_defaults.get(path):
1.53 structure.append(self.encode_member(path, name, default, "<instance>"))
1.54
1.55 - def write_instantiator(self, f_code, path, init_ref):
1.56 + def write_instantiator(self, f_code, f_signatures, path, init_ref):
1.57
1.58 """
1.59 - Write an instantiator to 'f_code' for instances of the class with the
1.60 - given 'path', with 'init_ref' as the initialiser function reference.
1.61 + Write an instantiator to 'f_code', with a signature to 'f_signatures',
1.62 + for instances of the class with the given 'path', with 'init_ref' as the
1.63 + initialiser function reference.
1.64
1.65 NOTE: This also needs to initialise any __fn__ and __args__ members
1.66 NOTE: where __call__ is provided by the class.
1.67 @@ -812,8 +818,13 @@
1.68 print >>f_code, """\
1.69 __attr %s(__attr __args[])
1.70 {
1.71 + /* Allocate the structure. */
1.72 __args[0] = __new(&%s, &%s, sizeof(%s));
1.73 +
1.74 + /* Call the initialiser. */
1.75 %s(__args);
1.76 +
1.77 + /* Return the allocated object details. */
1.78 return __args[0];
1.79 }
1.80 """ % (
1.81 @@ -824,6 +835,39 @@
1.82 encode_function_pointer(init_ref.get_origin())
1.83 )
1.84
1.85 + print >>f_signatures, "__attr %s(__attr[]);" % encode_instantiator_pointer(path)
1.86 +
1.87 + # Write additional literal instantiators. These do not call the
1.88 + # initialisers but instead populate the structures directly.
1.89 +
1.90 + if path in self.literal_instantiator_types:
1.91 + print >>f_code, """\
1.92 +__attr %s(__attr __args[], unsigned int number)
1.93 +{
1.94 + __attr data;
1.95 +
1.96 + /* Allocate the structure. */
1.97 + __args[0] = __new(&%s, &%s, sizeof(%s));
1.98 +
1.99 + /* Allocate a structure for the data. */
1.100 + data = __newdata(__args, number);
1.101 +
1.102 + /* Store a reference to the data in the object's __data__ attribute. */
1.103 + __store_via_object(__args[0].value, %s, data);
1.104 +
1.105 + /* Return the allocated object details. */
1.106 + return __args[0];
1.107 +}
1.108 +""" % (
1.109 + encode_literal_instantiator(path),
1.110 + encode_tablename("<instance>", path),
1.111 + encode_path(path),
1.112 + encode_symbol("obj", path),
1.113 + encode_symbol("pos", "__data__")
1.114 + )
1.115 +
1.116 + print >>f_signatures, "__attr %s(__attr[], unsigned int);" % encode_literal_instantiator(path)
1.117 +
1.118 def write_main_program(self, f_code, f_signatures):
1.119
1.120 """
1.121 @@ -833,7 +877,9 @@
1.122
1.123 print >>f_code, """\
1.124 int main(int argc, char *argv[])
1.125 -{"""
1.126 +{
1.127 + __Try
1.128 + {"""
1.129
1.130 for name in self.importer.modules.keys():
1.131 function_name = "__main_%s" % encode_path(name)
1.132 @@ -846,8 +892,14 @@
1.133 %s();""" % function_name
1.134
1.135 print >>f_code, """\
1.136 - __main___main__();
1.137 - return 0;
1.138 + __main___main__();
1.139 + return 0;
1.140 + }
1.141 + __Catch_anonymous
1.142 + {
1.143 + fprintf(stderr, "Program terminated due to exception.\\n");
1.144 + return 1;
1.145 + }
1.146 }
1.147 """
1.148