Panini 4 cancers
This commit is contained in:
380
src/parcours.c
Normal file
380
src/parcours.c
Normal file
@@ -0,0 +1,380 @@
|
||||
#include <stdio.h>
|
||||
#include "parcours.h"
|
||||
#include "syntabs.h"
|
||||
#include "util.h"
|
||||
#include "parcours.h"
|
||||
|
||||
int contexte = C_VARIABLE_GLOBALE;
|
||||
int adresseGlobalCourante = 0;
|
||||
int adresseLocaleCourante = 0;
|
||||
int adresseArgumentCourant = 0;
|
||||
int afficheMips = 0;
|
||||
int creg = 0;
|
||||
extern dico_ dico;
|
||||
|
||||
void printMips( const char * msg ) {
|
||||
if(afficheMips)
|
||||
printf("%s\n", msg);
|
||||
}
|
||||
|
||||
int newReg() {
|
||||
return creg++%10;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_table(n_prog *n)
|
||||
{
|
||||
printMips(".data");
|
||||
parcours_l_dec(n->variables);
|
||||
printMips(".text");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int 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);
|
||||
parcours_instr(n->u.si_.alors);
|
||||
if(n->u.si_.sinon){
|
||||
parcours_instr(n->u.si_.sinon);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_instr_tantque(n_instr *n)
|
||||
{
|
||||
parcours_exp(n->u.tantque_.test);
|
||||
parcours_instr(n->u.tantque_.faire);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
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);
|
||||
parcours_exp(n->u.pour_.test);
|
||||
parcours_instr(n->u.pour_.faire);
|
||||
parcours_instr(n->u.pour_.incr);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_instr_affect(n_instr *n)
|
||||
{
|
||||
parcours_var(n->u.affecte_.var);
|
||||
parcours_exp(n->u.affecte_.exp);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_instr_appel(n_instr *n)
|
||||
{
|
||||
parcours_appel(n->u.appel);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_appel(n_appel *n)
|
||||
{
|
||||
int id = rechercheExecutable(n->fonction);
|
||||
if(id < 0) {
|
||||
printf("Fonction %s introuvable\n", n->fonction);
|
||||
affiche_dico();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_instr_retour(n_instr *n)
|
||||
{
|
||||
parcours_exp(n->u.retour_.expression);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
void parcours_instr_ecrire(n_instr *n)
|
||||
{
|
||||
int tRegistre = parcours_exp(n->u.ecrire_.expression);
|
||||
char tmp[250];
|
||||
sprintf(tmp, "move $a0 $t%d", tRegistre);
|
||||
printMips(tmp);
|
||||
printMips("li $v0 1");
|
||||
printMips("systcall");
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int parcours_l_exp(n_l_exp *n)
|
||||
{
|
||||
if(n){
|
||||
parcours_exp(n->tete);
|
||||
return 1 + parcours_l_exp(n->queue);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int parcours_exp(n_exp *n)
|
||||
{
|
||||
|
||||
if(n->type == varExp) return parcours_varExp(n);
|
||||
else if(n->type == opExp) return parcours_opExp(n);
|
||||
else if(n->type == intExp) return parcours_intExp(n);
|
||||
else if(n->type == appelExp) return parcours_appelExp(n);
|
||||
else if(n->type == lireExp) return parcours_lireExp(n);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int parcours_varExp(n_exp *n)
|
||||
{
|
||||
parcours_var(n->u.var);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int parcours_opExp(n_exp *n)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int parcours_intExp(n_exp *n)
|
||||
{
|
||||
char texte[ 50 ]; // Max. 50 chiffres
|
||||
sprintf(texte, "%d", n->u.entier);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int parcours_lireExp(n_exp *n)
|
||||
{
|
||||
printMips("li $v0 5");
|
||||
printMips("systcall");
|
||||
int iRegistre = newReg();
|
||||
char tmp[250];
|
||||
sprintf(tmp, "move $t%d $a0", iRegistre);
|
||||
printMips(tmp);
|
||||
return iRegistre;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
int 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)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
|
||||
dico.tab[id].complement = j;
|
||||
|
||||
contexte = C_VARIABLE_LOCALE;
|
||||
parcours_l_dec(n->u.foncDec_.variables);
|
||||
parcours_instr(n->u.foncDec_.corps);
|
||||
affiche_dico();
|
||||
sortieFonction();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
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: .word", n->nom);
|
||||
printMips(tmp);
|
||||
adresseGlobalCourante += 4;
|
||||
} else if (contexte == C_VARIABLE_LOCALE) {
|
||||
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)
|
||||
{
|
||||
if(n->type == simple) {
|
||||
parcours_var_simple(n);
|
||||
}
|
||||
else if(n->type == indicee) {
|
||||
parcours_var_indicee(n);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void parcours_var_simple(n_var *n)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void parcours_var_indicee(n_var *n)
|
||||
{
|
||||
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 );
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
Reference in New Issue
Block a user