842 lines
20 KiB
C
842 lines
20 KiB
C
#include <stdio.h>
|
|
#include "parcours.h"
|
|
#include "syntabs.h"
|
|
#include "util.h"
|
|
|
|
int nbArg = 0;
|
|
int nbvariableLocalFonc = 0;
|
|
int contexte = C_VARIABLE_GLOBALE;
|
|
int adresseGlobalCourante = 0;
|
|
int adresseLocaleCourante = 0;
|
|
int adresseArgumentCourant = 0;
|
|
int afficheMips = 0;
|
|
int creg = 0;
|
|
|
|
extern dico_ dico;
|
|
|
|
int tagindice = 0;
|
|
void new_tag(char * tmp){
|
|
sprintf(tmp,"e%d",tagindice );
|
|
++tagindice;
|
|
}
|
|
|
|
void printMips( const char * msg ) {
|
|
if(afficheMips)
|
|
printf("%s\n", msg);
|
|
}
|
|
|
|
int newReg() {
|
|
return creg++%10;
|
|
}
|
|
|
|
void debutFunc() {
|
|
printMips("subi $sp, $sp, 4");
|
|
printMips("sw $fp, 0($sp)");
|
|
printMips("move $fp, $sp");
|
|
printMips("subi $sp, $sp, 4");
|
|
printMips("sw $ra, 0($sp)");
|
|
}
|
|
|
|
void finFuncreturn(int bool){
|
|
printMips("lw $ra, 0($sp)");
|
|
printMips("addi $sp, $sp, 4");
|
|
printMips("lw $fp, 0($sp)");
|
|
printMips("addi $sp, $sp, 4");
|
|
if(!bool){
|
|
printMips("addi $sp, $sp, 4 #ignore valeur de retour");
|
|
}
|
|
printMips("jr $ra");
|
|
}
|
|
void finFunc() {
|
|
finFuncreturn(0);
|
|
}
|
|
|
|
void empile(char *reg) {
|
|
if(afficheMips) {
|
|
printf("subi $sp, $sp, 4\n");
|
|
printf("sw %s, 0($sp)\n", reg);
|
|
}
|
|
}
|
|
|
|
void depile(char *reg) {
|
|
if(afficheMips) {
|
|
printf("lw %s, 0($sp)\n", reg);
|
|
printf("addi $sp, $sp, 4\n");
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_table(n_prog *n)
|
|
{
|
|
printMips(".data");
|
|
parcours_l_dec(n->variables);
|
|
printMips(".text");
|
|
printMips("__start:");
|
|
printMips("jal main");
|
|
printMips("li $v0, 10");
|
|
printMips("syscall");
|
|
|
|
parcours_l_dec(n->fonctions);
|
|
|
|
int id = rechercheExecutable("main");
|
|
if(id < 0 || dico.tab[id].complement != 0) {
|
|
printf("Fonction main non trouvé\n");
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_l_instr(n_l_instr *n)
|
|
{
|
|
if(n) {
|
|
parcours_instr(n->tete);
|
|
parcours_l_instr(n->queue);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr(n_instr *n)
|
|
{
|
|
if(n) {
|
|
if(n->type == blocInst) parcours_l_instr(n->u.liste);
|
|
else if(n->type == affecteInst) parcours_instr_affect(n);
|
|
else if(n->type == siInst) parcours_instr_si(n);
|
|
else if(n->type == tantqueInst) parcours_instr_tantque(n);
|
|
else if(n->type == faireInst) parcours_instr_faire(n);
|
|
else if(n->type == pourInst) parcours_instr_pour(n);
|
|
else if(n->type == appelInst) parcours_instr_appel(n);
|
|
else if(n->type == retourInst) parcours_instr_retour(n);
|
|
else if(n->type == ecrireInst) parcours_instr_ecrire(n);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_si(n_instr *n)
|
|
{
|
|
parcours_exp(n->u.si_.test);
|
|
int iRegistre = 0;
|
|
char tmp[250];
|
|
char registre[250];
|
|
char faux[256];
|
|
char suite[256];
|
|
|
|
new_tag(faux);
|
|
new_tag(suite);
|
|
|
|
sprintf(registre,"$t%d",iRegistre);
|
|
depile(registre);
|
|
|
|
sprintf(tmp,"beq %s $zero %s", registre,faux);
|
|
printMips(tmp);
|
|
|
|
parcours_instr(n->u.si_.alors);
|
|
|
|
sprintf(tmp,"j %s",suite);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp,"%s:",faux);
|
|
printMips(tmp);
|
|
|
|
if(n->u.si_.sinon) {
|
|
parcours_instr(n->u.si_.sinon);
|
|
}
|
|
|
|
sprintf(tmp,"%s:",suite);
|
|
printMips(tmp);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_tantque(n_instr *n)
|
|
{
|
|
char tmp[256];
|
|
char etiquette[256];
|
|
char fin[256];
|
|
char registre[250];
|
|
|
|
new_tag(etiquette);
|
|
new_tag(fin);
|
|
|
|
sprintf(tmp,"%s:",etiquette);
|
|
printMips(tmp);
|
|
|
|
parcours_exp(n->u.tantque_.test);
|
|
|
|
int iRegistre = 0;
|
|
sprintf(registre,"$t%d",iRegistre);
|
|
depile(registre);
|
|
sprintf(tmp,"beq %s $0 %s", registre,fin);
|
|
printMips(tmp);
|
|
|
|
parcours_instr(n->u.tantque_.faire);
|
|
|
|
sprintf(tmp,"j %s",etiquette);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s:",fin);
|
|
printMips(tmp);
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_faire(n_instr *n)
|
|
{
|
|
|
|
parcours_instr(n->u.faire_.faire);
|
|
parcours_exp(n->u.faire_.test);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_pour(n_instr *n)
|
|
{
|
|
parcours_instr(n->u.pour_.init);
|
|
char tmp[250];
|
|
char etiquette[256];
|
|
char fin[256];
|
|
char registre[250];
|
|
|
|
new_tag(etiquette);
|
|
new_tag(fin);
|
|
|
|
sprintf(tmp,"%s:",etiquette);
|
|
printMips(tmp);
|
|
|
|
parcours_exp(n->u.pour_.test);
|
|
|
|
int iRegistre = 0;
|
|
sprintf(registre,"$t%d",iRegistre);
|
|
depile(registre);
|
|
sprintf(tmp,"beq %s $zero %s", registre, fin);
|
|
printMips(tmp);
|
|
|
|
parcours_instr(n->u.pour_.faire);
|
|
parcours_instr(n->u.pour_.incr);
|
|
|
|
sprintf(tmp,"j %s",etiquette);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s:",fin);
|
|
printMips(tmp);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_affect(n_instr *n)
|
|
{
|
|
char var[256];
|
|
char tmp[250];
|
|
char registre[250];
|
|
|
|
parcours_exp(n->u.affecte_.exp);
|
|
parcours_var(n->u.affecte_.var,var);
|
|
|
|
|
|
int iRegistre = 0;
|
|
sprintf(registre,"$t%d",iRegistre);
|
|
depile(registre);
|
|
sprintf(tmp,"sw %s, %s",registre, var);
|
|
printMips(tmp);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_appel(n_instr *n)
|
|
{
|
|
parcours_appel(n->u.appel);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_appel(n_appel *n)
|
|
{
|
|
char tmp[250];
|
|
|
|
int id = rechercheExecutable(n->fonction);
|
|
if(id < 0) {
|
|
printf("Fonction %s introuvable\n", n->fonction);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
printMips("subi $sp, $sp, 4 #Val Retour");
|
|
|
|
int nbArg = parcours_l_exp(n->args);
|
|
|
|
|
|
if(dico.tab[id].complement != nbArg) {
|
|
printf("Nombre Argument différent pour l'appel à %s\n", n->fonction);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
sprintf(tmp,"jal %s",n->fonction);
|
|
printMips(tmp);
|
|
int i = nbArg * 4;
|
|
if(i != 0) {
|
|
sprintf(tmp,"addi $sp, $sp, %d #désalocation des arguments",i);
|
|
printMips(tmp);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_instr_retour(n_instr *n)
|
|
{
|
|
char tmp[250];
|
|
char exec[250];
|
|
int returnAdress = 4 * (nbArg + 1);
|
|
parcours_exp(n->u.retour_.expression);
|
|
int iRegistre = 0;
|
|
sprintf(tmp,"$t%d",iRegistre);
|
|
depile(tmp);
|
|
sprintf(exec,"sw %s %d($fp) #Adresse de retour",tmp , returnAdress);
|
|
printMips(exec);
|
|
|
|
sprintf(tmp,"addi $sp, $sp %d # desallocation variables locales",nbvariableLocalFonc * 4);
|
|
printMips(tmp);
|
|
|
|
finFuncreturn(1);
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_instr_ecrire(n_instr *n)
|
|
{
|
|
parcours_exp(n->u.ecrire_.expression);
|
|
|
|
char tmp[250];
|
|
int iRegistre = 0;
|
|
|
|
sprintf(tmp,"$t%d",iRegistre);
|
|
depile(tmp);
|
|
sprintf(tmp, "move $a0, $t%d",iRegistre);
|
|
printMips(tmp);
|
|
printMips("li $v0, 1");
|
|
printMips("syscall");
|
|
printMips("li $a0, '\\n'");
|
|
printMips("li $v0, 11");
|
|
printMips("syscall");
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
int parcours_l_exp(n_l_exp *n)
|
|
{
|
|
if(n){
|
|
parcours_exp(n->tete);
|
|
return 1 + parcours_l_exp(n->queue);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_exp(n_exp *n)
|
|
{
|
|
if(n->type == varExp) parcours_varExp(n);
|
|
else if(n->type == opExp) parcours_opExp(n);
|
|
else if(n->type == intExp) parcours_intExp(n);
|
|
else if(n->type == appelExp) parcours_appelExp(n);
|
|
else if(n->type == lireExp) parcours_lireExp(n);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_varExp(n_exp *n)
|
|
{
|
|
char var[256];
|
|
char tmp[256];
|
|
|
|
parcours_var(n->u.var, var);
|
|
|
|
int iRegistre = 0;
|
|
sprintf(tmp, "lw $t%d, %s", iRegistre, var);
|
|
printMips(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre);
|
|
empile(tmp);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_opExp(n_exp *n)
|
|
{
|
|
char tmp[256];
|
|
|
|
int iRegistre = 0;
|
|
int iRegistre2 = 1;
|
|
int iRegistre3 = 2;
|
|
|
|
|
|
if(n->u.opExp_.op == plus) {
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"add $t%d, $t%d, $t%d",iRegistre, iRegistre2, iRegistre3);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == moins){
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"sub $t%d, $t%d, $t%d",iRegistre, iRegistre2, iRegistre3);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == fois) {
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"mult $t%d, $t%d", iRegistre2, iRegistre3);
|
|
printMips(tmp);
|
|
sprintf(tmp,"mflo $t%d",iRegistre);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == divise) {
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"div $t%d, $t%d", iRegistre2, iRegistre3);
|
|
printMips(tmp);
|
|
sprintf(tmp,"mflo $t%d",iRegistre);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == egal){
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
char etiquette[256];
|
|
new_tag(etiquette);
|
|
sprintf(tmp,"li $t%d, 1",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"beq $t%d, $t%d %s",iRegistre2, iRegistre3, etiquette);
|
|
printMips(tmp);
|
|
sprintf(tmp,"li $t%d, 0",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s:", etiquette);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == diff) {
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
char etiquette[256];
|
|
new_tag(etiquette);
|
|
sprintf(tmp,"li $t%d, 0",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"beq $t%d, $t%d %s",iRegistre2, iRegistre3, etiquette);
|
|
printMips(tmp);
|
|
sprintf(tmp,"li $t%d, 1",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s:", etiquette);
|
|
printMips(tmp);
|
|
}else if(n->u.opExp_.op == inf){
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
char etiquette[256];
|
|
new_tag(etiquette);
|
|
sprintf(tmp,"li $t%d, 1",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"blt $t%d, $t%d %s",iRegistre2, iRegistre3, etiquette);
|
|
printMips(tmp);
|
|
sprintf(tmp,"li $t%d, 0",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s:", etiquette);
|
|
printMips(tmp);
|
|
}else if(n->u.opExp_.op == infeg){
|
|
parcours_exp(n->u.opExp_.op1);
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
char etiquette[256];
|
|
new_tag(etiquette);
|
|
sprintf(tmp,"li $t%d, 1",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"ble $t%d, $t%d %s",iRegistre2, iRegistre3, etiquette);
|
|
printMips(tmp);
|
|
sprintf(tmp,"li $t%d, 0",iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s:", etiquette);
|
|
printMips(tmp);
|
|
}else if(n->u.opExp_.op == ou){
|
|
char faux1[256];
|
|
char faux2[256];
|
|
char vrai[256];
|
|
char empile[256];
|
|
new_tag(faux1);
|
|
new_tag(faux2);
|
|
new_tag(vrai);
|
|
new_tag(empile);
|
|
|
|
parcours_exp(n->u.opExp_.op1);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
sprintf(tmp,"beq $zero, $t%d, %s",iRegistre2, faux1);
|
|
printMips(tmp);
|
|
sprintf(tmp,"j %s",vrai);
|
|
printMips(tmp);
|
|
sprintf(tmp,"%s :",faux1);
|
|
printMips(tmp);
|
|
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"or $t%d, $zero, $t%d",iRegistre, iRegistre3);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp,"j %s",empile);
|
|
printMips(tmp);
|
|
sprintf(tmp, "%s :", vrai);
|
|
printMips(tmp);
|
|
sprintf(tmp,"move $t%d $t%d",iRegistre, iRegistre2);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp,"%s : ", empile);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == et) {
|
|
char fin[256];
|
|
char faux[256];
|
|
new_tag(fin);
|
|
new_tag(faux);
|
|
|
|
parcours_exp(n->u.opExp_.op1);
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"beq $zero, $t%d, %s",iRegistre2,faux);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
empile(tmp);
|
|
|
|
parcours_exp(n->u.opExp_.op2);
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"beq $zero, $t%d, %s", iRegistre3, faux);
|
|
printMips(tmp);
|
|
|
|
|
|
sprintf(tmp,"and $t%d, $t%d, $t%d",iRegistre, iRegistre2, iRegistre3);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp,"j %s", fin);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp," %s :",faux);
|
|
printMips(tmp);
|
|
sprintf(tmp,"li $t%d 0",iRegistre);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp ," %s :",fin);
|
|
|
|
printMips(tmp);
|
|
|
|
} else if(n->u.opExp_.op == non) {
|
|
parcours_exp(n->u.opExp_.op1);
|
|
|
|
sprintf(tmp, "$t%d", iRegistre3);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp,"not $t%d $t%d",iRegistre,iRegistre3);
|
|
printMips(tmp);
|
|
} else if(n->u.opExp_.op == cond) {
|
|
char tmp[256];
|
|
char faux[256];
|
|
char empile[256];
|
|
new_tag(faux);
|
|
new_tag(empile);
|
|
|
|
parcours_exp(n->u.opExp_.op1);
|
|
|
|
sprintf(tmp, "$t%d", iRegistre2);
|
|
depile(tmp);
|
|
sprintf(tmp,"beq $t%d, $zero %s",iRegistre2, faux);
|
|
printMips(tmp);
|
|
|
|
parcours_exp(n->u.opExp_.op2);
|
|
|
|
sprintf(tmp, "$t%d", iRegistre);
|
|
depile(tmp);
|
|
sprintf(tmp,"j %s", empile);
|
|
printMips(tmp);
|
|
|
|
sprintf(tmp, "%s :", faux);
|
|
printMips(tmp);
|
|
parcours_exp(n->u.opExp_.op3);
|
|
sprintf(tmp, "$t%d", iRegistre);
|
|
depile(tmp);
|
|
|
|
sprintf(tmp, "%s :", empile);
|
|
printMips(tmp);
|
|
}
|
|
sprintf(tmp, "$t%d", iRegistre);
|
|
empile(tmp);
|
|
}
|
|
|
|
/*-------------------------------- -----------------------------------------*/
|
|
|
|
void parcours_intExp(n_exp *n)
|
|
{
|
|
int iRegistre = 0;
|
|
|
|
char tmp[256];
|
|
sprintf(tmp, "li $t%d, %d", iRegistre, n->u.entier);
|
|
printMips(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre);
|
|
empile(tmp);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_lireExp(n_exp *n)
|
|
{
|
|
printMips("li $v0 5");
|
|
printMips("syscall");
|
|
|
|
int iRegistre = 0;
|
|
char tmp[256];
|
|
|
|
sprintf(tmp, "move $t%d, $v0", iRegistre);
|
|
printMips(tmp);
|
|
sprintf(tmp, "$t%d", iRegistre);
|
|
empile(tmp);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_appelExp(n_exp *n)
|
|
{
|
|
parcours_appel(n->u.appel);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_l_dec(n_l_dec *n)
|
|
{
|
|
if( n ){
|
|
parcours_dec(n->tete);
|
|
parcours_l_dec(n->queue);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_dec(n_dec *n)
|
|
{
|
|
|
|
if(n){
|
|
if(n->type == foncDec) {
|
|
parcours_foncDec(n);
|
|
}
|
|
else if(n->type == varDec) {
|
|
parcours_varDec(n);
|
|
}
|
|
else if(n->type == tabDec) {
|
|
parcours_tabDec(n);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_foncDec(n_dec *n)
|
|
{
|
|
char tmp[256];
|
|
sprintf(tmp, "%s :", n->nom);
|
|
printMips(tmp);
|
|
debutFunc();
|
|
|
|
int i = rechercheExecutable(n->nom);
|
|
if( i >= 0) {
|
|
printf("Fonction %s déjà déclaré\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
int id = ajouteIdentificateur(n->nom, contexte, T_FONCTION, 0, -1);
|
|
entreeFonction();
|
|
contexte = C_ARGUMENT;
|
|
parcours_l_dec(n->u.foncDec_.param);
|
|
|
|
int j = 0;
|
|
for(int i = dico.sommet - 1; i >= 0; i--){
|
|
if(dico.tab[i].classe != C_ARGUMENT)
|
|
break;
|
|
j++;
|
|
}
|
|
nbArg = j;
|
|
i = id;
|
|
int nbvariableLocale = 0;
|
|
|
|
|
|
dico.tab[id].complement = j;
|
|
|
|
contexte = C_VARIABLE_LOCALE;
|
|
parcours_l_dec(n->u.foncDec_.variables);
|
|
while (i+1 < dico.sommet && (dico.tab[i+1].classe == C_VARIABLE_LOCALE
|
|
|| dico.tab[i+1].classe == C_ARGUMENT)){
|
|
if(dico.tab[i+1].classe == C_VARIABLE_LOCALE)
|
|
++nbvariableLocale;
|
|
++i;
|
|
}
|
|
nbvariableLocalFonc = nbvariableLocale;
|
|
|
|
parcours_instr(n->u.foncDec_.corps);
|
|
sprintf(tmp,"addi $sp, $sp %d # desallocation variables locales",nbvariableLocale * 4);
|
|
|
|
printMips(tmp);
|
|
|
|
affiche_dico();
|
|
sortieFonction();
|
|
finFunc();
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
void parcours_varDec(n_dec *n)
|
|
{
|
|
if(rechercheDeclarative(n->nom) >= 0) {
|
|
printf("Variable %s déjà déclaré\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
if (contexte == C_VARIABLE_GLOBALE) {
|
|
ajouteIdentificateur(n->nom, contexte, T_ENTIER, adresseGlobalCourante, -1);
|
|
char tmp[250];
|
|
sprintf(tmp, "$%s: .space 4", n->nom);
|
|
printMips(tmp);
|
|
adresseGlobalCourante += 4;
|
|
} else if (contexte == C_VARIABLE_LOCALE) {
|
|
printMips("subi $sp, $sp, 4");
|
|
ajouteIdentificateur(n->nom, contexte, T_ENTIER, adresseLocaleCourante, -1);
|
|
adresseLocaleCourante += 4;
|
|
} else if (contexte == C_ARGUMENT) {
|
|
ajouteIdentificateur(n->nom, contexte, T_ENTIER, adresseArgumentCourant, -1);
|
|
adresseArgumentCourant += 4;
|
|
} else {
|
|
printf("Wtf ? %s\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_tabDec(n_dec *n)
|
|
{
|
|
char texte[100]; // Max. 100 chars nom tab + taille
|
|
sprintf(texte, "%s[%d]", n->nom, n->u.tabDec_.taille);
|
|
|
|
if(rechercheDeclarative(n->nom) >= 0) {
|
|
printf("Tableau %s déjà déclaré\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
if (contexte == C_VARIABLE_GLOBALE) {
|
|
ajouteIdentificateur(n->nom, contexte, T_TABLEAU_ENTIER, adresseGlobalCourante, n->u.tabDec_.taille);
|
|
char tmp[250];
|
|
sprintf(tmp, "$%s: .space %d", n->nom, 4*n->u.tabDec_.taille);
|
|
printMips(tmp);
|
|
adresseGlobalCourante += 4*n->u.tabDec_.taille;
|
|
} else {
|
|
printf("Wtf ? %s\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_var(n_var *n , char * var)
|
|
{
|
|
if(n->type == simple) {
|
|
parcours_var_simple(n, var);
|
|
}
|
|
else if(n->type == indicee) {
|
|
parcours_var_indicee(n, var);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_var_simple(n_var *n, char * var)
|
|
{
|
|
int i = rechercheExecutable(n->nom);
|
|
if( i < 0) {
|
|
printf("Variable %s non déclaré\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
} else if (dico.tab[i].type == T_TABLEAU_ENTIER) {
|
|
printf("Indice tableau %s est attendu\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
|
|
if(dico.tab[i].classe == C_VARIABLE_GLOBALE) {
|
|
sprintf(var, "$%s", n->nom);
|
|
}
|
|
else if (dico.tab[i].classe == C_ARGUMENT) {
|
|
int adress = dico.tab[i].adresse;
|
|
int result = 4 * nbArg - adress;
|
|
sprintf(var, "%d($fp) #variable argument %s",result,n->nom);
|
|
}
|
|
else if (dico.tab[i].classe == C_VARIABLE_LOCALE){
|
|
int adresse = -1 *(8 + dico.tab[i].adresse);
|
|
sprintf(var, "%d($fp) #variable locale", adresse);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void parcours_var_indicee(n_var *n, char * var)
|
|
{
|
|
int i = rechercheExecutable(n->nom);
|
|
if( i < 0) {
|
|
printf("Tableau %s non déclaré\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
} else if (dico.tab[i].type == T_ENTIER) {
|
|
printf("%s n'est pas un Tableau\n", n->nom);
|
|
affiche_dico();
|
|
exit(1);
|
|
}
|
|
parcours_exp( n->u.indicee_.indice );
|
|
depile ("$t4");
|
|
printMips("add $t4,$t4,$t4");
|
|
printMips("add $t4,$t4,$t4");
|
|
sprintf(var,"$%s($t4)",n->nom);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|