package coreVisitors; import java.util.ArrayList; import java.util.List; import java.util.function.Function; import tools.Assertions; import ast.Ast.*; import ast.ErrorMessage; import ast.ExpCore; import ast.ExpCore.Block; 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; import ast.Redex; import auxiliaryGrammar.Ctx; public class ExtractCtxUpToX implements Visitor<Ctx<Block>>{ String x; private ExtractCtxUpToX(String x){this.x=x;} public Ctx<Block> visit(ExpCore.EPath s) {throw Assertions.codeNotReachable();} public Ctx<Block> visit(X s) {throw Assertions.codeNotReachable();} public Ctx<Block> visit(_void s) {throw Assertions.codeNotReachable();} public Ctx<Block> visit(WalkBy s) {throw Assertions.codeNotReachable();} public Ctx<Block> visit(ClassB s) {throw Assertions.codeNotReachable();} public Ctx<Block> visit(Signal s) { return lift(s.getInner().accept(this), ctx->s.withInner(ctx)); } public Ctx<Block> visit(Loop s) { return lift(s.getInner().accept(this), ctx->s.withInner(ctx)); } public Ctx<Block> visit(Using s) { for(ExpCore ei:s.getEs()){ if(!IsCtx.of(ei)){continue;} return lift(ei.accept(this),ctx->{ List<ExpCore> es=new ArrayList<ExpCore>(s.getEs()); es.set(es.indexOf(ei), ctx); return s.withEs(es); }); } throw Assertions.codeNotReachable(); } public Ctx<Block> visit(MCall s) { if(IsCtx.of(s.getInner())){ return lift(s.getInner().accept(this), ctx->s.withInner(ctx));} for(ExpCore ei:s.getEs()){ if(!IsCtx.of(ei)){continue;} return lift(ei.accept(this),ctx->{ List<ExpCore> es=new ArrayList<ExpCore>(s.getEs()); es.set(es.indexOf(ei), ctx); return s.withEs(es); }); } throw Assertions.codeNotReachable(); } public Ctx<Block> visit(Block s) { int xPos=s.domDecs().indexOf(x); if(xPos!=-1 && IsCtx.of(s)){return new Ctx<Block>(new WalkBy(),s);} List<Block.Dec> newDecs=new ArrayList<Block.Dec>(); Ctx<Block>res=null; for(Block.Dec dec:s.getDecs()){ if(!IsCtx.of(dec.getInner())){ newDecs.add(dec); continue;} res=dec.getInner().accept(this); newDecs.add(dec.withInner(res.ctx)); } if(res!=null){ res.ctx=s.withDecs(newDecs); return res; } assert IsCtx.of(s.getInner()); assert s.getOns().isEmpty(); res=s.getInner().accept(this); res.ctx=s.withInner(res.ctx); return res; } private Ctx<Block> lift(Ctx<Block> res,Function<ExpCore,ExpCore> f){ assert res!=null; res.ctx=f.apply(res.ctx); return res; } public static Ctx<Block> of(String x,ExpCore e){ Ctx<Block> result=e.accept(new ExtractCtxUpToX(x)); if(result!=null){ //NO assert result.ctx instanceof Block: result.ctx; return result; } throw Assertions.codeNotReachable(); } }