242 lines
7.7 KiB
Java
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();
|
|
}
|
|
}
|