diff --git a/NULL b/NULL new file mode 100644 index 0000000..a2721b4 --- /dev/null +++ b/NULL @@ -0,0 +1,4 @@ +tests\testsAdvanced\portee3.ll:20:4: error: multiple definition of local value named 'null' + 20 | %null = alloca i32 + | ^ +1 error generated. diff --git a/runAllTests2.py b/runAllTests2.py new file mode 100644 index 0000000..bbbec1d --- /dev/null +++ b/runAllTests2.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 + +import os +import subprocess + +from colorama import init as colorama_init +from colorama import Fore +from colorama import Style + +stats = {} + +# Détermine quel est l'exécutable clang utilisable. +# Note : à l'istic c'est clang-19 +def clangName(): + for name in ["clang-" + str(v) for v in range(20,16,-1)]: + p = subprocess.run(f"command -v {name} 2>&1 >/dev/null", shell=True) + if p.returncode == 0 : + return name + return "clang" + +clang = clangName() + +def runNormalTestSuit(testSuit): + print(f"Running test suit : {testSuit}") + stats[testSuit] = (0,0,0,0) + for dirname, dirnames, filenames in os.walk(testSuit): + for filename in filenames: + runNormalTest(testSuit, dirname, filename) + +def runNormalTest(testSuit, dirname,filename): + vslToLLVM = False + llvmToBin = False + executionCorrect = False + + path = os.path.join(dirname, filename) + basename, ext = os.path.splitext(path) + # Ignore not .vsl files + if ext != ".vsl": + return + + print(f'\tRunning test {filename}') + + # VSL -> LLVM + p = subprocess.run(f"java -jar build/libs/TP2.jar {path}", shell=True) + print(f"java -jar build/libs/TP2.jar {path}") + if p.returncode == 0 : + vslToLLVM = True + + + # LLVM -> Bin + if vslToLLVM : + p = subprocess.run(f"{clang} {basename}.ll -o {basename} 2>NULL", shell=True) + print(f"{clang} {basename}.ll -o {basename} 2>NULL") + if p.returncode == 0: + llvmToBin = True + executionCorrect = True + + # Exe + if llvmToBin : + executionCorrect = True + try: + input = "" + if os.path.isfile(f"{basename}.test_in"): + input = f"< {basename}.test_in" + p = subprocess.run(f".\{basename} " + input, shell=True, stdout=subprocess.PIPE, timeout=5) + print(f".\{basename} ") + except subprocess.TimeoutExpired: + executionCorrect = "diverge" in basename + + # Check return code + if os.path.isfile(f"{basename}.test_ret"): + with open(f"{basename}.test_ret", "r") as expected: + executionCorrect = executionCorrect and int(expected.read()) == p.returncode + # Check stdout + if os.path.isfile(f"{basename}.test_out"): + with open(f"{basename}.test_out", "rb") as expected: + executionCorrect = executionCorrect and expected.read() == p.stdout + + print(f"{colorFromBool(vslToLLVM)}\t\tVSL to LLVM : {'OK' if vslToLLVM else 'Fail'}{Style.RESET_ALL}") + print(f"{colorFromBool(llvmToBin)}\t\tLLVM to Bin : {'OK' if llvmToBin else 'Fail'}{Style.RESET_ALL}") + print(f"{colorFromBool(executionCorrect)}\t\tCorrect Execution : {'OK' if executionCorrect else 'Fail'}{Style.RESET_ALL}") + + x,y,z,t = stats[testSuit] + if vslToLLVM : + x += 1 + if llvmToBin : + y += 1 + if executionCorrect : + z += 1 + t += 1 + stats[testSuit] = (x,y,z,t) + +def colorFromBool(b): + if b: + return Fore.GREEN + else: + return Fore.RED + + +def afficheStats(stat): + x,y,z,t = stat + print(f'\t Nombre de tests : {t}') + print(f'{colorFromBool(x==t)}\t vsl to llvm : {x} / {t}{Style.RESET_ALL}') + print(f'{colorFromBool(y==t)}\t llvm to bin : {y} / {t}{Style.RESET_ALL}') + print(f'{colorFromBool(z==t)}\t resultat correct: {z} / {t}{Style.RESET_ALL}') + +nbError = 0 +nbErrorTests = 0 + +def runErrorTest(testSuit, dirname,filename): + path = os.path.join(dirname, filename) + basename, ext = os.path.splitext(path) + if ext != ".vsl": + return + + print(f'\tRunning test {filename}') + + hasError = False + + p = subprocess.run(f"java -jar build/libs/TP2.jar < {path} 1>{basename}.ll", shell=True, stderr=subprocess.PIPE) + + if p.returncode != 0 and p.stderr != b'': + print(f"\t\t{Fore.GREEN}Error : Yes{Style.RESET_ALL}") + hasError = True + else: + print(f"\t\t{Fore.RED}Error : No{Style.RESET_ALL}") + hasError = False + + x,t = stats[testSuit] + if hasError : + x += 1 + t += 1 + stats[testSuit] = (x,t) + + +def runErrorLevelTests(testSuit): + print(f"Running test suit : {testSuit}") + stats[testSuit] = (0,0) + for dirname, dirnames, filenames in os.walk(testSuit): + for filename in filenames: + runErrorTest(testSuit, dirname, filename) + + +def runTests(testDirName): + folderContent = [os.path.join(testDirName, d) for d in os.listdir(testDirName)] + testSuits = [d for d in folderContent if os.path.isdir(d)] + testSuits.sort() + + for suit in testSuits: + if "error" in suit or "Error" in suit: + runErrorLevelTests(suit) + else: + runNormalTestSuit(suit) + + for suit in testSuits: + print(f'Résumé du test {suit}') + if "error" in suit or "Error" in suit: + nbError, nbErrorTests = stats[suit] + print(f'{colorFromBool(nbError==nbErrorTests)}\t Nombre d\'erreurs : {nbError} / {nbErrorTests}{Style.RESET_ALL}') + else: + afficheStats(stats[suit]) + + + + + +if __name__ == "__main__" : + colorama_init() + runTests("tests") \ No newline at end of file diff --git a/src/main/java/TP2/Main.java b/src/main/java/TP2/Main.java index 73434b1..604cdc9 100644 --- a/src/main/java/TP2/Main.java +++ b/src/main/java/TP2/Main.java @@ -23,21 +23,21 @@ import java.util.*; /* + ./gradlew build + java -jar build/libs/TP2.jar tests/fragment0/priority2.vsl + java -jar build/libs/TP2.jar tests/aLaMain.vsl + +(/!\ pas besoin, le main le fait tout seul /!\) java -jar build/libs/TP2.jar tests/fragment1/while2.vsl > tests/fragment1/while2.ll + +clang tests/aLaMain.ll -o tests/aLaMain + */ -/* TODO : problème de "-" : un NUMVER seul avec un "-" devant doit être reconnu comme un NUMBER négatif -frament 1 : -java -jar build/libs/TP2.jar tests/fragment1/print4.vsl - -java -jar build/libs/TP2.jar tests/fragment1/while2.vsl > tests/fragment1/while2.ll -clang tests/fragment1/while2.ll -o tests/fragment1/while2 - - */ - public class Main { + static Boolean TESTAUTOMOD = false; public static void main(String[] args) { try { // Set input @@ -62,29 +62,35 @@ public class Main { // Pretty-print the program (to debug parsing) - //System.out.println(ast.prettyprinter()); + if(!TESTAUTOMOD) System.out.println(ast.prettyprinter()); // Verify the program semantic // Generate the intermediate representation - //System.out.println("\n\n"); - PrintWriter out2 = new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8), true); + if(!TESTAUTOMOD) System.out.println("\n\n"); ProgramLLVMImp astLLVM = ast.toLLVM(); String llvmStr = astLLVM.prettyprinter(); - out2.println(llvmStr); + System.out.println(llvmStr); - /* - - String sortieLLVM = args[0].replace(".vsl", ".ll"); - Files.write( - Paths.get(sortieLLVM), - llvmStr.getBytes(StandardCharsets.UTF_8) - ); - - System.out.println("\n[VSL compile Succes] : " + args[0] + " -> " + sortieLLVM +"\n"); + /* + utiliser la commande : + java -jar build/libs/TP2.jar file.vsl > file.ll + provoque peut provoquer de mauvais encodage (UTF16(LE) au lieu d'UTF8) + et empêche l'utilisation de print pour autre chose */ + if(!TESTAUTOMOD){ + String sortieLLVM = args[0].replace(".vsl", ".ll"); + Files.write( + Paths.get(sortieLLVM), + llvmStr.getBytes(StandardCharsets.UTF_8) + ); + + System.out.println("\n[VSL compile succes] : " + args[0] + " -> " + sortieLLVM); + System.out.println("Pour compiler en bin utilisez :"); + System.out.println("clang " + sortieLLVM + " -o " + sortieLLVM.replace(".ll", "") + "\n"); + } } catch (IOException | RecognitionException e) { e.printStackTrace(); diff --git a/src/main/java/TP2/asd/toLLVM_Visitor.java b/src/main/java/TP2/asd/toLLVM_Visitor.java index 9e5983b..1b2bec2 100644 --- a/src/main/java/TP2/asd/toLLVM_Visitor.java +++ b/src/main/java/TP2/asd/toLLVM_Visitor.java @@ -78,7 +78,7 @@ public class toLLVM_Visitor implements ProgramVisitor, paramsLLVM.add(var); VarLLVMImp newVar =new VarLLVMImp(type, nameVar,false); setParam.add(new AssignLLVMImp(newVar,new allocaLLVMImp(type))); - setParam.add(new StoreLLVMImp(type,var,type,newVar)); + setParam.add(new StoreLLVMImp(type,var,newVar)); } instrLLVM.addAll(setParam); instrLLVM.addAll(fun.instruction().accept(this, h)); @@ -115,7 +115,7 @@ public class toLLVM_Visitor implements ProgramVisitor, h = r.symTable; list.add(new AssignLLVMImp(new VarLLVMImp(t2, r.var,false),new allocaLLVMImp(t2))); }else { - TypeLLVM arrayType = new ArrayLLVMImp(t2, size); + TypeLLVM arrayType = new PointerLLVMImp(t2); //Alloca Result r_size= h.addNewTempVar(); @@ -196,7 +196,7 @@ public class toLLVM_Visitor implements ProgramVisitor, ArrayList result = new ArrayList<>(); result.addAll(res.instrs); //InstructionLLVM r = new AssignLLVMImp(new VarLLVMImpl(var.getType(),instr.t()),var); - InstructionLLVM r = new StoreLLVMImp(var.getType(),var,var.getType(),new VarLLVMImp(var.getType(),h.getVar(instr.t()),false)); + InstructionLLVM r = new StoreLLVMImp(var.getType(),var,new VarLLVMImp(var.getType(),h.getVar(instr.t()),false)); result.add(r); return result; } diff --git a/src/main/java/TP2/llvm/Interface.java b/src/main/java/TP2/llvm/Interface.java index ebed265..f37fade 100644 --- a/src/main/java/TP2/llvm/Interface.java +++ b/src/main/java/TP2/llvm/Interface.java @@ -55,6 +55,7 @@ public interface Interface { public S visitVarLLVM(VarLLVMImp e,H h); public S visitIcmpLLVM(IcmpLLVMImp e, H h); public S visitCallLLVM(CallLLVMImp e, H h); + public S visitGetElementPtrLLVM(GetElementPtr getElementPtr, H h); } /*public interface IdentifierLLVM{ //globaux @ et local % diff --git a/src/main/java/TP2/llvm/PrettyprinterLLVM_Visitor.java b/src/main/java/TP2/llvm/PrettyprinterLLVM_Visitor.java index e4f6b0b..ac8e989 100644 --- a/src/main/java/TP2/llvm/PrettyprinterLLVM_Visitor.java +++ b/src/main/java/TP2/llvm/PrettyprinterLLVM_Visitor.java @@ -120,6 +120,13 @@ TypeLLVMVisitor return str + e.type().accept(this,h) + " " + e.val1().accept(this,h) + ", " + e.val2().accept(this,h); } + @Override + public String visitGetElementPtrLLVM(GetElementPtr exp, String h) { + PointerLLVMImp type = (PointerLLVMImp)exp.getType(); + //getelementptr , , + return "getelementptr " + type.type().accept(this, h)+ ", " + exp.ptrVar().type().accept(this, h) + " " + exp.ptrVar().accept(this, h) + ", " + exp.i().getType().accept(this, h) + exp.i().accept(this, h); + } + @Override public String visitIcmpLLVM(IcmpLLVMImp e, String h) { return "icmp ne " + e.val1().getType().accept(this, h) +" "+ e.val1().accept(this, h) + ", " + e.val2().accept(this, h); @@ -132,7 +139,7 @@ TypeLLVMVisitor @Override public String visitStoreLLVM(StoreLLVMImp instr, String h) { - return INDENT+"store " + instr.valType().accept(this, "") + " " + instr.e().accept(this, "") + ", " + new PointerLLVMImp(instr.varType()).accept(this, "") + " " + instr.var().accept(this,""); + return INDENT+"store " + instr.type().accept(this, "") + " " + instr.e().accept(this, "") + ", " + new PointerLLVMImp(instr.type()).accept(this, "") + " " + instr.var().accept(this,""); } diff --git a/src/main/java/TP2/llvm/ProgramLLVM.java b/src/main/java/TP2/llvm/ProgramLLVM.java index dd2481e..e0adbac 100644 --- a/src/main/java/TP2/llvm/ProgramLLVM.java +++ b/src/main/java/TP2/llvm/ProgramLLVM.java @@ -67,7 +67,7 @@ public class ProgramLLVM { } } - public static record StoreLLVMImp(TypeLLVM valType, ExpressionLLVM e,TypeLLVM varType, ValLLVM var) implements InstructionLLVM{ + public static record StoreLLVMImp(TypeLLVM type, ExpressionLLVM e, ValLLVM var) implements InstructionLLVM{ @Override public S accept(InstructionLLVMVisitor v, H h) { return v.visitStoreLLVM(this, h); @@ -168,6 +168,20 @@ public class ProgramLLVM { } } + public static record GetElementPtr(VarLLVMImp ptrVar, ExpressionLLVM i) implements ExpressionLLVM{ + + @Override + public S accept(ExpressionLLVMVisitor v, H h) { + return v.visitGetElementPtrLLVM(this, h); + } + + @Override + public TypeLLVM getType() { + return ptrVar.type(); + } + + } + //Val public static record ValLLVMImp(TypeLLVM type, int val) implements ValLLVM{ diff --git a/tests/aLaMain.vsl b/tests/aLaMain.vsl index aa49412..bd41780 100644 --- a/tests/aLaMain.vsl +++ b/tests/aLaMain.vsl @@ -2,4 +2,5 @@ FUNC INT main() { INT a,b[10],c,d[11] a:=1 c:=2 + b[1] := 2 } \ No newline at end of file diff --git a/tests/fragment0/add0 b/tests/fragment0/add0 index 9dfdd70..517b2b7 100755 Binary files a/tests/fragment0/add0 and b/tests/fragment0/add0 differ diff --git a/tests/fragment0/add1 b/tests/fragment0/add1 index b03d758..e7085c9 100755 Binary files a/tests/fragment0/add1 and b/tests/fragment0/add1 differ diff --git a/tests/fragment0/const0 b/tests/fragment0/const0 index 1e56730..93e416c 100755 Binary files a/tests/fragment0/const0 and b/tests/fragment0/const0 differ diff --git a/tests/fragment0/const1 b/tests/fragment0/const1 index 8963a2c..3cf8124 100755 Binary files a/tests/fragment0/const1 and b/tests/fragment0/const1 differ diff --git a/tests/fragment0/div0 b/tests/fragment0/div0 index 313c5d0..0cedace 100755 Binary files a/tests/fragment0/div0 and b/tests/fragment0/div0 differ diff --git a/tests/fragment0/div1 b/tests/fragment0/div1 index b37ffbb..1cd23e3 100755 Binary files a/tests/fragment0/div1 and b/tests/fragment0/div1 differ diff --git a/tests/fragment0/mod b/tests/fragment0/mod index d8a31cb..1bfcf74 100755 Binary files a/tests/fragment0/mod and b/tests/fragment0/mod differ diff --git a/tests/fragment0/mult1 b/tests/fragment0/mult1 index a5c3dba..cc7d7bd 100755 Binary files a/tests/fragment0/mult1 and b/tests/fragment0/mult1 differ diff --git a/tests/fragment0/mult2 b/tests/fragment0/mult2 index 5879018..0f7e296 100755 Binary files a/tests/fragment0/mult2 and b/tests/fragment0/mult2 differ diff --git a/tests/fragment0/paren b/tests/fragment0/paren index 8c2d236..9b91d56 100755 Binary files a/tests/fragment0/paren and b/tests/fragment0/paren differ diff --git a/tests/fragment0/priority1 b/tests/fragment0/priority1 index b3776d2..2befceb 100755 Binary files a/tests/fragment0/priority1 and b/tests/fragment0/priority1 differ diff --git a/tests/fragment0/priority2 b/tests/fragment0/priority2 index 38cc9eb..78ef7ae 100755 Binary files a/tests/fragment0/priority2 and b/tests/fragment0/priority2 differ diff --git a/tests/fragment0/sub0 b/tests/fragment0/sub0 index a71c29d..086ed94 100755 Binary files a/tests/fragment0/sub0 and b/tests/fragment0/sub0 differ diff --git a/tests/fragment0/sub1 b/tests/fragment0/sub1 index 55e36b6..fd7eda3 100755 Binary files a/tests/fragment0/sub1 and b/tests/fragment0/sub1 differ diff --git a/tests/fragment1/assign1 b/tests/fragment1/assign1 index 2c0cb1c..ef4eb30 100755 Binary files a/tests/fragment1/assign1 and b/tests/fragment1/assign1 differ diff --git a/tests/fragment1/assign2 b/tests/fragment1/assign2 index 2ba9eb3..f2b3992 100755 Binary files a/tests/fragment1/assign2 and b/tests/fragment1/assign2 differ diff --git a/tests/fragment1/block b/tests/fragment1/block index 458dda7..21099c9 100755 Binary files a/tests/fragment1/block and b/tests/fragment1/block differ diff --git a/tests/fragment1/decl b/tests/fragment1/decl index 60670d4..fe41532 100755 Binary files a/tests/fragment1/decl and b/tests/fragment1/decl differ diff --git a/tests/fragment1/hello_world b/tests/fragment1/hello_world index b94fac9..0f6aa9e 100755 Binary files a/tests/fragment1/hello_world and b/tests/fragment1/hello_world differ diff --git a/tests/fragment1/if1 b/tests/fragment1/if1 index b5231f4..5f24bf0 100755 Binary files a/tests/fragment1/if1 and b/tests/fragment1/if1 differ diff --git a/tests/fragment1/if2 b/tests/fragment1/if2 index 8271f70..5f24bf0 100755 Binary files a/tests/fragment1/if2 and b/tests/fragment1/if2 differ diff --git a/tests/fragment1/print1 b/tests/fragment1/print1 index f9faf29..dba49f3 100755 Binary files a/tests/fragment1/print1 and b/tests/fragment1/print1 differ diff --git a/tests/fragment1/print2 b/tests/fragment1/print2 index ba8955f..dc81c67 100755 Binary files a/tests/fragment1/print2 and b/tests/fragment1/print2 differ diff --git a/tests/fragment1/print3 b/tests/fragment1/print3 index 79be5b9..e116db0 100755 Binary files a/tests/fragment1/print3 and b/tests/fragment1/print3 differ diff --git a/tests/fragment1/print4 b/tests/fragment1/print4 index a036668..add719e 100755 Binary files a/tests/fragment1/print4 and b/tests/fragment1/print4 differ diff --git a/tests/fragment1/read0 b/tests/fragment1/read0 deleted file mode 100755 index 958a221..0000000 Binary files a/tests/fragment1/read0 and /dev/null differ diff --git a/tests/fragment1/read1 b/tests/fragment1/read1 deleted file mode 100755 index 4a79e5f..0000000 Binary files a/tests/fragment1/read1 and /dev/null differ diff --git a/tests/fragment1/read2 b/tests/fragment1/read2 deleted file mode 100755 index 04f77b0..0000000 Binary files a/tests/fragment1/read2 and /dev/null differ diff --git a/tests/fragment1/sequence b/tests/fragment1/sequence index 06292b3..8d21d2f 100755 Binary files a/tests/fragment1/sequence and b/tests/fragment1/sequence differ diff --git a/tests/fragment1/while1 b/tests/fragment1/while1 index 43b8db4..c9ad8db 100755 Binary files a/tests/fragment1/while1 and b/tests/fragment1/while1 differ diff --git a/tests/fragment1/while2 b/tests/fragment1/while2 index f0013e8..a8f9a77 100755 Binary files a/tests/fragment1/while2 and b/tests/fragment1/while2 differ diff --git a/tests/fragment2/call b/tests/fragment2/call index 918641a..6ff922f 100755 Binary files a/tests/fragment2/call and b/tests/fragment2/call differ diff --git a/tests/fragment2/call2 b/tests/fragment2/call2 index 8be4c43..61f7b7d 100755 Binary files a/tests/fragment2/call2 and b/tests/fragment2/call2 differ diff --git a/tests/fragment2/call3expr b/tests/fragment2/call3expr index 4d71261..0e863ae 100755 Binary files a/tests/fragment2/call3expr and b/tests/fragment2/call3expr differ diff --git a/tests/fragment2/call4if b/tests/fragment2/call4if index be1419c..b90010b 100755 Binary files a/tests/fragment2/call4if and b/tests/fragment2/call4if differ diff --git a/tests/fragment2/proto1 b/tests/fragment2/proto1 index 974577e..381c3f4 100755 Binary files a/tests/fragment2/proto1 and b/tests/fragment2/proto1 differ diff --git a/tests/fragment2/proto2 b/tests/fragment2/proto2 index 25a79ed..b3f19bb 100755 Binary files a/tests/fragment2/proto2 and b/tests/fragment2/proto2 differ diff --git a/tests/testsAdvanced/carre b/tests/testsAdvanced/carre index 860eed4..70c8d16 100755 Binary files a/tests/testsAdvanced/carre and b/tests/testsAdvanced/carre differ diff --git a/tests/testsAdvanced/diverge b/tests/testsAdvanced/diverge index f7a93d9..8b168f6 100755 Binary files a/tests/testsAdvanced/diverge and b/tests/testsAdvanced/diverge differ diff --git a/tests/testsAdvanced/divergeDifficile b/tests/testsAdvanced/divergeDifficile index be8ec84..adf6a5c 100755 Binary files a/tests/testsAdvanced/divergeDifficile and b/tests/testsAdvanced/divergeDifficile differ diff --git a/tests/testsAdvanced/portee b/tests/testsAdvanced/portee deleted file mode 100755 index 43de3e0..0000000 Binary files a/tests/testsAdvanced/portee and /dev/null differ diff --git a/tests/testsAdvanced/portee2 b/tests/testsAdvanced/portee2 index 0fc701b..2401e11 100755 Binary files a/tests/testsAdvanced/portee2 and b/tests/testsAdvanced/portee2 differ