X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/flow.nit b/src/semantize/flow.nit index 522a347..3d27623 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") @@ -263,10 +263,10 @@ redef class APropdef # The starting flow - var before_flow_context: nullable FlowContext + var before_flow_context: nullable FlowContext is noautoinit # The ending flow - var after_flow_context: nullable FlowContext + var after_flow_context: nullable FlowContext is noautoinit redef fun accept_flow_visitor(v) do @@ -345,8 +345,22 @@ end redef class ADoExpr redef fun accept_flow_visitor(v) do - super + # FlowContext before the block + var before_block = v.make_sub_flow + + # Visit the bloc, then merge the breaks + v.enter_visit(self.n_block) v.merge_breaks(self.break_mark) + var after_block = v.current_flow_context + + # Visit the catch if there is one + if self.n_catch != null then + var before_catch = v.make_sub_flow + v.make_merge_flow(before_block, after_block) + v.enter_visit(self.n_catch) + var after_catch = v.current_flow_context + v.make_merge_flow(before_catch, after_catch) + end end end @@ -396,7 +410,7 @@ redef class AWhileExpr var after_block = v.current_flow_context before_loop.add_loop(after_block) - v.merge_continues_to(after_block, self.continue_mark) + v.merge_continues_to(before_loop, self.continue_mark) v.current_flow_context = after_expr.when_false v.merge_breaks(self.break_mark) @@ -413,7 +427,7 @@ redef class ALoopExpr var after_block = v.current_flow_context before_loop.add_loop(after_block) - v.merge_continues_to(after_block, self.continue_mark) + v.merge_continues_to(before_loop, self.continue_mark) v.make_unreachable_flow v.merge_breaks(self.break_mark) @@ -423,7 +437,9 @@ end redef class AForExpr redef fun accept_flow_visitor(v) do - v.enter_visit(self.n_expr) + for g in n_groups do + v.enter_visit(g.n_expr) + end var before_loop = v.make_sub_flow @@ -432,13 +448,21 @@ redef class AForExpr var after_block = v.current_flow_context before_loop.add_loop(after_block) - v.merge_continues_to(after_block, self.continue_mark) + v.merge_continues_to(before_loop, self.continue_mark) v.make_merge_flow(v.current_flow_context, before_loop) 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 + redef class AAssertExpr redef fun accept_flow_visitor(v) do