diff --git a/src/main/antlr/VSLParser.g b/src/main/antlr/VSLParser.g index 46b5068..b8c7b69 100644 --- a/src/main/antlr/VSLParser.g +++ b/src/main/antlr/VSLParser.g @@ -22,11 +22,37 @@ options { } program returns [ProgramImp p] : + pro=prototypes func=functions EOF - {$p = new ProgramImp($func.out);} + {$p = new ProgramImp($func.out,$pro.out);} ; +prototypes returns [ArrayList out] + @init{ + $out = new ArrayList(); + }: + (proto { + $out.add($proto.out); + })* + ; + +proto returns [Prototype out]: + PROTOTYPE t=type i=ident ParO v=vars_locaux ParF + { + $out=new PrototypeImp($t.return_type,$i.out, $v.out); + } + ; + +vars_locaux returns [ArrayList out] + @init{ + $out = new ArrayList(); + }: + ( + (ii1=ident {$out.add($ii1.out);}) + (VIRGULE ii2=ident {$out.add($ii2.out);})* + )* + ; functions returns [ArrayList out] @init{ diff --git a/src/main/java/TP2/Error/TypeCheckExprDiag.java b/src/main/java/TP2/Error/TypeCheckExprDiag.java new file mode 100644 index 0000000..2625026 --- /dev/null +++ b/src/main/java/TP2/Error/TypeCheckExprDiag.java @@ -0,0 +1,34 @@ +package TP2.Error; +import TP2.asd.Interface.*; +public class TypeCheckExprDiag { + private Type t; + private String err; + private boolean check; + + public TypeCheckExprDiag(Type type) { + this.t = type; + this.check = true; + this.err = null; + } + + public TypeCheckExprDiag(String error){ + this.err=error; + this.check=false; + } + + public boolean get_check(){ + return this.check; + } + + public Type get_type(){ + return this.t; + } + + public static TypeCheckExprDiag error(String err){ + return new TypeCheckExprDiag(err); + } + + public static TypeCheckExprDiag checked(Type type){ + return new TypeCheckExprDiag(type); + } +} diff --git a/src/main/java/TP2/Error/TypeChecking.java b/src/main/java/TP2/Error/TypeChecking.java index a70f201..13ee354 100644 --- a/src/main/java/TP2/Error/TypeChecking.java +++ b/src/main/java/TP2/Error/TypeChecking.java @@ -1,34 +1,155 @@ package TP2.Error; import TP2.asd.SymTable; -import TP2.asd.Interface.ExprVisitor; -import TP2.asd.Program.BinopExpressionImp; -import TP2.asd.Program.ConstImp; -import TP2.asd.Program.VarImp; +import TP2.asd.Program.*; +import TP2.asd.Interface.*; public class TypeChecking { - private SymTable st; - /* - public class TypeCheckExpr implements ExprVisitor{ + public class TypeCheckProg implements ProgramVisitor{ + private TypeCheckFunction func_check; + @Override + public TypeCheckExprDiag visitProgram(ProgramImp prog, SymTable h) { + SymTable st= new SymTable(); + for (Function f : prog.fonctions()) { + TypeCheckExprDiag diag = f.accept(func_check, h); + if (!diag.get_check()) return diag; + } + return TypeCheckExprDiag.checked(null); + } + } + + public class TypeCheckFunction implements FunctionVisitor{ + private TypeCheckInstr instr_check; + @Override + public TypeCheckExprDiag visitFunction(FunctionImp f, SymTable h) { + return f.instruction().accept(instr_check,h); + } + } + + public class TypeCheckInstr implements InstrVisitor { + private TypeCheckExpr expr_check; + @Override + public TypeCheckExprDiag visitReturn(Return_instrImp instr, SymTable h) { + return instr.e().accept(expr_check, h); + } @Override - public TypeCheckExprDiag visitConst(ConstImp e, SymTable h) { + public TypeCheckExprDiag visitBloc(BlocImp instr, SymTable h) { + for(Instruction i: instr.instrs()){ + TypeCheckExprDiag diag= i.accept(this, h); + if(!diag.get_check()) return diag; + } + return TypeCheckExprDiag.checked(null); + } + + @Override + public TypeCheckExprDiag visitBlocDec(BlocDecImp instr, SymTable h) { // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visitConst'"); + throw new UnsupportedOperationException("Unimplemented method 'visitBlocDec'"); + } + + @Override + public TypeCheckExprDiag visitAssign(AssignImp instr, SymTable h) { + if(!h.searchVar(instr.t())){ + return TypeCheckExprDiag.error("Variable "+instr.t()+" n'existe pas"); + } + Type t_type=h.getvar_Type(instr.t()).type; + TypeCheckExprDiag expr= instr.e().accept(expr_check, h); + + if (!expr.get_check()) return expr; + //Verify type t = Type expr + if(!t_type.getClass().equals(expr.get_type().getClass())){ + return TypeCheckExprDiag.error("Type d'expression est different que le type de variable"); + } + return TypeCheckExprDiag.checked(t_type); + } + + @Override + public TypeCheckExprDiag visitPrint(PrintImp instr, SymTable h) { + for(Object o :instr.t()){ + //We have string and expression + if(o instanceof Expression e){ + TypeCheckExprDiag result = e.accept(expr_check, h); + if (!result.get_check()) return result; + } + } + return TypeCheckExprDiag.checked(null); + } + + @Override + public TypeCheckExprDiag visitRead(ReadImp instr, SymTable h) { + for(VarImp v: instr.t()){ + if(!h.searchVar(v.name())){ + return TypeCheckExprDiag.error("Variable "+v.name()+" n'existe pas"); + } + } + return TypeCheckExprDiag.checked(null); + } + + @Override + public TypeCheckExprDiag visitIfThen(IfThenImp instr, SymTable h) { + TypeCheckExprDiag cond =instr.e().accept(expr_check, h); + if(!cond.get_check()) return cond; + if (!(cond.get_type() instanceof Type_intImp)){ + return TypeCheckExprDiag.error("Condition n'est pas un int"); + } + return instr.i1().accept(this, h); + } + + @Override + public TypeCheckExprDiag visitIfThenElse(IfThenElseImp instr, SymTable h) { + TypeCheckExprDiag cond =instr.e().accept(expr_check, h); + if(!cond.get_check()) return cond; + if (!(cond.get_type() instanceof Type_intImp)){ + return TypeCheckExprDiag.error("Condition n'est pas un int"); + } + + TypeCheckExprDiag then= instr.i1().accept(this, h); + if (!then.get_check()) return then; + return instr.i2().accept(this, h); + } + + @Override + public TypeCheckExprDiag visitWhile(WhileImp instr, SymTable h) { + TypeCheckExprDiag cond =instr.e().accept(expr_check, h); + if(!cond.get_check()) return cond; + if (!(cond.get_type() instanceof Type_intImp)){ + return TypeCheckExprDiag.error("Condition n'est pas un int"); + } + return instr.i1().accept(this, h); + } + } + + public class TypeCheckExpr implements ExprVisitor{ + @Override + public TypeCheckExprDiag visitConst(ConstImp e, SymTable h) { + return TypeCheckExprDiag.checked(new Type_intImp()); } @Override public TypeCheckExprDiag visitVar(VarImp e, SymTable h) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visitVar'"); + if(!h.searchVar(e.name())){ + return TypeCheckExprDiag.error("Ce variable n'existe pas"); + } + Type e_type= h.getvar_Type(e.name()).type; + return TypeCheckExprDiag.checked(e_type); } @Override public TypeCheckExprDiag visitBinOp(BinopExpressionImp e, SymTable h) { - TypeCheckExprDiag tce1 = e.e1().accept(this, h) ; - TypeCheckExprDiag tce2 = e.e2().accept(this, h) ; + TypeCheckExprDiag tce1 = e.e1().accept(this, h); + TypeCheckExprDiag tce2 = e.e2().accept(this, h); + + // Check if not ok then return its error + if(!tce1.get_check()) return tce1; + if(!tce2.get_check()) return tce2; + + // Check int + int + if (!(tce1.get_type() instanceof Type_intImp) || !(tce2.get_type() instanceof Type_intImp) ){ + return TypeCheckExprDiag.error("Ses types sont different"); + } + return TypeCheckExprDiag.checked(tce1.get_type()); } } - */ } diff --git a/src/main/java/TP2/asd/Interface.java b/src/main/java/TP2/asd/Interface.java index 56a2da8..3e1f290 100644 --- a/src/main/java/TP2/asd/Interface.java +++ b/src/main/java/TP2/asd/Interface.java @@ -14,7 +14,15 @@ public interface Interface{ public interface ProgramVisitor { public S visitProgram(ProgramImp prog, H h); } + + //PROTOTYPE + public interface Prototype{ + public S accept(PrototypeVisitor v, H h); + } + public interface PrototypeVisitor { + public S visitPrototype(PrototypeImp proto, H h); + } //FUNCTION public interface Function { diff --git a/src/main/java/TP2/asd/PrettyprinterVisitor.java b/src/main/java/TP2/asd/PrettyprinterVisitor.java index 8492169..026517a 100644 --- a/src/main/java/TP2/asd/PrettyprinterVisitor.java +++ b/src/main/java/TP2/asd/PrettyprinterVisitor.java @@ -4,6 +4,7 @@ import TP2.asd.Interface.*; import TP2.asd.Program.*; public class PrettyprinterVisitor implements ProgramVisitor, + PrototypeVisitor, FunctionVisitor, DeclVisitor, InstrVisitor, @@ -18,6 +19,11 @@ public class PrettyprinterVisitor implements ProgramVisitor, @Override public String visitProgram(ProgramImp prog, String indent) { String str =""; + for(int i= 0; i, return str; } - //FUNCTION + //PROTOTYPE + @Override + public String visitPrototype(PrototypeImp proto, String indent){ + String str= indent + "PROTO "+proto.type().accept(this, "")+ " "+ proto.nom() + "("; + for(int i=0; i, } //DELCARATION - @Override public String visitDeclaration(DeclarationImp instr, String indent) { String str = indent +instr.t().accept(this,"") + " "; @@ -47,7 +64,6 @@ public class PrettyprinterVisitor implements ProgramVisitor, } //INSTRUCTION - @Override public String visitReturn(Return_instrImp instr, String indent) { return indent+"RETURN " + instr.e().accept(this,""); diff --git a/src/main/java/TP2/asd/Program.java b/src/main/java/TP2/asd/Program.java index ebaaf99..77cb794 100644 --- a/src/main/java/TP2/asd/Program.java +++ b/src/main/java/TP2/asd/Program.java @@ -7,7 +7,7 @@ import TP2.llvm.ProgramLLVM.*; public class Program{ //Prog - public static record ProgramImp(ArrayList fonctions) implements ProgramI{ + public static record ProgramImp(ArrayList fonctions,ArrayList protos) implements ProgramI{ public S accept(ProgramVisitor v, H h) { return v.visitProgram(this, h); } @@ -23,6 +23,15 @@ public class Program{ return this.accept(llvmVisitor,new SymTable()); } } + + //Prototype + public static record PrototypeImp(Type type, String nom, ArrayList s) implements Prototype{ + @Override + public S accept(PrototypeVisitor v, H h) { + return v.visitPrototype(this,h); + } + + } //Fonction public static record FunctionImp(Type type, String nom, Instruction instruction)implements Function { diff --git a/tests/aLaMain.vsl b/tests/aLaMain.vsl index 6921373..446f575 100644 --- a/tests/aLaMain.vsl +++ b/tests/aLaMain.vsl @@ -1,3 +1,4 @@ +PROTO INT add(x,y) FUNC INT main() { INT a,b,c b:=3