-
Notifications
You must be signed in to change notification settings - Fork 0
/
CalculetteUtils.java
295 lines (266 loc) · 8.38 KB
/
CalculetteUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
import java.util.*;
/**
* Classe permettant d'effectuer des actions pour la calculette.
*/
class CalculetteUtils {
/**
* Table de symboles (pour variables globales et locales, et fonctions).
*/
private TablesSymboles tablesSymboles = new TablesSymboles();
/**
* Prochain numero de label à utiliser.
*/
private int currentLabel = 1;
/**
* Liste contenant les noms des variables globales créées.
*/
private List<String> globalVariables = new ArrayList<>();
/**
* Liste contenant les noms des variables locales créées.
*/
private List<String> localVariables = new ArrayList<>();
/**
* Booléen permettant de savoir si une table locale est initialisée.
*/
private boolean localTableEnabled = false;
/**
* Permet de savoir quelle fonction on déclare.
*/
private String currentFunctionDefinition = null;
/**
* Récupère les tables de symboles.
*
* @return tables de symboles
*/
public TablesSymboles getTablesSymboles() {
return this.tablesSymboles;
}
/**
* Renvoie le label suivant (pour un branchement ou un boucle par exemple)
*
* @return nouveau label
*/
public String getNewLabel() {
return "B" + (this.currentLabel++);
}
/**
* Vérifie si le paramètre @code{type} est un flottant
*
* @param type type de la variable ou de l'expression
* @return est un flottant ou non
*/
public static boolean isFloat(String type) {
return type.equals("float");
}
/**
* Vérifie si le paramètre @code{type} est un entier
*
* @param type type de la variable ou de l'expression
* @return est un entier ou non
*/
public static boolean isInteger(String type) {
return type.equals("int");
}
/**
* Vérifie si le paramètre @code{type} est un booléen
*
* @param type type de la variable ou de l'expression
* @return est un booléen ou non
*/
public static boolean isBool(String type) {
return type.equals("bool");
}
/**
* Vérifie si le paramètre @code{at} est identifiant de type flottant
*
* @param at adresse de la variable
* @return est un flottant ou non
*/
public static boolean isFloat(AdresseType at) {
return at.type.equals("float");
}
/**
* Vérifie si le paramètre @code{at} est identifiant de type entier
*
* @param at adresse de la variable
* @return est un entier ou non
*/
public static boolean isInteger(AdresseType at) {
return at.type.equals("int");
}
/**
* Vérifie si le paramètre @code{at} est identifiant de type booléen
*
* @param at adresse de la variable
* @return est un booléen ou non
*/
public static boolean isBool(AdresseType at) {
return at.type.equals("bool");
}
/**
* Récupère l'adresse et le type d'une certaine variable
*
* @param id identifiant de la variable
* @return adresse-type
*/
public AdresseType getAdresseType(String id) {
return this.tablesSymboles.getAdresseType(id);
}
/**
* Calcule le type final d'un calcul entre 2 expressions
*
* @param a première expression
* @param b deuxième expression
* @return type final
*/
public static String getFinalExpressionType(String a, String b) {
if (a.equals("float") || b.equals("float")) {
return "float";
}
return (a.equals("int") || b.equals("int") ? "int" : "bool");
}
/**
* Génère le code MVaP pour dépiler la variable
*
* @param name identifiant de la variable
* @return code MVaP pour dépiler
*/
public String generatePopForVariable(String name) {
return generatePopFromType(this.tablesSymboles.getAdresseType(name).type);
}
/**
* Génère le code MVaP pour dépiler en fonction du type
*
* @param type type pour connaître le nombre de POP à générer
* @return code MVaP pour dépiler
*/
public String generatePopFromType(String type) {
String res = "";
for (int i = 0; i < AdresseType.getSize(type); i++) {
res += " POP\n";
}
return res;
}
/**
* Dépile toute la pile (en fonction des variables globales déclarées)
*
* @return code MVaP pour dépiler
*/
public String unstackWholeStack() {
int res = 0;
for (String variable : this.globalVariables) {
res += AdresseType.getSize(this.tablesSymboles.getAdresseType(variable).type);
}
this.globalVariables = new ArrayList<>();
return " FREE " + res + "\n";
}
/**
* Génère un type d'action en fonction de si c'est une variable locale ou
* globale.
*
* @param name identifiant de la variable
* @param actionName nom de l'action
* @return code MVaP
*/
public String getTypeOfAction(String name, String actionName) {
AdresseType at = this.tablesSymboles.getAdresseType(name);
return getTypeOfActionWithAddress(at, actionName);
}
/**
* Génère un type d'action en fonction de si c'est une variable locale ou
* globale.
*
* @param at adresse-type de la variable
* @param actionName nom de l'action
* @return code MVaP
*/
public static String getTypeOfActionWithAddress(AdresseType at, String actionName) {
if (at.adresse < 0) {
return " " + actionName + "L " + at.adresse + "\n";
}
return " " + actionName + "G " + at.adresse + "\n";
}
/**
* Met une variable dans la table de symboles
*
* @param name identifiant de la variable
* @param type type de la variable
*/
public void putVariable(String name, String type) {
this.tablesSymboles.putVar(name, type);
if (!this.localTableEnabled) {
this.globalVariables.add(name);
} else {
this.localVariables.add(name);
}
}
/**
* Ajout d'une fonction dans la table de symboles
*
* @param name identifiant de la fonction
* @param type type de retour de la fonction
* @return si elle n'existe pas (=true), si elle existe déjà (=false)
*/
public boolean newFunction(String name, String type) {
this.currentFunctionDefinition = name;
return this.tablesSymboles.newFunction(name, type);
}
/**
* Récupère l'adresse-type de la fonction qui est en train d'être déclarée.
*
* @return adresse-type de la fonction déclarée actuellement
*/
public String getAdresseTypeOfCurrentFunction() {
return this.getFunction(this.currentFunctionDefinition);
}
/**
* Récupère le type de retour de la fonction.
*
* @param name identifiant de la fonction
* @return type de retour de la fonction
*/
public String getFunction(String name) {
return this.tablesSymboles.getFunction(name);
}
/**
* Créer la table locale.
*/
public void newLocaleTable() {
this.tablesSymboles.newTableLocale();
this.localTableEnabled = true;
}
/**
* Détruit la table locale.
*/
public void dropLocaleTable() {
this.tablesSymboles.dropTableLocale();
this.localTableEnabled = false;
this.localVariables = new ArrayList<>();
}
/**
* Génère la taille prise par l'ensemble des variables locales (arguments de la
* fonction). Utilisé pour le token return.
*
* @return taille prise par les variables locales
*/
public int generateStoreLocalToFunction() {
int res = 0;
for (String variable : localVariables) {
res += AdresseType.getSize(tablesSymboles.getAdresseType(variable).type);
}
return res;
}
/**
* Génère le code MVaP pour convertir un entier en booléen (modulo 2). Gère les
* entiers négatifs.
*
* @return code MVaP pour convertir un entier en booléen
*/
public String convertToBool() {
// String modulo2 = " DUP\n PUSHI 2\n DIV\n PUSHI 2\n MUL\n SUB\n";
// String label = this.getNewLabel();
// return modulo2 + " DUP\n PUSHI 0\n INF\n JUMPF " + label + "\n PUSHI -1\n
// MUL\nLABEL " + label + "\n";
return " PUSHI 0\n NEQ\n";
}
}