This commit is contained in:
Vu Tuan Minh
2025-04-30 16:34:31 +02:00
50 changed files with 229 additions and 27 deletions

4
NULL Normal file
View File

@@ -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.

169
runAllTests2.py Normal file
View File

@@ -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")

View File

@@ -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();

View File

@@ -78,7 +78,7 @@ public class toLLVM_Visitor implements ProgramVisitor<SymTable,ProgramLLVMImp>,
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<SymTable,ProgramLLVMImp>,
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<SymTable,ProgramLLVMImp>,
ArrayList<InstructionLLVM> 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;
}

View File

@@ -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 %

View File

@@ -120,6 +120,13 @@ TypeLLVMVisitor<String,String>
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 <type de sortie>, <type d'entrée> <Var d'entrée>, <type de l'indice> <indice>
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<String,String>
@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,"");
}

View File

@@ -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 <H, S> S accept(InstructionLLVMVisitor<H, S> 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 <H, S> S accept(ExpressionLLVMVisitor<H, S> 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{

View File

@@ -2,4 +2,5 @@ FUNC INT main() {
INT a,b[10],c,d[11]
a:=1
c:=2
b[1] := 2
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.