nitj: implement ADoExpr, AWhileExpr, ALoopExpr
authorAlexandre Terrasa <alexandre@moz-code.org>
Fri, 10 Jul 2015 05:32:01 +0000 (01:32 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Tue, 21 Jul 2015 21:23:22 +0000 (17:23 -0400)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/compiler/java_compiler.nit

index 0806fc8..eb2787b 100644 (file)
@@ -325,6 +325,26 @@ class JavaCompilerVisitor
                end
        end
 
+       # Return an unique and stable identifier associated with an escapemark
+       fun escapemark_name(e: nullable EscapeMark): String do
+               assert e != null
+               var frame = self.frame
+               assert frame != null
+               if frame.escapemark_names.has_key(e) then return frame.escapemark_names[e]
+               var name = e.name
+               if name == null then name = "label"
+               name = get_name(name)
+               frame.escapemark_names[e] = name
+               return name
+       end
+
+       # Insert a C label for associated with an escapemark
+       fun add_escape_label(e: nullable EscapeMark) do
+               if e == null then return
+               if e.escapes.is_empty then return
+               add("BREAK_{escapemark_name(e)}: ")
+       end
+
        # Variables handling
 
        # Registered variables
@@ -1128,6 +1148,10 @@ class JavaStaticFrame
 
        # The label at the end of the property
        var returnlabel: nullable String = null is writable
+
+       # Labels associated to a each escapemarks.
+       # Because of inlinings, escape-marks must be associated to their context (the frame)
+       private var escapemark_names = new HashMap[EscapeMark, String]
 end
 
 redef class Location
@@ -1946,6 +1970,44 @@ redef class AIfExpr
        end
 end
 
+redef class ADoExpr
+       redef fun stmt(v)
+       do
+               v.add_escape_label(break_mark)
+               v.add "\{"
+               v.stmt(self.n_block)
+               v.add "\}"
+       end
+end
+
+redef class AWhileExpr
+       redef fun stmt(v)
+       do
+               v.add_escape_label(break_mark)
+               v.add_escape_label(continue_mark)
+               v.add("for(;;) \{")
+               var cond = v.expr_bool(self.n_expr)
+               v.add("if (!{cond}) break;")
+               v.stmt(self.n_block)
+               v.add("\}")
+       end
+end
+
+redef class ALoopExpr
+       redef fun stmt(v)
+       do
+               v.add_escape_label(break_mark)
+               v.add_escape_label(continue_mark)
+               v.add("for(;;) \{")
+               v.stmt(self.n_block)
+               v.add("\}")
+       end
+end
+
+redef class AEscapeExpr
+       redef fun stmt(v) do v.add("break BREAK_{v.escapemark_name(escapemark)};")
+end
+
 redef class AVardeclExpr
        redef fun stmt(v) do
                var variable = self.variable.as(not null)