X-Git-Url: http://nitlanguage.org diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index 17a70d2..3238811 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -266,7 +266,7 @@ redef class IRoutine else p = cparams.join(", ") end - if human_name != null then v.add_decl("#define LOCATE_{cname} \"{human_name}\"") + if human_name != null then v.add_decl("static const char * const LOCATE_{cname} = \"{human_name}\";") v.add_decl("{r} {cname}({p});") v.add_decl("typedef {r} (*{cname}_t)({p});") v.add_instr("{r} {cname}({p})\{") @@ -289,7 +289,7 @@ redef class IRoutine v.add_decl("struct \{struct stack_frame_t me;\} fra;") end v.add_instr("fra.me.prev = stack_frame_head; stack_frame_head = &fra.me;") - v.add_instr("fra.me.file = LOCATE_{v.visitor.module.name};") + v.add_instr("fra.me.file = LOCATE_{v.visitor.mmmodule.name};") v.add_instr("fra.me.line = {ll};") v.add_instr("fra.me.meth = LOCATE_{v.basecname};") v.add_instr("fra.me.has_broke = 0;") @@ -577,16 +577,10 @@ redef class ICall var w = new Writer var prop = property if prop.global.is_init then args.add("init_table") - if prop.name == (once ("add".to_symbol)) and prop.local_class.name == (once ("Array".to_symbol)) then - w.add(prop.cname) - w.add("(") - else - w.add(prop.global.meth_call) - w.add("(") - w.add(args.first) - w.add(")(") - end - var first = true + w.add(prop.global.meth_call) + w.add("(") + w.add(args.first) + w.add(")(") w.add_all(args, ", ") w.add(")") return w @@ -679,20 +673,258 @@ redef class INative redef fun compile_to_c(v) do v.add_location(location) - var w = new_result(v) - if exprs.is_empty then - w.add(code) + if method.is_intern then + compile_intern_method_to_c(v) else - var i = 0 - var c = code.split_with("@@@") - for s in c do - w.add(s) - if i < exprs.length and i < c.length-1 then - w.add(v.register(exprs[i])) - end - i += 1 + compile_extern_method_to_c(v) + end + end + + fun compile_extern_method_to_c(v: I2CCompilerVisitor) + do + var ename = method.extern_name.as(not null)#"{method.module.name}_{method.local_class.name}_{method.local_class.name}_{method.name}_{method.signature.arity}" + var sig = method.signature + assert exprs.length == sig.arity + 1 + + var regs = v.registers(exprs) + + var args = new Array[String] + args.add(sig.recv.unboxtype(regs[0])) + for i in [0..sig.arity[ do + args.add(sig[i].unboxtype(regs[i+1])) + end + var s = "{ename}({args.join(", ")})" + + if need_result then s = sig.return_type.boxtype(s) + var w = new_result(v) + w.add(s) + end + + fun compile_intern_method_to_c(v: I2CCompilerVisitor) + do + var sig = method.signature + assert exprs.length == sig.arity + 1 + var c = method.local_class.name + var n = method.name + var regs = v.registers(exprs) + var s: nullable String = null + if c == once "Int".to_symbol then + if n == once "object_id".to_symbol then + s = regs[0] + else if n == once "unary -".to_symbol then + s = "TAG_Int(-UNTAG_Int({regs[0]}))" + else if n == once "output".to_symbol then + s = "printf(\"%ld\\n\", UNTAG_Int({regs[0]}));" + else if n == once "ascii".to_symbol then + s = "TAG_Char(UNTAG_Int({regs[0]}))" + else if n == once "succ".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})+1)" + else if n == once "prec".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})-1)" + else if n == once "to_f".to_symbol then + s = "BOX_Float((float)UNTAG_Int({regs[0]}))" + else if n == once "+".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})+UNTAG_Int({regs[1]}))" + else if n == once "-".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})-UNTAG_Int({regs[1]}))" + else if n == once "*".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})*UNTAG_Int({regs[1]}))" + else if n == once "/".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})/UNTAG_Int({regs[1]}))" + else if n == once "%".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})%UNTAG_Int({regs[1]}))" + else if n == once "<".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})>UNTAG_Int({regs[1]}))" + else if n == once "<=".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})<=UNTAG_Int({regs[1]}))" + else if n == once ">=".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})>=UNTAG_Int({regs[1]}))" + else if n == once "lshift".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})<".to_symbol then + s = "TAG_Bool(UNBOX_Float({regs[0]})>UNBOX_Float({regs[1]}))" + else if n == once "<=".to_symbol then + s = "TAG_Bool(UNBOX_Float({regs[0]})<=UNBOX_Float({regs[1]}))" + else if n == once ">=".to_symbol then + s = "TAG_Bool(UNBOX_Float({regs[0]})>=UNBOX_Float({regs[1]}))" + end + else if c == once "Char".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(UNTAG_Char({regs[0]}))" + else if n == once "unary -".to_symbol then + s = "TAG_Char(-UNTAG_Char({regs[0]}))" + else if n == once "output".to_symbol then + s = "printf(\"%c\", (unsigned char)UNTAG_Char({regs[0]}));" + else if n == once "ascii".to_symbol then + s = "TAG_Int((unsigned char)UNTAG_Char({regs[0]}))" + else if n == once "succ".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})+1)" + else if n == once "prec".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})-1)" + else if n == once "to_i".to_symbol then + s = "TAG_Int(UNTAG_Char({regs[0]})-'0')" + else if n == once "+".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})+UNTAG_Char({regs[1]}))" + else if n == once "-".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})-UNTAG_Char({regs[1]}))" + else if n == once "*".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})*UNTAG_Char({regs[1]}))" + else if n == once "/".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})/UNTAG_Char({regs[1]}))" + else if n == once "%".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})%UNTAG_Char({regs[1]}))" + else if n == once "<".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})>UNTAG_Char({regs[1]}))" + else if n == once "<=".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})<=UNTAG_Char({regs[1]}))" + else if n == once ">=".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})>=UNTAG_Char({regs[1]}))" + else if n == once "==".to_symbol then + s = "TAG_Bool(({regs[0]})==({regs[1]}))" + else if n == once "!=".to_symbol then + s = "TAG_Bool(({regs[0]})!=({regs[1]}))" + end + else if c == once "Bool".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(UNTAG_Bool({regs[0]}))" + else if n == once "unary -".to_symbol then + s = "TAG_Bool(-UNTAG_Bool({regs[0]}))" + else if n == once "output".to_symbol then + s = "(void)printf(UNTAG_Bool({regs[0]})?\"true\\n\":\"false\\n\");" + else if n == once "ascii".to_symbol then + s = "TAG_Bool(UNTAG_Bool({regs[0]}))" + else if n == once "to_i".to_symbol then + s = "TAG_Int(UNTAG_Bool({regs[0]}))" + else if n == once "==".to_symbol then + s = "TAG_Bool(({regs[0]})==({regs[1]}))" + else if n == once "!=".to_symbol then + s = "TAG_Bool(({regs[0]})!=({regs[1]}))" + end + else if c == once "NativeArray".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(((Nit_NativeArray){regs[0]})->object_id)" + else if n == once "[]".to_symbol then + s = "((Nit_NativeArray){regs[0]})->val[UNTAG_Int({regs[1]})]" + else if n == once "[]=".to_symbol then + s = "((Nit_NativeArray){regs[0]})->val[UNTAG_Int({regs[1]})]={regs[2]}" + else if n == once "copy_to".to_symbol then + s = "(void)memcpy(((Nit_NativeArray ){regs[1]})->val, ((Nit_NativeArray){regs[0]})->val, UNTAG_Int({regs[2]})*sizeof(val_t))" + end + else if c == once "NativeString".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(UNBOX_NativeString({regs[0]}))" + else if n == once "atoi".to_symbol then + s = "TAG_Int(atoi(UNBOX_NativeString({regs[0]})))" + else if n == once "[]".to_symbol then + s = "TAG_Char(UNBOX_NativeString({regs[0]})[UNTAG_Int({regs[1]})])" + else if n == once "[]=".to_symbol then + s = "UNBOX_NativeString({regs[0]})[UNTAG_Int({regs[1]})]=UNTAG_Char({regs[2]});" + else if n == once "copy_to".to_symbol then + s = "(void)memcpy(UNBOX_NativeString({regs[1]})+UNTAG_Int({regs[4]}), UNBOX_NativeString({regs[0]})+UNTAG_Int({regs[3]}), UNTAG_Int({regs[2]}));" + end + else if n == once "object_id".to_symbol then + s = "TAG_Int((bigint)((obj_t){regs[0]})[1].object_id)" + else if n == once "sys".to_symbol then + s = "(G_sys)" + else if n == once "is_same_type".to_symbol then + s = "TAG_Bool((VAL2VFT({regs[0]})==VAL2VFT({regs[1]})))" + else if n == once "exit".to_symbol then + s = "exit(UNTAG_Int({regs[1]}));" + else if n == once "calloc_array".to_symbol then + s = "NEW_NativeArray(UNTAG_Int({regs[1]}), sizeof(val_t))" + else if n == once "calloc_string".to_symbol then + s = "BOX_NativeString((char*)raw_alloc((UNTAG_Int({regs[1]}) * sizeof(char))))" end + if s == null then + var ll = location + if ll != null then v.add_instr("fprintf(stderr, \"{ll.to_s}: \");") + v.add_instr("fprintf(stderr, \"Fatal error: unknown intern method {method.full_name}.\\n\");") + v.add_instr("nit_exit(1);") + s = "NIT_NULL" + end + if result == null then + v.new_instr.add(s).add(";\n") + else if need_result then + var w = new_result(v) + w.add(s) + end + end +end + +redef class IIntValue + redef fun compile_to_c(v) + do + v.add_location(location) + var w = new_result(v) + w.add("TAG_Int(").add(value.to_s).add(")") + end +end + +redef class IBoolValue + redef fun compile_to_c(v) + do + v.add_location(location) + var w = new_result(v) + w.add("TAG_Bool(") + if value then w.add("true") else w.add("false") + w.add(")") + end +end + +redef class ICharValue + redef fun compile_to_c(v) + do + v.add_location(location) + var w = new_result(v) + w.add("TAG_Char(").add(value).add(")") + end +end + +redef class IFloatValue + redef fun compile_to_c(v) + do + v.add_location(location) + var w = new_result(v) + w.add("BOX_Float(").add(value).add(")") + end +end + +redef class IStringValue + redef fun compile_to_c(v) + do + v.add_location(location) + var w = new_result(v) + w.add("BOX_NativeString(\"").add(value).add("\")") end end @@ -701,29 +933,25 @@ redef class IAbort do v.add_location(location) var w = v.new_instr - w.add("fprintf(stderr") - for t in texts do - w.add(", \"") - w.add(t) + w.add("nit_abort(\"") + w.add(texts[0]) + if texts.length > 1 then + w.add("\", \"") + w.add(texts[1]) w.add("\"") + else + w.add("\", NULL") end - w.add(");\n") - - var ll = location - w = v.new_instr - w.add("fprintf(stderr, \" (%s") - if ll != null then - w.add(":%d") - end - w.add(")\\n\", LOCATE_") + w.add(", LOCATE_") w.add(module_location.name.to_s) + var ll = location if ll != null then w.add(", ") w.add(ll.line_start.to_s) + else + w.add(", 0") end w.add(");\n") - - v.add_instr("nit_exit(1);") end end @@ -788,18 +1016,16 @@ redef class ITypeCheck redef fun compile_to_c(v) do if not need_result then return - # FIXME handle formaltypes v.add_location(location) - var g = stype.local_class.global - var recv = v.register(expr) + var recv = v.register(expr2) var w = new_result(v) w.add("TAG_Bool(") - if expr.stype.is_nullable then + if expr2.stype.is_nullable then if stype.is_nullable then w.add("(") w.add(recv) w.add("==NIT_NULL) || ") - else if stype.as_nullable == expr.stype then + else if stype.as_nullable == expr2.stype then w.add(recv) w.add("!=NIT_NULL)") return @@ -809,15 +1035,38 @@ redef class ITypeCheck w.add("!=NIT_NULL) && ") end end - w.add("VAL_ISA(") - w.add(recv) - w.add(", ") - w.add(g.color_id) - w.add(", ") - w.add(g.id_id) - w.add(")) /*cast ") - w.add(stype.to_s) - w.add("*/") + # FIXME handle formaltypes + var t = stype + if t isa MMVirtualType then + var slf = v.register(expr1) + var g = t.property.global + w.add("VAL_ISA(") + w.add(recv) + w.add(", ") + w.add(g.vt_class_color) + w.add("(") + w.add(slf) + w.add(")") + w.add(", ") + w.add(g.vt_class_id) + w.add("(") + w.add(slf) + w.add(")") + w.add(")) /*cast ") + w.add(t.to_s) + w.add("*/") + else + var g = t.local_class.global + w.add("VAL_ISA(") + w.add(recv) + w.add(", ") + w.add(g.color_id) + w.add(", ") + w.add(g.id_id) + w.add(")) /*cast ") + w.add(t.to_s) + w.add("*/") + end end end