package TP2.asd; import java.util.ArrayList; import java.util.List; import java.util.Map; import TP2.asd.Interface.*; import TP2.asd.Eval.*; public class Program{ public static record ProgramImp(ArrayList instructions) implements ProgramI{ public S accept(ProgramVisitor v, H h) { return v.visitProgram(this, h); } } public static record FunctionImp(Type type, String nom, ArrayList 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 static record ConstImp(int c) implements Expression{ public S accept(ExprVisitor v, H h) { return v.visitConst(this, h); } } 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 static record Return_instrImp(Expression e) implements Instruction{ public S accept(InstrVisitor v, H h) { return v.visitReturn(this,h); } } 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.instructions()) { 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(); } } } }