package TP2.asd; import java.util.ArrayList; import java.util.Map; import org.antlr.grammar.v3.ANTLRParser.defaultNodeOption_return; import TP2.asd.Interface.ExprVisitor; import TP2.asd.Interface.Expression; import TP2.asd.Interface.Function; import TP2.asd.Interface.FunctionVisitor; import TP2.asd.Interface.InstrVisitor; import TP2.asd.Interface.Instruction; import TP2.asd.Interface.Op; import TP2.asd.Interface.ProgramI; import TP2.asd.Interface.ProgramVisitor; import TP2.asd.Interface.Type; public class Program{ static String INDENT = " "; public static record ProgramImp(ArrayList fonctions) implements ProgramI{ public S accept(ProgramVisitor v, H h) { return v.visitProgram(this, h); } public String prettyprinter(){ String str =""; for(int i = 0; i instructions)implements Function { public FunctionImp(Type type, String name, Instruction instruction) { this(type, name, new ArrayList<>() {{ add(instruction); }}); } public S accept(FunctionVisitor v, H h) { return v.visitFunction(this, h); } public String prettyprinter(String indent){ String str = indent+"FUNC " + type.prettyprinter()+ " " + nom +"(){\n"; for(int i = 0; i S accept(ExprVisitor v, H h) { return v.visitConst(this, h); } public String prettyprinter(){ return c+""; } } public static record BinopExpressionImp(Op op,Expression e1, Expression e2) implements Expression{ public S accept(ExprVisitor v, H h) { return v.visitBinOp(this, h); } public String prettyprinter(){ String opStr = "?"; switch(op){ case PLUS: opStr = "+"; break; case DIV: opStr = "/"; break; case MINUS: opStr = "-"; break; case MOD: opStr = "%"; break; case TIMES: opStr = "*"; break; default:break; } return "(" + e1.prettyprinter() +" "+ opStr +" " + e2.prettyprinter() + ")"; } } public static record Return_instrImp(Expression e) implements Instruction{ public S accept(InstrVisitor v, H h) { return v.visitReturn(this,h); } public String prettyprinter(String indent){ return indent+"RETURN " + e.prettyprinter(); } } public static record Type_voidImp() implements Type{ public String prettyprinter() { return "VOID"; } } public static record Type_intImp() implements Type{ public String prettyprinter() { return "INT"; } } //Eval public static class ProgramEval implements ProgramVisitor, Integer> { @Override public Integer visitProgram(ProgramImp e, Map h) { Integer result = null; FunctionEval functionEval = new FunctionEval(); for (Function function : e.fonctions()) { result = function.accept(functionEval, h); } return result; } } public static class FunctionEval implements FunctionVisitor, Integer> { @Override public Integer visitFunction(FunctionImp e, Map h) { InstructionEval instructionEval = new InstructionEval(); Integer result = null; for (Instruction instr : e.instructions()) { result = instr.accept(instructionEval, h); } return result; } } public static class InstructionEval implements InstrVisitor,Integer>{ @Override public Integer visitReturn(Return_instrImp e, Map h) { ExprEval exprEval = new ExprEval(); return e.e().accept(exprEval, h); } } public static class ExprEval implements ExprVisitor,Integer>{ public Integer visitConst(ConstImp c, Map h){ return c.c(); } public Integer visitBinOp(BinopExpressionImp e, Map h) { switch(e.op()) { case Op.PLUS: return e.e1().accept(this, h)+e.e2().accept(this, h); case Op.MINUS: return e.e1().accept(this, h)-e.e2().accept(this, h); case Op.TIMES: return e.e1().accept(this, h)*e.e2().accept(this, h); case Op.DIV: return e.e1().accept(this, h)/e.e2().accept(this, h); case Op.MOD: return e.e1().accept(this, h)%e.e2().accept(this, h); default: throw new IllegalArgumentException(); } } } }