X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/flow.nit b/src/semantize/flow.nit index 65f5c7b..b0e833a 100644 --- a/src/semantize/flow.nit +++ b/src/semantize/flow.nit @@ -20,6 +20,7 @@ module flow import scope redef class ToolContext + # Run `APropdef::do_flow` on each propdef var flow_phase: Phase = new FlowPhase(self, [scope_phase]) end @@ -33,19 +34,17 @@ end private class FlowVisitor super Visitor - var current_flow_context: FlowContext + var current_flow_context = new FlowContext var toolcontext: ToolContext - init(toolcontext: ToolContext) + init do - self.toolcontext = toolcontext - current_flow_context = new FlowContext flows.add(current_flow_context) current_flow_context.is_start = true end - var first: nullable ANode + var first: nullable ANode = null redef fun visit(node) do @@ -78,8 +77,8 @@ private class FlowVisitor fun printflow do - var file = new OFStream.open("flow.dot") - file.write("digraph \{\n") + var file = new FileWriter.open("flow.dot") + file.write("digraph \{\nnode[shape=box];") for f in flows do var s = "" if f.node isa AExpr then @@ -87,13 +86,14 @@ private class FlowVisitor end file.write "F{f.object_id} [label=\"{f.object_id}\\n{f.node.location}\\n{f.node.class_name}\\n{f.name}{s}\"];\n" for p in f.previous do - file.write "F{p.object_id} -> F{f.object_id};\n" + s = "" + if f.when_true == p then s = "[label=TRUE, style=dotted]" + if f.when_false == p then s = "[label=FALSE, style=dotted]" + if f.when_true == p and f.when_false == p then s = "[label=TRUE_FALSE, style=dotted]" + file.write "F{p.object_id} -> F{f.object_id}{s};\n" end - if f.when_true != f then - file.write "F{f.object_id} -> F{f.when_true.object_id}[label=TRUE, style=dotted];\n" - end - if f.when_false != f then - file.write "F{f.object_id} -> F{f.when_false.object_id}[label=FALSE,style=dotted];\n" + for p in f.loops do + file.write "F{p.object_id} -> F{f.object_id}[label=LOOP, style=dashed, constraint=false];\n" end end file.write("\}\n") @@ -165,7 +165,7 @@ private class FlowVisitor fun merge_continues_to(before_loop: FlowContext, escapemark: nullable EscapeMark) do if escapemark == null then return - for b in escapemark.continues do + for b in escapemark.escapes do var before = b.before_flow_context if before == null then continue # Forward error before_loop.add_loop(before) @@ -175,7 +175,7 @@ private class FlowVisitor fun merge_breaks(escapemark: nullable EscapeMark) do if escapemark == null then return - for b in escapemark.breaks do + for b in escapemark.escapes do var before = b.before_flow_context if before == null then continue # Forward error self.make_merge_flow(self.current_flow_context, before) @@ -346,7 +346,7 @@ redef class ADoExpr redef fun accept_flow_visitor(v) do super - v.merge_breaks(self.escapemark) + v.merge_breaks(self.break_mark) end end @@ -396,10 +396,10 @@ redef class AWhileExpr var after_block = v.current_flow_context before_loop.add_loop(after_block) - v.merge_continues_to(after_block, self.escapemark) + v.merge_continues_to(before_loop, self.continue_mark) v.current_flow_context = after_expr.when_false - v.merge_breaks(self.escapemark) + v.merge_breaks(self.break_mark) end end @@ -413,10 +413,10 @@ redef class ALoopExpr var after_block = v.current_flow_context before_loop.add_loop(after_block) - v.merge_continues_to(after_block, self.escapemark) + v.merge_continues_to(before_loop, self.continue_mark) v.make_unreachable_flow - v.merge_breaks(self.escapemark) + v.merge_breaks(self.break_mark) end end @@ -432,10 +432,18 @@ redef class AForExpr var after_block = v.current_flow_context before_loop.add_loop(after_block) - v.merge_continues_to(after_block, self.escapemark) + v.merge_continues_to(before_loop, self.continue_mark) v.make_merge_flow(v.current_flow_context, before_loop) - v.merge_breaks(self.escapemark) + v.merge_breaks(self.break_mark) + end +end + +redef class AWithExpr + redef fun accept_flow_visitor(v) + do + super + v.merge_breaks(self.break_mark) end end @@ -538,7 +546,15 @@ redef class AIsaExpr end end -redef class AProxyExpr +redef class AParExpr + redef fun accept_flow_visitor(v) + do + var after_expr = v.visit_expr(self.n_expr) + v.current_flow_context = after_expr + end +end + +redef class AOnceExpr redef fun accept_flow_visitor(v) do var after_expr = v.visit_expr(self.n_expr)