Files
tp2-vsl-pds/src/main/java/TP2/asd/SymTable.java
2025-04-29 00:50:56 +02:00

242 lines
7.7 KiB
Java

package TP2.asd;
import java.util.ArrayList;
import org.pcollections.*;
import TP2.asd.Interface.Type;
import TP2.asd.Program.Type_intImp;
import TP2.llvm.ProgramLLVM.DeclarGlobalLLVMImp;
import TP2.llvm.ProgramLLVM.DefineLLVMImp;
public class SymTable {
private PStack<PMap<String,ValueVarMap>> varMap;
private PMap<String,ValueFunMap> functionsMap;
private int[] id ; //id partagé entre toute les symTable, [0] : idVar, [1] : idLabel, [2] : idGlobalVar
private ArrayList<DeclarGlobalLLVMImp> declarationsGlobal; //aussi partagé entre toute les symTable (.fmt pour les print et scan)
public SymTable(){
this.id = new int[3];
this.varMap= ConsPStack.singleton(HashTreePMap.empty());
this.functionsMap = HashTreePMap.empty();
this.declarationsGlobal = new ArrayList<>();
this.id[0] = 1; //idVar
this.id[1] = 1; //idLaber
this.id[2] = 1; //idGlobalVar
}
public SymTable(PStack<PMap<String,ValueVarMap>> varMap, PMap<String,ValueFunMap> functionsMap, int[] id,ArrayList<DeclarGlobalLLVMImp> declarationsGlobal){
this.varMap= varMap;
this.id = id;
this.functionsMap = functionsMap;
this.declarationsGlobal = declarationsGlobal;
}
public static class ValueFunMap{
public DefineLLVMImp define;
public Boolean isProto;
public ValueFunMap(DefineLLVMImp define, Boolean isProto){
this.define = define;
this.isProto = isProto;
}
}
public SymTable newBlock() {
return new SymTable(varMap.plus(HashTreePMap.empty()), functionsMap, id,declarationsGlobal);
}
public SymTable outBlock() {
if (varMap.size() > 1) {
return new SymTable(varMap.minus(0), functionsMap, id,declarationsGlobal);
} else {
return this;
}
}
public static class ValueVarMap{
public Type type;
public int id;
public Boolean isParam;
public ValueVarMap(Type type,int id, Boolean isParam){
this.type = type;
this.id = id;
this.isParam = isParam;
}
}
/*public void update(SymTable symTable2){
this.id = symTable2.getId();
this.idLabel = symTable2.getIdLabel();
this.declarationsGlobal = symTable2.getDeclarationGlobal();
}*/
public ArrayList<DeclarGlobalLLVMImp> getDeclarationGlobal(){
return this.declarationsGlobal;
}
public static class Result{
public SymTable symTable;
public String var;
public Result(SymTable symTable, String var){
this.symTable = symTable;
this.var = var;
}
}
public SymTable addFunction(DefineLLVMImp function, Boolean isProto){
ValueFunMap value = this.functionsMap.get(function.name());
if(value == null || (value!=null && value.isProto && !isProto)){
return new SymTable(this.varMap, this.functionsMap.plus(function.name(),new ValueFunMap(function,isProto)), this.id,this.declarationsGlobal);
}
else{
if(value.isProto) System.err.println("[VSL compile error] : Le prototype "+function.name()+" existe déjà");
else if(isProto) System.err.println("[VSL compile error] : Le prototype "+function.name()+" doit être déclaré avant son implémentation");
else System.err.println("[VSL compile error] : La fonction "+function.name()+" existe déjà");
return null;
}
}
public ValueFunMap getFunction(String name){
return this.functionsMap.get(name);
}
public int getId(){
return this.id[0];
}
public int getIdLabel(){
return this.id[1];
}
public int getNewId(){
int a = this.id[0];
this.id[0]++;
return a;
}
public int getNewIdLabel(){
int a = this.id[1];
this.id[1]++;
return a;
}
public Result addNewTempVar(){
String newVar = "temp"+id[0];
SymTable newSymTab = this.addVarInTab(newVar,new Type_intImp(),false);
return new Result(newSymTab,newVar);
}
public Result addParam(String nomParam){
String newParam = "param_"+nomParam;
SymTable newSymTab = this.addVarInTab(nomParam,new Type_intImp(),true);
return new Result(newSymTab,newParam);
}
public String getGlobalDeclName(){;
return "fmt"+id[2];
}
public void addGlobalDecl(DeclarGlobalLLVMImp decl){
id[2]++;
this.declarationsGlobal.add(decl);
}
public Result addVar(String nomVar) {
PMap<String, ValueVarMap> top = varMap.get(0);
if (top.containsKey(nomVar)) {
System.err.println("[VSL compile error] :" + "Erreur");
return new Result(this, null);
}
String realName = nomVar + id[0];
top = top.plus(nomVar, new ValueVarMap(new Type_intImp(), id[0], false));
id[0]++;
SymTable newSym = new SymTable(varMap.minus(0).plus(0, top), functionsMap, id,this.declarationsGlobal);
return new Result(newSym, realName);
}
//retourne le nom de la var déjà déclaré avec son id
public String getVar(String nomVar){
for(PMap<String,ValueVarMap> scope : varMap) {
if (scope.containsKey(nomVar)) {
ValueVarMap value = scope.get(nomVar);
String prefix = "";
if(value.isParam){
prefix = "param_";
}
return prefix + nomVar + value.id;
}
}
System.err.println("[VSL compile error] :" + nomVar+" n'est pas trovué");
return null;
}
public Boolean isPresentVar(String nomVar){
for (PMap<String,ValueVarMap> scope : varMap) {
if (scope.containsKey(nomVar)) {
return true;
}
}
System.err.println("[VSL compile error] :" + nomVar+" n'est pas trouvé");
return false;
}
public Type getvar_Type(String s){
for (PMap<String,ValueVarMap> scope : varMap) {
if (scope.containsKey(s)) {
return scope.get(s).type;
}
}
return null;
}
//retourne le type de la var
public Type getType(String nomVar){
for (PMap<String,ValueVarMap> scope : varMap) {
if (scope.containsKey(nomVar)) {
return scope.get(nomVar).type;
}
}
return null;
}
public SymTable addVarInTab(String nomVar, Interface.Type type, boolean isParam) {
PMap<String,ValueVarMap> top = varMap.get(0);
if (top.containsKey(nomVar)) {
System.err.println(nomVar+ " déjà déclaré.");
return this;
}
top = top.plus(nomVar, new ValueVarMap(type, id[0], isParam));
if(!isParam) this.id[0]++;
return new SymTable(varMap.minus(0).plus(0, top), functionsMap, id, this.declarationsGlobal);
}
public String print_all(){
StringBuilder str = new StringBuilder();
str.append("Id = ").append(id[0]).append("\n");
str.append("VARIABLES:\n");
int scopeLevel = varMap.size();
for (PMap<String, ValueVarMap> scope : varMap) {
str.append("Block Level ").append(scopeLevel--).append(":\n");
for (String varName : scope.keySet()) {
ValueVarMap value = scope.get(varName);
str.append("Name: ").append(varName)
.append(", Id: ").append(value.id)
.append(", Type: ").append(value.type)
.append(", IsParam: ").append(value.isParam)
.append("\n");
}
}
str.append("FUNCTIONS:\n");
for (String funcName : functionsMap.keySet()) {
str.append(" Name: ").append(funcName).append("\n");
}
return str.toString();
}
}