package TP2.asd; import java.util.ArrayList; import java.util.List; import java.util.Map; import TP2.asd.Interface.*; import TP2.llvm.ProgramLLVM.*; import TP2.llvm.Interface.*; 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 fonctionLLVM = new ArrayList<>(); for(int i = 0; i(),fonctionLLVM); } } 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 String prettyprinter(String indent){ String str = indent+"FUNC " + type.prettyprinter()+ " " + nom +"(){\n"; for(int i = 0; i instrLLVM = new ArrayList<>(); for(int i = 0; i S accept(ExprVisitor v, H h) { return v.visitConst(this, h); } public String prettyprinter(){ return c+""; } @Override public ArrayList toLLVM() { //TODO // TODO Auto-generated method stub ArrayList list = new ArrayList<>(); ConstLLVMImp cLLVM = new ConstLLVMImp(new IntLLVMImpl(),c); list.add(new AssignLVMImp(new VarLLVMImpl("todo"), cLLVM)); return list; } } 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() + ")"; } @Override public ArrayList toLLVM() { //TODO si e1 ou e2 est une constante, elle doit pouvoir ĂȘtre mise directement dans l'expression ArrayList list = new ArrayList<>(); ArrayList eLLVM1 = e1.toLLVM(); ArrayList eLLVM2 = e2.toLLVM(); list.addAll(eLLVM1); list.addAll(eLLVM2); VarLLVMImpl var1 = eLLVM1.getLast().getVar(); VarLLVMImpl var2 = eLLVM2.getLast().getVar(); list.add(new AssignLVMImp(new VarLLVMImpl("todo"), new BinOpLLVMImp(new IntLLVMImpl(),op,var1,var2))); return list; } } 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(); } @Override public ArrayList toLLVM() { ArrayList list = e.toLLVM(); InstructionLLVM r = new ReturnLLVMImp(new IntLLVMImpl(),list.getLast().getVar()); ArrayList result = new ArrayList<>(); result.addAll(list); result.add(r); return result; } } public static record AssignImp(String t, Expression e) implements Instruction{ public S accept(InstrVisitor v, H h) { return v.visitAssign(this, h); } @Override public String prettyprinter(String indent) { // TODO Auto-generated method stub throw new UnsupportedOperationException("Unimplemented method 'prettyprinter'"); } @Override public ArrayList toLLVM() { ArrayList list = e.toLLVM(); InstructionLLVM r = new AssignLVMImp(new VarLLVMImpl(t),list.getLast().getVar()); ArrayList result = new ArrayList<>(); result.addAll(list); result.add(r); return result; } } public static record Type_voidImp() implements Type{ public String prettyprinter() { return "VOID"; } @Override public TypeLLVM toLLVM() { return new IntLLVMImpl(); } } public static record Type_intImp() implements Type{ public String prettyprinter() { return "INT"; } @Override public TypeLLVM toLLVM() { return new VoidLLVMImpl(); } } //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); } @Override public Integer visitAssign(AssignImp e, Map h) { //h.put(e.t(), e.e()); //TODO return 1; } } 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(); } } } }