Files
tp2-vsl-pds/src/main/java/TP2/LLVM.java
2025-04-01 16:58:01 +02:00

312 lines
8.6 KiB
Java

package TP2;
import java.util.ArrayList;
import java.util.List;
public class LLVM {
static String INDENT = " ";
sealed interface Prog{}
sealed interface Fonction{
String toString(String string);}
sealed interface Instr permits Return,Bloc,Aff,Print,Read,IfThen,IfThenElse,While {
String toString(String string);}
sealed interface Type permits INT,VOID {}
sealed interface ListDecl{
String toString(String string);}
sealed interface ListPar{}
sealed interface ListInstr{
String toString(String string);}
sealed interface Par{}
sealed interface Expression{
Type getType();
}
sealed static interface Op{}
sealed interface Var extends Expression{
};
sealed interface Val extends Expression{
};
public static void main(String[] args) {
Add ADD = new Add();
Modulo MODULO = new Modulo();
Expression exp1 = new BinOp(ADD,new BinOp(ADD,new ValInt(0),new ValInt(1)),new ValInt(2));
ListPar param = new ListParImpl(new ArrayList<>());
ArrayList<Instr> l = new ArrayList<>();
l.add(new Return(exp1));
Fonction f = new FonctionImpl(new VOID(),"main",param,l);
Prog p1 = new ProgImpl(List.of(f));
System.out.println(p1.toString());
System.out.println("\n");
Var a = new VarInt("a");
Var b = new VarInt("b");
Prog p2 = new ProgImpl(List.of(
f,
new FonctionImpl(new INT(),"maFonction",new ListParImpl(List.of(new ParImpl(new INT(),a),new ParImpl(new INT(),b) )),List.of(
new IfThenElse(a,List.of(
new Print(List.of("a = ",a))
),List.of(
new Print(List.of("b = ",b))
)),
new While(b, List.of(
new Aff(b, new BinOp(MODULO,b,new ValInt(2)))
)),
new Return(new BinOp(ADD,a,b))
))
));
System.out.println(p2.toString());
}
record ProgImpl(List<Fonction> fonctions) implements Prog{
public String toString(){
String str ="";
for(int i = 0; i<fonctions.size(); i++){
str += fonctions.get(i).toString(INDENT)+"\n";
}
return str;
}
}
record FonctionImpl(Type type, String nom,ListPar param, List<Instr> instrs) implements Fonction{
public String toString(String indent){
String str = indent+"FUNC " + type.toString()+ " " + nom +" ("+param.toString()+"){\n";
for(int i = 0; i<instrs.size(); i++){
str += instrs.get(i).toString(indent+INDENT)+"\n";
}
str+= indent+"}";
return str;
}
}
record Return(Expression exp) implements Instr{
public String toString(String indent){
return indent+"RETURN " + exp.toString();
}
}
record Bloc(List<ListDecl> listDecls, ListInstr instrs) implements Instr{
public String toString(String indent){
String str = indent +"{\n";
for(int i = 0; i<listDecls.size(); i++){
str += listDecls.get(i).toString(indent+INDENT) +"\n";
}
str += instrs.toString(indent+INDENT);
str += indent +"}";
return str;
}
}
record Aff(Var var, Expression expression) implements Instr{
public String toString(String indent){
return indent + var.toString() + ":=" + expression.toString();
}
}
record Print(List<Object> items) implements Instr{
public String toString(String indent){
String str = indent+"PRINT ";
for(int i = 0; i<items.size(); i++){
if(items.get(i) instanceof Expression){
str += items.get(i).toString();
}
else if(items.get(i) instanceof String){
str += '"'+items.get(i).toString()+'"';
}
else System.err.println("Item de mauvais type dans PRINT");
if(i<items.size()-1) str += ", ";
}
return str;
}
}
record Read(List<Var> items) implements Instr{ //TODO pas bon
public String toString(String indent){
String str = indent + "READ";
for(int i = 0; i<items.size(); i++){
str += items.get(i).toString();
if(i<items.size()-1) str += ", ";
}
return str;
}
}
record IfThen(Expression cond, List<Instr> instrs) implements Instr{
public String toString(String indent){
String str = indent + "IF " + cond.toString() + "\n" + indent + "THEN\n";
for(int i = 0; i< instrs.size(); i++){
str += instrs.get(i).toString(indent+INDENT) + "\n";
if(i<instrs.size()-1) str += "\n";
}
return str;
}
}
record IfThenElse(Expression cond, List<Instr> instrs1, List<Instr> instrs2) implements Instr{
public String toString(String indent){
String str = indent + "IF " + cond.toString() + "\n" + indent + "THEN\n";
for(int i = 0; i< instrs1.size(); i++){
str += instrs1.get(i).toString(indent+INDENT) + "\n";
}
str += indent + "ELSE\n";
for(int i = 0; i< instrs2.size(); i++){
str += instrs2.get(i).toString(indent+INDENT);
if(i<instrs2.size()-1) str += "\n";
}
return str;
}
}
record While(Expression cond, List<Instr> instrs) implements Instr{
public String toString(String indent){
String str = indent + "WHILE " + cond.toString() +"\n" + indent +"DO{\n";
for(int i = 0; i< instrs.size(); i++){
str += instrs.get(i).toString(indent+INDENT) + "\n";
}
str += indent + "}";
return str;
}
}
record INT() implements Type{
public String toString(){
return "INT";
}
}
record VOID() implements Type{
public String toString(){
return "VOID";
}
}
record ListDeclImpl(Type type, List<String> vars) implements ListDecl{ //erreur
public String toString(String indent){
String str = indent + type.toString() + " ";
for(int i = 0; i<vars.size(); i++){
if(i<vars.size()-1){
str += vars.get(i)+",";
}
else str += vars.get(i);
}
return str;
}
}
record ListParImpl(List<Par> pars) implements ListPar{
public String toString(){
String str = "";
for(int i = 0; i<pars.size();i++){
str += pars.get(i).toString();
if(i<pars.size()-1) str += ", ";
}
return str;
}
}
record ListInstrImpl(List<Instr> instrs) implements ListInstr{
public String toString(String indent){
String str = "";
for(int i = 0; i<instrs.size();i++){
str += indent + instrs.get(i).toString() + "\n";
}
return str;
}
}
record ParImpl(Type type, Var var) implements Par{
public String toString(){
return type.toString() + " " + var.toString();
}
}
record BinOp(Op op,Expression e1, Expression e2) implements Expression{
public String toString(){
return "("+ e1 + " " + op.toString() + " " + e2 + ")";
}
public Type getType(){
Type t1 = e1.getType();
Type t2 = e2.getType();
if(t1 == t2) return t1;
else return null;
}
}
record Add() implements Op{
public String toString(){
return "+";
}
}
record Sub() implements Op{
public String toString(){
return "-";
}
}
record Modulo() implements Op{
public String toString(){
return "%";
}
}
record Mult() implements Op{
public String toString(){
return "*";
}
}
record Div() implements Op{
public String toString(){
return "/";
}
}
record ValInt(int val) implements Val{
public String toString(){
return val+"";
}
public Type getType(){
return new INT();
}
}
record VarInt(String nom) implements Var{
public String toString(){
return nom;
}
public Type getType(){
return new INT();
}
}
}