diff --git a/src/Compiler.java b/src/Compiler.java index 6a87a9259bb5cd80e8135de893f074d8c75f69b0..41d8b22805d94c4f529c43924fa078c2a51ac52b 100644 --- a/src/Compiler.java +++ b/src/Compiler.java @@ -35,9 +35,10 @@ public class Compiler buildSa(); System.out.println("[BUILD TS] "); buildTs(); - /* +/* System.out.println("[TYPE CHECKING]"); typeCheck(); + System.out.println("[BUILD C3A] "); buildC3a(); System.out.println("[BUILD PRE NASM] "); diff --git a/src/sa/SaInstBloc.java b/src/sa/SaInstBloc.java index 8f13f49c6bccdc48b6fc4bda8cdbe9e8a417ffc1..a1f570253c9acc77424c80df22c0b8c474c3ad9a 100644 --- a/src/sa/SaInstBloc.java +++ b/src/sa/SaInstBloc.java @@ -16,4 +16,6 @@ public class SaInstBloc implements SaInst{ public String toString() { return "(" + this.getClass().getSimpleName() + " " + val + ")"; } + + } diff --git a/src/sa/SaLDecFonc.java b/src/sa/SaLDecFonc.java index 73135aeaf1b30f4684851bd6f0dc90f0f97dbe73..a09497d056c33b2b6c7f6b82d42348a2c07e4df7 100644 --- a/src/sa/SaLDecFonc.java +++ b/src/sa/SaLDecFonc.java @@ -25,4 +25,5 @@ public class SaLDecFonc implements SaNode{ return "(" + this.getClass().getSimpleName() + " " + tete + " " + queue + ")"; } + } diff --git a/src/sa/SaTypeCheck.java b/src/sa/SaTypeCheck.java index 60e71efec1cba615a2f3bb32f6c710652f1f5086..00c093f8875ee56778fdfa5c15bdfc206c97f5bc 100644 --- a/src/sa/SaTypeCheck.java +++ b/src/sa/SaTypeCheck.java @@ -3,13 +3,31 @@ import util.Type; import util.Error; import ts.*; +import java.util.ArrayList; +import java.util.List; + public class SaTypeCheck extends SaDepthFirstVisitor <Void>{ private TsItemFct fonctionCourante; + private List<TsItemFct> fonctions; + public SaTypeCheck(SaNode root) { try{ + //BANCAL + /* + fonctions = new ArrayList<>(); + SaProg prog = (SaProg) root; + SaLDecFonc list = prog.getFonctions(); + for (int i = 0; i < list.length(); i++) { + fonctions.add(list.getTete().tsItem); + list = list.getQueue(); + } + fonctionCourante = fonctions.get(0); + */ root.accept(this); + + } catch(ErrorException e){ System.err.print("ERREUR DE TYPAGE : "); System.err.println(e.getMessage()); @@ -17,14 +35,132 @@ public class SaTypeCheck extends SaDepthFirstVisitor <Void>{ } catch(Exception e){} } - public void defaultIn(SaNode node) + + @Override + public Void visit(SaExpAdd node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.BOOL) || Type.checkCompatibility(node.getOp2().getType(), Type.BOOL)) { + throw new ErrorException(Error.TYPE, "Veuillez additioner uniquement des entiers"); + } + return null; + } + + @Override + public Void visit(SaInstTantQue node) throws Exception { + if (Type.checkCompatibility(node.getTest().getType(), Type.ENTIER)) { + throw new ErrorException(Error.TYPE, "Le résultat du test de la condition doit être un booléen"); + } + return null; + } + + @Override + public Void visit(SaInstAffect node) throws Exception { + String id = node.getLhs().getTsItem().identif; + Ts table = fonctionCourante.getTable(); + Type type = table.getVar(id).getType(); + + if (!Type.checkCompatibility(node.getRhs().getType(), type)) { + throw new ErrorException(Error.TYPE, "Le type affecté doit être le même que celui spécifié à la déclaration de la variable"); + } + return null; + } + + @Override + public Void visit(SaExpSub node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.BOOL) || Type.checkCompatibility(node.getOp2().getType(), Type.BOOL)) { + throw new ErrorException(Error.TYPE, "Veuillez soustraire uniquement des entiers"); + } + return null; + } + + @Override + public Void visit(SaExpMult node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.BOOL) || Type.checkCompatibility(node.getOp2().getType(), Type.BOOL)) { + throw new ErrorException(Error.TYPE, "Veuillez multiplier uniquement des entiers"); + } + return null; + } + + @Override + public Void visit(SaExpDiv node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.BOOL) || Type.checkCompatibility(node.getOp2().getType(), Type.BOOL)) { + throw new ErrorException(Error.TYPE, "Veuillez diviser uniquement des entiers"); + } + return null; + } + + @Override + public Void visit(SaExpInf node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.BOOL) || Type.checkCompatibility(node.getOp2().getType(), Type.BOOL)) { + throw new ErrorException(Error.TYPE, "L'opérateur '<' marche uniquement sur des entiers"); + } + return null; + } + + @Override + public Void visit(SaExpEqual node) throws Exception { + if (!Type.checkCompatibility(node.getOp1().getType(), node.getOp2().getType())) { + throw new ErrorException(Error.TYPE, "Veuillez comparer uniquement des operande du même type"); + } + return null; + } + + @Override + public Void visit(SaExpAnd node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.ENTIER) || Type.checkCompatibility(node.getOp2().getType(), Type.ENTIER)) { + throw new ErrorException(Error.TYPE, "Veuillez 'And' uniquement des booléens"); + } + return null; + } + + @Override + public Void visit(SaExpOr node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.ENTIER) || Type.checkCompatibility(node.getOp2().getType(), Type.ENTIER)) { + throw new ErrorException(Error.TYPE, "Veuillez 'Or' uniquement des booléens"); + } + return null; + } + + @Override + public Void visit(SaExpNot node) throws Exception { + if (Type.checkCompatibility(node.getOp1().getType(), Type.ENTIER)) { + throw new ErrorException(Error.TYPE, "Veuillez 'Not' uniquement des booléens"); + } + return null; + } + + @Override + public Void visit(SaInstSi node) throws Exception { + if (Type.checkCompatibility(node.getTest().getType(), Type.ENTIER)) { + throw new ErrorException(Error.TYPE, "Le résultat du test de la condition doit être un booléen"); + } + return null; + } + + @Override + public Void visit(SaInstRetour node) throws Exception { + + if (!Type.checkCompatibility(node.getType(), fonctionCourante.getTypeRetour())) { + throw new ErrorException(Error.TYPE, "Le type retourné doit être le même que celui de la fonction"); + } + return null; + } + + @Override + public Void visit(SaAppel node) throws Exception { + throw new ErrorException(Error.TYPE, "nique"); + } + + + + public void defaultIn(SaNode node) { - // System.out.println("<" + node.getClass().getSimpleName() + ">"); + System.out.println("<" + node.getClass().getSimpleName() + ">"); } public void defaultOut(SaNode node) { - // System.out.println("</" + node.getClass().getSimpleName() + ">"); + System.out.println("</" + node.getClass().getSimpleName() + ">"); + } diff --git a/src/ts/Sa2ts.java b/src/ts/Sa2ts.java index f2c3b196fec1139e1d42ef9ee9c0c28bd45c13fc..765f0f0eb56362962b753adcc5974136011feaf6 100644 --- a/src/ts/Sa2ts.java +++ b/src/ts/Sa2ts.java @@ -41,30 +41,43 @@ public class Sa2ts extends SaDepthFirstVisitor <Void> { @Override public Void visit(SaDecFonc node) throws Exception { + String idFct = node.getNom(); SaLDecVar parameters = node.getParametres(); SaLDecVar variable = node.getVariable(); - SaInst corps = node.getCorps(); + SaInst corps = node.getCorps(); + if (tableGlobale.getFct(idFct) != null) { throw new ErrorException(Error.TS, "La fonction " + idFct + " est déjà définie."); } + Ts table = new Ts(); tableLocaleCourante = table; int nbArgs = 0; + if (parameters != null) { context = Context.PARAM; parameters.accept(this); nbArgs = parameters.length(); } + if (variable != null) { context = Context.LOCAL; variable.accept(this); } + node.tsItem = tableGlobale.addFct(idFct, node.getTypeRetour(), nbArgs, table, node); - if (corps != null) { + + //besoin de rajouter un equals pour le SaInstBloc + + SaInstBloc tempCorps = (SaInstBloc) corps; + + + if (corps != null && tempCorps.getVal() != null) { context = Context.LOCAL; corps.accept(this); } + context = Context.GLOBAL; return null; } @@ -131,7 +144,6 @@ public class Sa2ts extends SaDepthFirstVisitor <Void> { if (tableGlobale.getFct(idFct) == null) { throw new ErrorException(Error.TS, "La fonction " + idFct + " n'est pas définie."); } - if (this.tableGlobale.getFct(idFct).getNbArgs() != nbArgs) { throw new ErrorException(Error.TS, "Le nombre d'arguments est incorrect." + this.tableGlobale.getFct(idFct).getNbArgs() + " requis.");