package coreVisitors; import java.util.HashSet; import java.util.List; import java.util.Set; import tools.Assertions; import ast.ExpCore; import ast.Ast.Path; import ast.ExpCore.Block; import ast.ExpCore.Block.On; import ast.ExpCore.ClassB; import ast.ExpCore.Loop; import ast.ExpCore.MCall; import ast.ExpCore.Signal; import ast.ExpCore.Using; import ast.ExpCore.WalkBy; import ast.ExpCore.X; import ast.ExpCore._void; public class FreeVariables implements Visitor<Set<String>>{ private HashSet<String> collected=new HashSet<String>(); private HashSet<String> inScope=new HashSet<String>(); public static Set<String> of(ExpCore e){ return e.accept(new FreeVariables()); } public static Set<String> ofBlock(Block s){ return new FreeVariables().inBlock(s); } public Set<String> visit(X s) { if(!inScope.contains(s.getInner())){ collected.add(s.getInner()); } return collected; } public Set<String> visit(Using s) { for(ExpCore e:s.getEs()){e.accept(this);} return s.getInner().accept(this); } public Set<String> visit(Signal s) { return s.getInner().accept(this); } public Set<String> visit(Loop s) { return s.getInner().accept(this); } @Override public Set<String> visit(MCall s) { for(ExpCore e:s.getEs()){e.accept(this);} return s.getInner().accept(this); } private void visitK(List<On> k) { for(On on:k){ inScope.add(on.getX()); on.getInner().accept(this); inScope.remove(on.getX()); } } @Override public Set<String> visit(Block s) { for(Block.Dec di:s.getDecs()){ inScope.add(di.getX()); } Set<String> res = inBlock(s); for(Block.Dec di:s.getDecs()){ inScope.remove(di.getX()); } return res; } private Set<String> inBlock(Block s) { for(Block.Dec di:s.getDecs()){ di.getInner().accept(this); } if(!s.getOns().isEmpty()){visitK(s.getOns());} Set<String> res = s.getInner().accept(this); return res; } public Set<String> visit(WalkBy s) {throw Assertions.codeNotReachable();} public Set<String> visit(_void s) {return collected;} public Set<String> visit(ExpCore.EPath s) {return collected;} public Set<String> visit(ClassB s) {return collected;} }