end
v.add("\}")
+ # compile class structures
for m in mainmodule.in_importation.greaters do
- compiler.compile_module_to_c(m)
for mclass in m.intro_mclasses do
compiler.compile_class_to_c(mclass)
end
end
+ # compile methods
+ for m in mainmodule.in_importation.greaters do
+ compiler.compile_module_to_c(m)
+ end
+
# compile live & cast type structures
var mtypes = compiler.do_global_type_coloring
for t in mtypes do
compiler.compile_type_to_c(t)
end
+ # compile live generic types selection structures
for mclass in model.mclasses do
compiler.compile_live_gentype_to_c(mclass)
end
return
end
+ var is_native_array = mclass.name == "NativeArray"
+
+ var sig
+ if is_native_array then
+ sig = "int length, struct type* type"
+ else
+ sig = "struct type* type"
+ end
+
#Build instance struct
- v.add_decl("struct instance_{c_name} \{")
- v.add_decl("const struct type *type;")
- v.add_decl("const struct class *class;")
- v.add_decl("nitattribute_t attrs[{attrs.length}];")
- v.add_decl("\};")
+ #extern const struct instance_array__NativeArray instance_array__NativeArray;
+ self.header.add_decl("struct instance_{c_name} \{")
+ self.header.add_decl("const struct type *type;")
+ self.header.add_decl("const struct class *class;")
+ self.header.add_decl("nitattribute_t attrs[{attrs.length}];")
+ if is_native_array then
+ # NativeArrays are just a instance header followed by an array of values
+ self.header.add_decl("val* values[0];")
+ end
+ self.header.add_decl("\};")
+ self.header.add_decl("{mtype.ctype} NEW_{c_name}({sig});")
+ v.add_decl("/* allocate {mtype} */")
+ v.add_decl("{mtype.ctype} NEW_{c_name}({sig}) \{")
var res = v.new_named_var(mtype, "self")
res.is_exact = true
-
- self.header.add_decl("{mtype.ctype} NEW_{c_name}(struct type* type);")
- v.add_decl("/* allocate {mtype} */")
- v.add_decl("{mtype.ctype} NEW_{c_name}(struct type* type) \{")
- v.add("{res} = calloc(sizeof(struct instance_{c_name}), 1);")
+ if is_native_array then
+ var mtype_elt = mtype.arguments.first
+ v.add("{res} = GC_MALLOC(sizeof(struct instance_{c_name}) + length*sizeof({mtype_elt.ctype}));")
+ else
+ v.add("{res} = GC_MALLOC(sizeof(struct instance_{c_name}));")
+ end
+ #v.add("{res} = calloc(sizeof(struct instance_{c_name}), 1);")
v.add("{res}->type = type;")
v.add("{res}->class = (struct class*) &class_{c_name};")
var res = self.new_var(bool_type)
var buff = new Buffer
- if mtype isa MNullableType then mtype = mtype.mtype
+ var s: String
+ if mtype isa MNullableType then
+ mtype = mtype.mtype
+ s = "{value} == NULL ||"
+ else
+ s = "{value} != NULL &&"
+ end
if mtype isa MGenericType and mtype.need_anchor then
for ft in mtype.mclass.mclass_type.arguments do
var ftcolor = compiler.ft_colors[ft.as(MParameterType)]
buff.append("[self->type->fts_table->fts[{ftcolor}]->id]")
end
- self.add("{res} = {value}->type->type_table[livetypes_{mtype.mclass.c_name}{buff.to_s}->color] == livetypes_{mtype.mclass.c_name}{buff.to_s}->id;")
+ self.add("{res} = {s} {value}->type->type_table[livetypes_{mtype.mclass.c_name}{buff.to_s}->color] == livetypes_{mtype.mclass.c_name}{buff.to_s}->id;")
else if mtype isa MClassType then
compiler.undead_types.add(mtype)
- self.add("{res} = {value}->type->type_table[type_{mtype.c_name}.color] == type_{mtype.c_name}.id;")
+ self.add("{res} = {s} {value}->type->type_table[type_{mtype.c_name}.color] == type_{mtype.c_name}.id;")
else if mtype isa MParameterType then
var ftcolor = compiler.ft_colors[mtype]
- self.add("{res} = {value}->type->type_table[self->type->fts_table->fts[{ftcolor}]->color] == self->type->fts_table->fts[{ftcolor}]->id;")
+ self.add("{res} = {s} {value}->type->type_table[self->type->fts_table->fts[{ftcolor}]->color] == self->type->fts_table->fts[{ftcolor}]->id;")
+ else
+ add("printf(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); exit(1);")
end
return res
redef fun is_same_type_test(value1, value2)
do
var res = self.new_var(bool_type)
- # TODO
- add("printf(\"NOT YET IMPLEMENTED: is_same_type(%s,%s).\\n\", \"{value1.inspect}\", \"{value2.inspect}\"); exit(1);")
+ # Swap values to be symetric
+ if value2.mtype.ctype != "val*" and value1.mtype.ctype == "val*" then
+ var tmp = value1
+ value1 = value2
+ value2 = tmp
+ end
+ if value1.mtype.ctype != "val*" then
+ if value2.mtype.ctype == value1.mtype.ctype then
+ self.add("{res} = 1; /* is_same_type_test: compatible types {value1.mtype} vs. {value2.mtype} */")
+ else if value2.mtype.ctype != "val*" then
+ self.add("{res} = 0; /* is_same_type_test: incompatible types {value1.mtype} vs. {value2.mtype}*/")
+ else
+ var mtype1 = value1.mtype.as(MClassType)
+ self.add("{res} = ({value2} != NULL) && ({value2}->class == (struct class*) &class_{mtype1.c_name}); /* is_same_type_test */")
+ end
+ else
+ self.add("{res} = ({value1} == {value2}) || ({value1} != NULL && {value2} != NULL && {value1}->class == {value2}->class); /* is_same_type_test */")
+ end
return res
end
self.add("\}")
end
else
- self.add("{res} = {value1} == {value2};")
+ var s = new Array[String]
+ # This is just ugly on so many level. this works but must be rewriten
+ for t in self.compiler.live_primitive_types do
+ if not t.is_subtype(self.compiler.mainmodule, null, value1.mcasttype) then continue
+ if not t.is_subtype(self.compiler.mainmodule, null, value2.mcasttype) then continue
+ s.add "({value1}->class == (struct class*)&class_{t.c_name} && ((struct instance_{t.c_name}*){value1})->value == ((struct instance_{t.c_name}*){value2})->value)"
+ end
+ if s.is_empty then
+ self.add("{res} = {value1} == {value2};")
+ else
+ self.add("{res} = {value1} == {value2} || ({value1} != NULL && {value2} != NULL && {value1}->class == {value2}->class && ({s.join(" || ")}));")
+ end
end
return res
end
+
+ redef fun array_instance(array, elttype)
+ do
+ var compiler = self.compiler.as(SeparateCompiler)
+ var nclass = self.get_class("NativeArray")
+ elttype = self.anchor(elttype)
+ var arraytype = self.get_class("Array").get_mtype([elttype])
+ var res = self.init_instance(arraytype)
+ self.add("\{ /* {res} = array_instance Array[{elttype}] */")
+ var nat = self.new_var(self.get_class("NativeArray").get_mtype([elttype]))
+ nat.is_exact = true
+ compiler.undead_types.add(nat.mtype.as(MClassType))
+ self.add("{nat} = NEW_{nclass.c_name}({array.length}, (struct type *) &type_{nat.mtype.c_name});")
+ for i in [0..array.length[ do
+ var r = self.autobox(array[i], self.object_type)
+ self.add("((struct instance_{nclass.c_name}*){nat})->values[{i}] = (val*) {r};")
+ end
+ var length = self.int_instance(array.length)
+ self.send(self.get_property("with_native", arraytype), [res, nat, length])
+ self.check_init_instance(res)
+ self.add("\}")
+ return res
+ end
+
+ redef fun native_array_def(pname, ret_type, arguments)
+ do
+ var elttype = arguments.first.mtype
+ var nclass = self.get_class("NativeArray")
+ var recv = "((struct instance_{nclass.c_name}*){arguments[0]})->values"
+ if pname == "[]" then
+ self.ret(self.new_expr("{recv}[{arguments[1]}]", ret_type.as(not null)))
+ return
+ else if pname == "[]=" then
+ self.add("{recv}[{arguments[1]}]={arguments[2]};")
+ return
+ else if pname == "copy_to" then
+ var recv1 = "((struct instance_{nclass.c_name}*){arguments[1]})->values"
+ self.add("memcpy({recv1}, {recv}, {arguments[2]}*sizeof({elttype.ctype}));")
+ return
+ end
+ end
+
+ redef fun calloc_array(ret_type, arguments)
+ do
+ var ret = ret_type.as(MClassType)
+ var compiler = self.compiler.as(SeparateCompiler)
+ compiler.undead_types.add(ret)
+ self.ret(self.new_expr("NEW_{ret.mclass.c_name}({arguments[1]}, (struct type*) &type_{ret_type.c_name})", ret_type))
+ end
end
redef class MClass