package repl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import ast.ErrorMessage;
import ast.ExpCore;
import ast.ExpCore.ClassB.Member;
import ast.ExpCore.ClassB.NestedClass;
import ast.Expression;
import ast.Ast.Doc;
import ast.Ast.Position;
import ast.Ast.Stage;
import ast.Expression.ClassB;
import ast.Expression.ClassReuse;
import coreVisitors.CloneVisitor;
import facade.ErrorFormatter;
import facade.L42;
import facade.Parser;
import facade.L42.ExecutionStage;
import programReduction.ProgramReduction;
import sugarVisitors.Desugar;
import sugarVisitors.InjectionOnCore;
public class ReplState {
String originalS;
ast.Expression.ClassReuse originalL;
ast.ExpCore.ClassB desugaredL;
public ReplState(String originalS, ast.Expression.ClassReuse originalL, ast.ExpCore.ClassB desugaredL) {
this.originalS = originalS;
this.originalL = originalL;
this.desugaredL = desugaredL;
}
public static ReplState start(String code){
try{
Expression.ClassReuse code1=(ClassReuse) Parser.parse("Repl",code);
auxiliaryGrammar.WellFormedness.checkAll(code1);
Expression.ClassReuse code2=(ClassReuse)Desugar.of(code1);
assert auxiliaryGrammar.WellFormedness.checkAll(code2);
ExpCore.ClassB code3=(ExpCore.ClassB)code2.accept(new InjectionOnCore());
assert coreVisitors.CheckNoVarDeclaredTwice.of(code3);
// TODO: will die after new reduction Refresh of position identities, it is used to generate correct Java code.
code3=(ExpCore.ClassB)code3.accept(new CloneVisitor(){
@Override public ExpCore visit(ExpCore.ClassB cb){
Position p=cb.getP();
cb=cb.withP(new Position(p.getFile(),p.getLine1(),p.getPos1(),p.getLine2(),p.getPos2(),p.get_next()));
return super.visit(cb);
}
});
ExpCore.ClassB result= ProgramReduction.allSteps(code3);
return new ReplState(code, code2,result);
}
catch(org.antlr.v4.runtime.misc.ParseCancellationException parser){
System.out.println(parser.getMessage());
return null;
}
catch(ErrorMessage msg){
ErrorFormatter.topFormatErrorMessage(msg);
return null;
}
}
public ReplState add(String code){
Expression.ClassB cbEmpty=new ClassB(Doc.empty(),new ast.Ast.InterfaceHeader(),Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),Position.noInfo);
try{
//parse
Expression.ClassB codeTmp=(ClassB) Parser.parse("Repl","{"+code+"}");
//new original
ClassReuse newOriginal = this.originalL;
List<ast.Expression.ClassB.Member> newOriginalMs=newOriginal.getInner().getMs();
newOriginalMs.addAll(codeTmp.getMs());
newOriginal.withInner(newOriginal.getInner().withMs(newOriginalMs));
//new src to desugar
List<ClassB.Member>newMs=new ArrayList<>();
int nestedAdded=0;
for( Member m:this.desugaredL.getMs()){
if(!(m instanceof NestedClass)){continue;}
NestedClass nc=(NestedClass)m;
newMs.add(new ClassB.NestedClass(Doc.empty(),nc.getName(),cbEmpty,nc.getP()));
nestedAdded+=1;
}
newMs.addAll(codeTmp.getMs());
codeTmp=codeTmp.withMs(newMs);
Expression code2=Desugar.of(codeTmp);
ExpCore.ClassB code3=(ExpCore.ClassB)code2.accept(new InjectionOnCore());
// TODO: will die after new reduction Refresh of position identities, it is used to generate correct Java code.
code3=(ExpCore.ClassB)code3.accept(new CloneVisitor(){
@Override public ExpCore visit(ExpCore.ClassB cb){
Position p=cb.getP();
cb=cb.withP(new Position(p.getFile(),p.getLine1(),p.getPos1(),p.getLine2(),p.getPos2(),p.get_next()));
return super.visit(cb);
}
});
//integrate new desugared src with old desugared code
List<Member> resultMs=new ArrayList<>(this.desugaredL.getMs());
for(int i=nestedAdded;i<code3.getMs().size();i++){
resultMs.add(code3.getMs().get(i));
}
code3=code3.withMs(resultMs);
//call the repl and return
ExpCore.ClassB result= ProgramReduction.allSteps(code3);
return new ReplState(this.originalS+"\n"+code, newOriginal,result);
}
catch(ParseCancellationException parser){
System.out.println(parser.getMessage());
return null;
}
catch(ErrorMessage msg){
ErrorFormatter.topFormatErrorMessage(msg);
return null;
}
}
}