nitg: add clean rule in generated Makefile
[nit.git] / src / global_compiler.nit
index b6480d7..f6e7a8a 100644 (file)
@@ -59,8 +59,8 @@ redef class ModelBuilder
                v.add_decl("#include <string.h>")
 
                # TODO: Better way to activate the GC
-               #v.add_decl("#include <gc/gc.h>")
-               v.add_decl("#define GC_MALLOC(x) calloc(1, (x))")
+               v.add_decl("#include <gc/gc.h>")
+               #v.add_decl("#define GC_MALLOC(x) calloc(1, (x))")
 
                # Declare structure for each live type
 
@@ -178,13 +178,23 @@ redef class ModelBuilder
                makefile.write("all: {outname}\n\n")
 
                var ofiles = new Array[String]
+               # Compile each generated file
                for f in cfiles do
                        var o = f.strip_extension(".c") + ".o"
-                       makefile.write("{o}: {f}\n\t$(CC) $(CFLAGS) -I .nit_compile -I ../clib -c -o {o} {f}\n\n")
+                       makefile.write("{o}: {f}\n\t$(CC) $(CFLAGS) -D NONITCNI -c -o {o} {f}\n\n")
                        ofiles.add(o)
                end
-
-               makefile.write("{outname}: {ofiles.join(" ")} {compiler.extern_bodies.join(" ")}\n\t$(CC) -Wl,--warn-unresolved-symbols $(CFLAGS) $(LDFLAGS) $(LDLIBS) -I .nit_compile -I ../clib -o {outname} {ofiles.join(" ")} {compiler.extern_bodies.join(" ")}\n\n")
+               # Compile each required extern body into a specific .o
+               for f in compiler.extern_bodies do
+                       i += 1
+                       var o = ".nit_compile/{mainmodule.name}.{i}.o"
+                       makefile.write("{o}: {f}\n\t$(CC) $(CFLAGS) -D NONITCNI -c -o {o} {f}\n\n")
+                       ofiles.add(o)
+               end
+               # Link edition
+               makefile.write("{outname}: {ofiles.join(" ")}\n\t$(CC) $(LDFLAGS) $(LDLIBS) -o {outname} {ofiles.join(" ")}\n\n")
+               # Clean
+               makefile.write("clean:\n\trm {ofiles.join(" ")} 2>/dev/null\n\n")
                makefile.close
                self.toolcontext.info("Generated makefile: {makename}", 2)
 
@@ -357,7 +367,6 @@ private class GlobalCompiler
                if tryfile.file_exists then
                        self.extern_bodies.add(tryfile)
                end
-               #(new OFStream.open("{file.basename("")}._nitni.h")).close
        end
 end
 
@@ -814,6 +823,20 @@ private class GlobalCompilerVisitor
 
        private var variables: HashMap[Variable, RuntimeVariable] = new HashMap[Variable, RuntimeVariable]
 
+       # Return an unique and stable identifier associated with an escapemark
+       fun escapemark_name(e: nullable EscapeMark): String
+       do
+               assert e != null
+               if escapemark_names.has_key(e) then return escapemark_names[e]
+               var name = e.name
+               if name == null then name = "label"
+               name = get_name(name)
+               escapemark_names[e] = name
+               return name
+       end
+
+       private var escapemark_names = new HashMap[EscapeMark, String]
+
        # Return a new name based on `s' and unique in the visitor
        fun get_name(s: String): String
        do
@@ -1003,7 +1026,7 @@ private class GlobalCompilerVisitor
                                vararg.add(rawargs[i+1])
                        end
                        # FIXME: its it to late to determine the vararg type, this should have been done during a previous analysis
-                       var elttype = m.msignature.parameter_mtypes[vararg_rank]
+                       var elttype = m.msignature.mparameters[vararg_rank].mtype
                        elttype = self.resolve_for(elttype, recv)
                        args.add(self.array_instance(vararg, elttype))
 
