package sugarVisitors;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import tools.Assertions;
import tools.Map;
import ast.Ast;
import ast.Expression;
import ast.Ast.Doc;
import ast.Ast.Mdf;
import ast.Ast.NormType;
import ast.Ast.Op;
import ast.Ast.Parameters;
import ast.Ast.Path;
import ast.Ast.Position;
import ast.Ast.SignalKind;
import ast.Ast.Type;
import ast.Expression.Catch;
import ast.Expression.Catch1;
import ast.Expression.With.On;
import ast.Expression.BlockContent;
import ast.Ast.VarDec;
import ast.Ast.VarDecE;
import ast.Ast.VarDecXE;
import ast.Expression.BinOp;
import ast.Expression.ClassB;
import ast.Expression.ClassReuse;
import ast.Expression.ContextId;
import ast.Expression.CurlyBlock;
import ast.Expression.DocE;
import ast.Expression.DotDotDot;
import ast.Expression.FCall;
import ast.Expression.If;
import ast.Expression.Literal;
import ast.Expression.Loop;
import ast.Expression.MCall;
import ast.Expression.RoundBlock;
import ast.Expression.Signal;
import ast.Expression.SquareCall;
import ast.Expression.SquareWithCall;
import ast.Expression.UnOp;
import ast.Expression.UseSquare;
import ast.Expression.Using;
import ast.Expression.WalkBy;
import ast.Expression.While;
import ast.Expression.With;
import ast.Expression.X;
import ast.Expression._void;
import ast.Expression.ClassB.MethodImplemented;
import ast.Expression.ClassB.MethodWithType;
import ast.Expression.ClassB.NestedClass;
import auxiliaryGrammar.Functions;
class ContextReplace extends ContextLocator{
Position pos;Expression receiver; String mName; String fName;
public Expression visit(Expression.ContextId s) {
assert s.getInner().startsWith("\\");
if(s.getInner().equals("\\")){
return Desugar.getMCall(pos, receiver,"#default#"+mName, Desugar.getPs(fName, Expression._void.instance));
}
return Desugar.getMCall(pos, receiver,s.getInner().substring(1),Desugar.getPs());
}
public static Expression of(Position pos,Expression receiver,String mName, String fName, Expression e){
ContextReplace v=new ContextReplace();
v.pos=pos;
v.receiver=receiver;
v.fName=fName;
v.mName=mName;
return e.accept(v);
}
public static Ast.Parameters of(Position pos,Expression receiver,String mName, Ast.Parameters ps){
Optional<Expression> fp=Optional.empty();
List<String> xs=ps.getXs();
List<Expression> es=new ArrayList<>();
if(ps.getE().isPresent()){
fp=Optional.of(of(pos,receiver,mName,"that",ps.getE().get()));
}
for(int i=0;i<xs.size();i++){
es.add(of(pos,receiver,mName,xs.get(i),ps.getEs().get(i)));
}
return new Ast.Parameters(fp,xs, es);
}
}
class DesugarContext extends CloneVisitor{
Set<String> usedVars=new HashSet<String>();
public static boolean checkRemoved(Expression e){
class AssertContextNotPresent extends CloneVisitor{ @Override public Expression visit(ContextId s) {
assert false:s;
return s; }}
e.accept(new AssertContextNotPresent());
return true;
}
public static Expression of(Set<String> usedVars,Expression e){
DesugarContext d=new DesugarContext();
d.usedVars=usedVars;
Expression result= e.accept(d);
return result;
//TODO: need to check there is no \ out of scope, that would be ill formed
//it is a subset of what is asserted now with checkRemoved.
}
public Expression visit(Expression.MCall s) {
s=s.withPs(ContextReplace.of(s.getP(),s.getReceiver(), s.getName(), s.getPs()));
return super.visit(s);
}
public Expression visit(FCall s) {
s=s.withPs(ContextReplace.of(s.getP(),s.getReceiver(), "#apply", s.getPs()));
return super.visit(s);
}
public Expression visit(SquareCall s) {
List<Parameters> pss=new ArrayList<>();
for(Parameters ps:s.getPss()){pss.add(ContextReplace.of(s.getP(), s.getReceiver(),"#square", ps));}
s=s.withPss(pss);
return super.visit(s);
}
public Expression visit(SquareWithCall s) {
s=s.withWith((With)ContextReplace.of(s.getP(),s.getReceiver(),"#square","#square", s.getWith()));
return super.visit(s);
}
}