diff --git a/lang/compile.py b/lang/compile.py index 6e679d1..fc54021 100755 --- a/lang/compile.py +++ b/lang/compile.py @@ -955,34 +955,34 @@ }""" % (len(module_args)) def generate_callbacks(): - return """static struct object_class module_class; + return """static struct object_class CLASSNAME_class; -static Object module_create(VmState state, struct object_list *use_modules) { - Object obj = object_create(state, &module_class, sizeof(struct object_list *)); - struct object_list **args = (struct object_list **)object_priv(state, obj, &module_class); +static Object CLASSNAME_create(VmState state, struct object_list *use_modules) { + Object obj = object_create(state, &CLASSNAME_class, sizeof(struct object_list *)); + struct object_list **args = (struct object_list **)object_priv(state, obj, &CLASSNAME_class); *args = create_args(state, use_modules); return obj; } -static void module_cleanup(VmState state, Object obj) { - struct object_list **args = (struct object_list **)object_priv(state, obj, &module_class); +static void CLASSNAME_cleanup(VmState state, Object obj) { + struct object_list **args = (struct object_list **)object_priv(state, obj, &CLASSNAME_class); free_args(state, args); } -static void module_call_bytecode(VmState state, Object obj, void *priv) { - struct object_list **args = (struct object_list **)object_priv(state, obj, &module_class); +static void CLASSNAME_call_bytecode(VmState state, Object obj, void *priv) { + struct object_list **args = (struct object_list **)object_priv(state, obj, &CLASSNAME_class); bytecode_run(state, obj, (const unsigned char *)priv, *args); }""" def generate_structures(functions): - structures = """static struct object_call module_calls[] = {\n""" + structures = """static struct object_call CLASSNAME_calls[] = {\n""" for function in functions: structures += "\t" + function + "\n" structures += "\t{.name = NULL, /* end */}\n};" structures += """\n -static struct object_class module_class = { - .cleanup = module_cleanup, - .calls = &module_calls[0], +static struct object_class CLASSNAME_class = { + .cleanup = CLASSNAME_cleanup, + .calls = &CLASSNAME_calls[0], };""" return structures @@ -998,9 +998,9 @@ output += "};\n\n" return output -def generate_call(node): - call = '{.name = "%s", .handler = module_call_bytecode, ' % (node.name) - call += '\n\t\t.priv = (void *)bytecode_%s_%s},' % (node.class_, node.name) +def generate_call(class_name, func_name): + call = '{.name = "%s", .handler = CLASSNAME_call_bytecode, ' % (func_name) + call += '\n\t\t.priv = (void *)bytecode_%s_%s},' % (class_name, func_name) return call def generate_metadata(node): @@ -1011,14 +1011,24 @@ output += "const struct module_info module_info_%s = {\n" % (node.id) output += "\t.name = \"%s\",\n" % (node.name) output += "\t.uses = module_uses,\n" - output += "\t.create = module_create,\n" + output += "\t.create = %s_create,\n" % (node.name) output += "};" return output +def generate_c_class(class_ir): + functions = [] + for func in class_ir.functions: + functions.append(generate_call(class_ir.name, func)) + output = generate_callbacks() + output += "\n\n" + output += generate_structures(functions) + output = output.replace('CLASSNAME', class_ir.name) + return output + def generate_c_file(module_args, ir, source): metadata = "" bytecodes = "" - functions = [] + classes = "" for node in ir: success = False if isinstance(node, IRMetadata): @@ -1027,10 +1037,12 @@ elif isinstance(node, IRFunction): bytecode = generate_bytecode(node) bytecodes += bytecode - functions.append(generate_call(node)) success = bytecode is not None elif isinstance(node, IRClass): - success = True + class_output = generate_c_class(node) + classes += "\n\n/* CLASS %s */\n\n" % (node.name) + classes += class_output + success = class_output is not None if not success: print("Can't generate node: %s" % (node)) return None @@ -1039,10 +1051,7 @@ output += bytecodes output += "/* MODULE ARGS */\n\n" output += generate_module_args(module_args) - output += "\n\n/* CALLBACKS */\n\n" - output += generate_callbacks() - output += "\n\n/* STRUCTURES */\n\n" - output += generate_structures(functions) + output += classes output += "\n\n/* METADATA */\n\n" output += metadata return output