@@ -1024,7 +1047,7 @@ private class GlobalCompilerVisitor
        do
                var recv = args.first
                for i in [0..m.msignature.arity[ do
-                       var t = m.msignature.parameter_mtypes[i]
+                       var t = m.msignature.mparameters[i].mtype
                        if i == m.msignature.vararg_rank then
                                t = args[i+1].mtype
                        end
@@ -1260,9 +1283,9 @@ private class GlobalCompilerVisitor
        fun add_abort(message: String)
        do
                if self.current_node != null and self.current_node.location.file != null then
-                       self.add("fprintf(stderr, \"%s (%s:%d)\\n\", \"{message.escape_to_c}\", \"{self.current_node.location.file.filename.escape_to_c}\", {current_node.location.line_start});")
+                       self.add("fprintf(stderr, \"Runtime error: %s (%s:%d)\\n\", \"{message.escape_to_c}\", \"{self.current_node.location.file.filename.escape_to_c}\", {current_node.location.line_start});")
                else
-                       self.add("fprintf(stderr, \"%s\\n\", \"{message.escape_to_c}\");")
+                       self.add("fprintf(stderr, \"Runtime error: %s\\n\", \"{message.escape_to_c}\");")
                end
                self.add("exit(1);")
        end
@@ -1374,7 +1397,7 @@ redef class MMethodDef
                comment.append("(self: {recv}")
                arguments.add(selfvar)
                for i in [0..self.msignature.arity[ do
-                       var mtype = self.msignature.parameter_mtypes[i]
+                       var mtype = self.msignature.mparameters[i].mtype
                        if i == self.msignature.vararg_rank then
                                mtype = v.get_class("Array").get_mtype([mtype])
                        end
@@ -1420,7 +1443,7 @@ end
 redef class APropdef
        private fun compile_to_c(v: GlobalCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
        do
-               v.add("printf(\"Not implemented {class_name} {mpropdef} at {location.to_s}\\n\");")
+               v.add("printf(\"NOT YET IMPLEMENTED {class_name} {mpropdef} at {location.to_s}\\n\");")
                debug("Not yet implemented")
        end
 
@@ -1724,7 +1747,7 @@ redef class AInternMethPropdef
                        end
                        return
                end
-               v.add("printf(\"Not implemented {class_name}:{mpropdef} at {location.to_s}\\n\");")
+               v.add("printf(\"NOT IMPLEMENTED {class_name}:{mpropdef} at {location.to_s}\\n\");")
                debug("Not implemented {mpropdef}")
        end
 end
@@ -1851,7 +1874,7 @@ redef class AExpr
        private fun expr(v: GlobalCompilerVisitor): nullable RuntimeVariable
        do
                debug("Unimplemented expr {class_name}")
-               v.add("printf(\"Not implemented {class_name}:{location.to_s}\\n\");")
+               v.add("printf(\"NOT YET IMPLEMENTED {class_name}:{location.to_s}\\n\");")
                var mtype = self.mtype
                if mtype == null then
                        return null
@@ -1933,14 +1956,14 @@ end
 redef class AContinueExpr
        redef fun stmt(v)
        do
-               v.add("goto CONTINUE_{self.escapemark.object_id};")
+               v.add("goto CONTINUE_{v.escapemark_name(self.escapemark)};")
        end
 end
 
 redef class ABreakExpr
        redef fun stmt(v)
        do
-               v.add("goto BREAK_{self.escapemark.object_id};")
+               v.add("goto BREAK_{v.escapemark_name(self.escapemark)};")
        end
 end
 
@@ -1996,7 +2019,7 @@ redef class ADoExpr
                v.stmt(self.n_block)
                var escapemark = self.escapemark
                if escapemark != null then
-                       v.add("BREAK_{escapemark.object_id}: (void)0;")
+                       v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
                end
        end
 end
@@ -2008,9 +2031,9 @@ redef class AWhileExpr
                var cond = v.expr_bool(self.n_expr)
                v.add("if (!{cond}) break;")
                v.stmt(self.n_block)
-               v.add("CONTINUE_{escapemark.object_id}: (void)0;")
+               v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;")
                v.add("\}")
-               v.add("BREAK_{escapemark.object_id}: (void)0;")
+               v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
        end
 end
 
@@ -2019,9 +2042,9 @@ redef class ALoopExpr
        do
                v.add("for(;;) \{")
                v.stmt(self.n_block)
-               v.add("CONTINUE_{escapemark.object_id}: (void)0;")
+               v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;")
                v.add("\}")
-               v.add("BREAK_{escapemark.object_id}: (void)0;")
+               v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
        end
 end
 
@@ -2035,14 +2058,25 @@ redef class AForExpr
                var ok = v.send(v.get_property("is_ok", it.mtype), [it])
                assert ok != null
                v.add("if(!{ok}) break;")
-               var i = v.send(v.get_property("item", it.mtype), [it])
-               assert i != null
-               v.assign(v.variable(variables.first), i)
+               if self.variables.length == 1 then
+                       var i = v.send(v.get_property("item", it.mtype), [it])
+                       assert i != null
+                       v.assign(v.variable(variables.first), i)
+               else if self.variables.length == 2 then
+                       var i = v.send(v.get_property("key", it.mtype), [it])
+                       assert i != null
+                       v.assign(v.variable(variables[0]), i)
+                       i = v.send(v.get_property("item", it.mtype), [it])
+                       assert i != null
+                       v.assign(v.variable(variables[1]), i)
+               else
+                       abort
+               end
                v.stmt(self.n_block)
-               v.add("CONTINUE_{escapemark.object_id}: (void)0;")
+               v.add("CONTINUE_{v.escapemark_name(escapemark)}: (void)0;")
                v.send(v.get_property("next", it.mtype), [it])
                v.add("\}")
-               v.add("BREAK_{escapemark.object_id}: (void)0;")
+               v.add("BREAK_{v.escapemark_name(escapemark)}: (void)0;")
        end
 end
 
@@ -2290,7 +2324,7 @@ redef class ASendExpr
        do
                var recv = v.expr(self.n_expr, null)
                var args = [recv]
-               for a in compute_raw_arguments do
+               for a in self.raw_arguments.as(not null) do
                        args.add(v.expr(a, null))
                end
                var mproperty = self.mproperty.as(not null)
@@ -2303,7 +2337,7 @@ redef class ASendReassignFormExpr
        do
                var recv = v.expr(self.n_expr, null)
                var args = [recv]
-               for a in compute_raw_arguments do
+               for a in self.raw_arguments.as(not null) do
                        args.add(v.expr(a, null))
                end
                var value = v.expr(self.n_value, null)