Interpreteur/Tables/tables.c

197 lines
6.3 KiB
C

#include "tables.h"
#include <stdio.h>
#include <stdlib.h>
#define TAILLE_BUFFER_INSTRUCTIONS (1024)
#define TAILLE_MEMOIRE (64)
/**************************************************/
/**************************************************/
/************ Variables et structures *************/
/**************************************************/
/**************************************************/
// Structure coding an instruction
struct str_instruction {
enum instruction_t instruction;
int param1;
int param2;
int param3;
};
// Buffer stockant le programme
struct str_instruction programme[TAILLE_BUFFER_INSTRUCTIONS * sizeof(struct str_instruction)];
// Pointeur d'instruction
int eip = 0;
// Memoire du programme
int mem[TAILLE_MEMOIRE];
// Pointeur de base dans la mémoire
int ebp = 0;
/**************************************************/
/**************************************************/
/******* Fonctions internes de verification *******/
/**************************************************/
/**************************************************/
// Verifie qu'une adresse est bien en mémoire (renvoi l'adresse si oui, leve une exception si non)
int check_adresse(int adresse) {
if (adresse >= TAILLE_MEMOIRE || adresse < 0) {
printf("\033[31;01m ERROR : \033[00m Segmentation fault\n");
exit(2);
}
return adresse;
}
// Verifie que eip ne depasse pas la taille du buffer
int check_eip(int eip) {
if (eip >= TAILLE_BUFFER_INSTRUCTIONS) {
printf("\033[31;01m ERROR : \033[00m Taille du buffer insuffisante pour charger le programme\n");
exit(2);
} else if (eip < 0) {
printf("\033[31;01m ERROR : \033[00m EIP < 0\n");
exit(2);
}
return eip;
}
/**************************************************/
/**************************************************/
/********** Fonction interne d'affichage **********/
/**************************************************/
/**************************************************/
// Affiche la mémoire
void print() {
int i;
printf("EBP : %d\n", ebp);
for (i=0; i<TAILLE_MEMOIRE; i++) {
printf("mem[%d] = %d\n", i, mem[i]);
}
}
/**************************************************/
/**************************************************/
/************** Instructions Writing **************/
/**************************************************/
/**************************************************/
// Add a new instruction
void add_instruction(enum instruction_t inst, int param1, int param2, int param3) {
struct str_instruction my_instruction = {inst, param1, param2, param3};
programme[check_eip(eip)] = my_instruction;
eip++;
}
/**************************************************/
/**************************************************/
/************* Execution du programme *************/
/**************************************************/
/**************************************************/
// execute le programme
void execute() {
printf("Debut de l'interpretation\n");
eip = 0;
int continuer = 1;
while (continuer) {
if (programme[eip].instruction == ADD) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] + mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == SUB) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] - mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == MUL) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] * mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == DIV) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] / mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == INF) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] < mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == SUP) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] > mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == EQU) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)] == mem[check_adresse(ebp + programme[eip].param3)];
} else if (programme[eip].instruction == AFC) {
mem[check_adresse(ebp + programme[eip].param1)] = programme[eip].param2;
} else if (programme[eip].instruction == CPY) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(ebp + programme[eip].param2)];
} else if (programme[eip].instruction == AFCA) {
mem[check_adresse(ebp + programme[eip].param1)] = ebp + programme[eip].param2;
} else if (programme[eip].instruction == READ) {
mem[check_adresse(ebp + programme[eip].param1)] = mem[check_adresse(mem[check_adresse(ebp + programme[eip].param2)])];
} else if (programme[eip].instruction == WRITE) {
mem[check_adresse(mem[check_adresse(ebp + programme[eip].param1)])] = mem[check_adresse(ebp + programme[eip].param2)];
} else if (programme[eip].instruction == JMP) {
eip = programme[eip].param1 - 1;
} else if (programme[eip].instruction == JMF) {
if (!mem[check_adresse(ebp + programme[eip].param1)]) {
eip = programme[eip].param2 - 1;
}
} else if (programme[eip].instruction == GET) {
printf("Veuillez saisir un nombre : \n");
scanf("%d", &(mem[check_adresse(ebp + programme[eip].param1)]));
} else if (programme[eip].instruction == PRI) {
printf("%d@%d\n", mem[check_adresse(ebp + programme[eip].param1)], ebp + programme[eip].param1);
} else if (programme[eip].instruction == CALL) {
mem[check_adresse(ebp + programme[eip].param2)] = ebp;
mem[check_adresse(ebp + programme[eip].param2 + 1)] = eip + 1;
ebp = ebp + programme[eip].param2 + 2;
eip = programme[eip].param1 - 1;
} else if (programme[eip].instruction == RET) {
int lastebp = ebp;
eip = mem[check_adresse(ebp - 1)] - 1;
ebp = mem[check_adresse(ebp - 2)];
mem[check_adresse(lastebp - 2)] = mem[check_adresse(lastebp)];
} else if (programme[eip].instruction == STOP) {
if (programme[eip].param1 == 0) {
continuer = 0;
}
}
eip = (eip + 1) % TAILLE_BUFFER_INSTRUCTIONS;
//printf("EIP : %d \n", eip);
}
}