X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index 43686ae..101ff83 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -69,6 +69,8 @@ redef class ToolContext var opt_no_gcc_directive = new OptionArray("Disable a advanced gcc directives for optimization", "--no-gcc-directive") # --release var opt_release = new OptionBool("Compile in release mode and finalize application", "--release") + # -g + var opt_debug = new OptionBool("Compile in debug mode (no C-side optimization)", "--debug", "-g") redef init do @@ -80,6 +82,7 @@ redef class ToolContext self.option_context.add_option(self.opt_no_gcc_directive) self.option_context.add_option(self.opt_release) self.option_context.add_option(self.opt_max_c_lines, self.opt_group_c_files) + self.option_context.add_option(self.opt_debug) opt_no_main.hidden = true end @@ -156,10 +159,13 @@ class MakefileToolchain redef fun write_and_make do + var debug = toolcontext.opt_debug.value var compile_dir = compile_dir # Remove the compilation directory unless explicitly set var auto_remove = toolcontext.opt_compile_dir.value == null + # If debug flag is set, do not remove sources + if debug then auto_remove = false # Generate the .h and .c files # A single C file regroups many compiled rumtime functions @@ -341,8 +347,9 @@ class MakefileToolchain var libs = m.collect_linker_libs if libs != null then linker_options.add_all(libs) end + var debug = toolcontext.opt_debug.value - makefile.write("CC = ccache cc\nCXX = ccache c++\nCFLAGS = -g -O2 -Wno-unused-value -Wno-switch -Wno-attributes\nCINCL =\nLDFLAGS ?= \nLDLIBS ?= -lm {linker_options.join(" ")}\n\n") + makefile.write("CC = ccache cc\nCXX = ccache c++\nCFLAGS = -g{ if not debug then " -O2 " else " "}-Wno-unused-value -Wno-switch -Wno-attributes\nCINCL =\nLDFLAGS ?= \nLDLIBS ?= -lm {linker_options.join(" ")}\n\n") makefile.write "\n# SPECIAL CONFIGURATION FLAGS\n" if platform.supports_libunwind then @@ -389,6 +396,15 @@ endif makefile.write("CFLAGS += -D NO_STACKTRACE\n\n") end + makefile.write """ +# Special configuration for Darwin +ifeq ($(uname_S),Darwin) + # Remove POSIX flag -lrt + LDLIBS := $(filter-out -lrt,$(LDLIBS)) +endif + +""" + makefile.write("all: {outpath}\n") if outpath != real_outpath then makefile.write("\tcp -- {outpath.escape_to_sh} {real_outpath.escape_to_sh.replace("$","$$")}") @@ -638,6 +654,7 @@ abstract class AbstractCompiler self.header.add_decl("#include \n") self.header.add_decl("#include \n") self.header.add_decl("#include \n") + self.header.add_decl("#include \n") self.header.add_decl("#include \"gc_chooser.h\"") self.header.add_decl("#ifdef ANDROID") self.header.add_decl(" #include ") @@ -1130,6 +1147,7 @@ abstract class AbstractCompilerVisitor fun compile_callsite(callsite: CallSite, arguments: Array[RuntimeVariable]): nullable RuntimeVariable do + if callsite.is_broken then return null var initializers = callsite.mpropdef.initializers if not initializers.is_empty then var recv = arguments.first @@ -1490,12 +1508,56 @@ abstract class AbstractCompilerVisitor return res end + # Generate an int8 value + fun int8_instance(value: Int8): RuntimeVariable + do + var t = mmodule.int8_type + var res = new RuntimeVariable("((int8_t){value.to_s})", t, t) + return res + end + + # Generate an int16 value + fun int16_instance(value: Int16): RuntimeVariable + do + var t = mmodule.int16_type + var res = new RuntimeVariable("((int16_t){value.to_s})", t, t) + return res + end + + # Generate a uint16 value + fun uint16_instance(value: UInt16): RuntimeVariable + do + var t = mmodule.uint16_type + var res = new RuntimeVariable("((uint16_t){value.to_s})", t, t) + return res + end + + # Generate an int32 value + fun int32_instance(value: Int32): RuntimeVariable + do + var t = mmodule.int32_type + var res = new RuntimeVariable("((int32_t){value.to_s})", t, t) + return res + end + + # Generate a uint32 value + fun uint32_instance(value: UInt32): RuntimeVariable + do + var t = mmodule.uint32_type + var res = new RuntimeVariable("((uint32_t){value.to_s})", t, t) + return res + end + # Generate a char value fun char_instance(value: Char): RuntimeVariable do var t = mmodule.char_type - var res = new RuntimeVariable("'{value.to_s.escape_to_c}'", t, t) - return res + + if value.code_point < 128 then + return new RuntimeVariable("'{value.to_s.escape_to_c}'", t, t) + else + return new RuntimeVariable("{value.code_point}", t, t) + end end # Generate a float value @@ -1537,8 +1599,9 @@ abstract class AbstractCompilerVisitor var native_mtype = mmodule.native_string_type var nat = self.new_var(native_mtype) self.add("{nat} = \"{string.escape_to_c}\";") - var length = self.int_instance(string.length) - self.add("{res} = {self.send(self.get_property("to_s_with_length", native_mtype), [nat, length]).as(not null)};") + var bytelen = self.int_instance(string.bytelen) + var unilen = self.int_instance(string.length) + self.add("{res} = {self.send(self.get_property("to_s_full", native_mtype), [nat, bytelen, unilen]).as(not null)};") self.add("{name} = {res};") self.add("\}") return res @@ -1670,7 +1733,7 @@ abstract class AbstractCompilerVisitor fun stmt(nexpr: nullable AExpr) do if nexpr == null then return - if nexpr.mtype == null and not nexpr.is_typed then + if nexpr.is_broken then # Untyped expression. # Might mean dead code or invalid code # so aborts @@ -1885,8 +1948,18 @@ redef class MClassType return "uint32_t" else if mclass.name == "Float" then return "double" + else if mclass.name == "Int8" then + return "int8_t" else if mclass.name == "Byte" then return "unsigned char" + else if mclass.name == "Int16" then + return "int16_t" + else if mclass.name == "UInt16" then + return "uint16_t" + else if mclass.name == "Int32" then + return "int32_t" + else if mclass.name == "UInt32" then + return "uint32_t" else if mclass.name == "NativeString" then return "char*" else if mclass.name == "NativeArray" then @@ -1917,8 +1990,18 @@ redef class MClassType return "c" else if mclass.name == "Float" then return "d" + else if mclass.name == "Int8" then + return "i8" else if mclass.name == "Byte" then return "b" + else if mclass.name == "Int16" then + return "i16" + else if mclass.name == "UInt16" then + return "u16" + else if mclass.name == "Int32" then + return "i32" + else if mclass.name == "UInt32" then + return "u32" else if mclass.name == "NativeString" then return "str" else if mclass.name == "NativeArray" then @@ -2121,12 +2204,6 @@ redef class AMethPropdef else if pname == "%" then v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) return true - else if pname == "lshift" then - v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) - return true - else if pname == "rshift" then - v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) - return true else if pname == "==" then v.ret(v.equal_test(arguments[0], arguments[1])) return true @@ -2146,21 +2223,30 @@ redef class AMethPropdef else if pname == ">=" then v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) return true + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true else if pname == "to_f" then v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) return true else if pname == "to_b" then v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) return true - else if pname == "ascii" then - v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) - return true end else if cname == "Char" then - if pname == "output" then - v.add("printf(\"%c\", ((unsigned char){arguments.first}));") - return true - else if pname == "object_id" then + if pname == "object_id" then v.ret(v.new_expr("(long){arguments.first}", ret.as(not null))) return true else if pname == "successor" then @@ -2191,9 +2277,6 @@ redef class AMethPropdef else if pname == "to_i" then v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null))) return true - else if pname == "ascii" then - v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) - return true end else if cname == "Byte" then if pname == "output" then @@ -2223,12 +2306,6 @@ redef class AMethPropdef else if pname == "%" then v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) return true - else if pname == "lshift" then - v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) - return true - else if pname == "rshift" then - v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) - return true else if pname == "==" then v.ret(v.equal_test(arguments[0], arguments[1])) return true @@ -2254,8 +2331,20 @@ redef class AMethPropdef else if pname == "to_f" then v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) return true - else if pname == "ascii" then - v.ret(v.new_expr("{arguments[0]}", ret.as(not null))) + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) return true end else if cname == "Bool" then @@ -2329,6 +2418,21 @@ redef class AMethPropdef else if pname == "to_b" then v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) return true + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true end else if cname == "NativeString" then if pname == "[]" then @@ -2353,6 +2457,441 @@ redef class AMethPropdef else if cname == "NativeArray" then v.native_array_def(pname, ret, arguments) return true + else if cname == "Int8" then + if pname == "output" then + v.add("printf(\"%\"PRIi8 \"\\n\", {arguments.first});") + return true + else if pname == "object_id" then + v.ret(v.new_expr("(long){arguments.first}", ret.as(not null))) + return true + else if pname == "+" then + v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) + return true + else if pname == "-" then + v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary -" then + v.ret(v.new_expr("-{arguments[0]}", ret.as(not null))) + return true + else if pname == "unary +" then + v.ret(arguments[0]) + return true + else if pname == "*" then + v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null))) + return true + else if pname == "/" then + v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null))) + return true + else if pname == "%" then + v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "==" then + v.ret(v.equal_test(arguments[0], arguments[1])) + return true + else if pname == "!=" then + var res = v.equal_test(arguments[0], arguments[1]) + v.ret(v.new_expr("!{res}", ret.as(not null))) + return true + else if pname == "<" then + v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null))) + return true + else if pname == ">" then + v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null))) + return true + else if pname == "<=" then + v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null))) + return true + else if pname == ">=" then + v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) + return true + else if pname == "to_i" then + v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_b" then + v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_f" then + v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true + else if pname == "|" then + v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null))) + return true + else if pname == "^" then + v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary ~" then + v.ret(v.new_expr("~{arguments[0]}", ret.as(not null))) + return true + end + else if cname == "Int16" then + if pname == "output" then + v.add("printf(\"%\"PRIi16 \"\\n\", {arguments.first});") + return true + else if pname == "object_id" then + v.ret(v.new_expr("(long){arguments.first}", ret.as(not null))) + return true + else if pname == "+" then + v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) + return true + else if pname == "-" then + v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary -" then + v.ret(v.new_expr("-{arguments[0]}", ret.as(not null))) + return true + else if pname == "unary +" then + v.ret(arguments[0]) + return true + else if pname == "*" then + v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null))) + return true + else if pname == "/" then + v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null))) + return true + else if pname == "%" then + v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "==" then + v.ret(v.equal_test(arguments[0], arguments[1])) + return true + else if pname == "!=" then + var res = v.equal_test(arguments[0], arguments[1]) + v.ret(v.new_expr("!{res}", ret.as(not null))) + return true + else if pname == "<" then + v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null))) + return true + else if pname == ">" then + v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null))) + return true + else if pname == "<=" then + v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null))) + return true + else if pname == ">=" then + v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) + return true + else if pname == "to_i" then + v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_b" then + v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_f" then + v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true + else if pname == "|" then + v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null))) + return true + else if pname == "^" then + v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary ~" then + v.ret(v.new_expr("~{arguments[0]}", ret.as(not null))) + return true + end + else if cname == "UInt16" then + if pname == "output" then + v.add("printf(\"%\"PRIu16 \"\\n\", {arguments.first});") + return true + else if pname == "object_id" then + v.ret(v.new_expr("(long){arguments.first}", ret.as(not null))) + return true + else if pname == "+" then + v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) + return true + else if pname == "-" then + v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary -" then + v.ret(v.new_expr("-{arguments[0]}", ret.as(not null))) + return true + else if pname == "unary +" then + v.ret(arguments[0]) + return true + else if pname == "*" then + v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null))) + return true + else if pname == "/" then + v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null))) + return true + else if pname == "%" then + v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "==" then + v.ret(v.equal_test(arguments[0], arguments[1])) + return true + else if pname == "!=" then + var res = v.equal_test(arguments[0], arguments[1]) + v.ret(v.new_expr("!{res}", ret.as(not null))) + return true + else if pname == "<" then + v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null))) + return true + else if pname == ">" then + v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null))) + return true + else if pname == "<=" then + v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null))) + return true + else if pname == ">=" then + v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) + return true + else if pname == "to_i" then + v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_b" then + v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_f" then + v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true + else if pname == "|" then + v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null))) + return true + else if pname == "^" then + v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary ~" then + v.ret(v.new_expr("~{arguments[0]}", ret.as(not null))) + return true + end + else if cname == "Int32" then + if pname == "output" then + v.add("printf(\"%\"PRIi32 \"\\n\", {arguments.first});") + return true + else if pname == "object_id" then + v.ret(v.new_expr("(long){arguments.first}", ret.as(not null))) + return true + else if pname == "+" then + v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) + return true + else if pname == "-" then + v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary -" then + v.ret(v.new_expr("-{arguments[0]}", ret.as(not null))) + return true + else if pname == "unary +" then + v.ret(arguments[0]) + return true + else if pname == "*" then + v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null))) + return true + else if pname == "/" then + v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null))) + return true + else if pname == "%" then + v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "==" then + v.ret(v.equal_test(arguments[0], arguments[1])) + return true + else if pname == "!=" then + var res = v.equal_test(arguments[0], arguments[1]) + v.ret(v.new_expr("!{res}", ret.as(not null))) + return true + else if pname == "<" then + v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null))) + return true + else if pname == ">" then + v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null))) + return true + else if pname == "<=" then + v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null))) + return true + else if pname == ">=" then + v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) + return true + else if pname == "to_i" then + v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_b" then + v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u32" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_f" then + v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true + else if pname == "|" then + v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null))) + return true + else if pname == "^" then + v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary ~" then + v.ret(v.new_expr("~{arguments[0]}", ret.as(not null))) + return true + end + else if cname == "UInt32" then + if pname == "output" then + v.add("printf(\"%\"PRIu32 \"\\n\", {arguments.first});") + return true + else if pname == "object_id" then + v.ret(v.new_expr("(long){arguments.first}", ret.as(not null))) + return true + else if pname == "+" then + v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) + return true + else if pname == "-" then + v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary -" then + v.ret(v.new_expr("-{arguments[0]}", ret.as(not null))) + return true + else if pname == "unary +" then + v.ret(arguments[0]) + return true + else if pname == "*" then + v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null))) + return true + else if pname == "/" then + v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null))) + return true + else if pname == "%" then + v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "==" then + v.ret(v.equal_test(arguments[0], arguments[1])) + return true + else if pname == "!=" then + var res = v.equal_test(arguments[0], arguments[1]) + v.ret(v.new_expr("!{res}", ret.as(not null))) + return true + else if pname == "<" then + v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null))) + return true + else if pname == ">" then + v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null))) + return true + else if pname == "<=" then + v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null))) + return true + else if pname == ">=" then + v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) + return true + else if pname == "to_i" then + v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_b" then + v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i8" then + v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i16" then + v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_u16" then + v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_i32" then + v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "to_f" then + v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true + else if pname == "|" then + v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null))) + return true + else if pname == "^" then + v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null))) + return true + else if pname == "unary ~" then + v.ret(v.new_expr("~{arguments[0]}", ret.as(not null))) + return true + end end if pname == "exit" then v.add("exit({arguments[1]});") @@ -2901,12 +3440,18 @@ redef class AOrElseExpr end end -redef class AIntExpr - redef fun expr(v) do return v.int_instance(self.value.as(not null)) -end - -redef class AByteExpr - redef fun expr(v) do return v.byte_instance(self.value.as(not null)) +redef class AIntegerExpr + redef fun expr(v) do + if value isa Int then return v.int_instance(value.as(Int)) + if value isa Byte then return v.byte_instance(value.as(Byte)) + if value isa Int8 then return v.int8_instance(value.as(Int8)) + if value isa Int16 then return v.int16_instance(value.as(Int16)) + if value isa UInt16 then return v.uint16_instance(value.as(UInt16)) + if value isa Int32 then return v.int32_instance(value.as(Int32)) + if value isa UInt32 then return v.uint32_instance(value.as(UInt32)) + # Should never happen + abort + end end redef class AFloatExpr @@ -3106,6 +3651,7 @@ redef class ASendExpr do var recv = v.expr(self.n_expr, null) var callsite = self.callsite.as(not null) + if callsite.is_broken then return null var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) return v.compile_callsite(callsite, args) end @@ -3116,6 +3662,7 @@ redef class ASendReassignFormExpr do var recv = v.expr(self.n_expr, null) var callsite = self.callsite.as(not null) + if callsite.is_broken then return var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments) var value = v.expr(self.n_value, null) @@ -3138,6 +3685,7 @@ redef class ASuperExpr var callsite = self.callsite if callsite != null then + if callsite.is_broken then return null var args if self.n_args.n_exprs.is_empty then @@ -3187,6 +3735,7 @@ redef class ANewExpr var callsite = self.callsite if callsite == null then return recv + if callsite.is_broken then return null var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs) var res2 = v.compile_callsite(callsite, args) @@ -3326,7 +3875,12 @@ end # Here we load an process all modules passed on the command line var mmodules = modelbuilder.parse(arguments) -if mmodules.is_empty then return +if mmodules.is_empty then + toolcontext.check_errors + toolcontext.errors_info + if toolcontext.error_count > 0 then exit(1) else exit(0) +end + modelbuilder.run_phases for mmodule in mmodules do