if l != null then
visitor.add_indent(w)
w.add("/* ")
- w.add(l.file)
+ w.add(l.file.filename)
w.add(":")
w.add(l.line_start.to_s)
w.add(" */\n")
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})\{")
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;")
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
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]})<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 ">=".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]})<<UNTAG_Int({regs[1]}))"
+ else if n == once "rshift".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})>>UNTAG_Int({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 "Float".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = "TAG_Int((bigint)UNBOX_Float({regs[0]}))"
+ else if n == once "unary -".to_symbol then
+ s = "BOX_Float(-UNBOX_Float({regs[0]}))"
+ else if n == once "output".to_symbol then
+ s = "printf(\"%f\\n\", UNBOX_Float({regs[0]}));"
+ else if n == once "to_i".to_symbol then
+ s = "TAG_Int((bigint)UNBOX_Float({regs[0]}))"
+ else if n == once "+".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})+UNBOX_Float({regs[1]}))"
+ else if n == once "-".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})-UNBOX_Float({regs[1]}))"
+ else if n == once "*".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})*UNBOX_Float({regs[1]}))"
+ else if n == once "/".to_symbol then
+ s = "BOX_Float(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]}))"
+ 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]})<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(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
+
redef class IAbort
redef fun compile_to_c(v)
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