diff --git a/interpreteur.c b/interpreteur.c index 2b3dc4ccd7621daa9f6b4e80f2c62092cd9efe79..061f6c6cea8a34776f8a9a0bed8c1461aed472da 100644 --- a/interpreteur.c +++ b/interpreteur.c @@ -1,10 +1,26 @@ #include "interpreteur.h" +int troncate(int n) { + if (n<0) + return 0; + else if (n>255) + return 255; + else + return n; +} + void interpreteur(char **matrix, int height, int width) { curseur cur; - int i, j; + int i, j, a, b; list pile = empty(); char tmp; + time_t t; + int string_mode = 0; + int bridge = 0; + char *endptr; + + /* initialise le module random */ + srand((unsigned) time(&t)); cur.x = 0; cur.y = 0; @@ -15,42 +31,273 @@ void interpreteur(char **matrix, int height, int width) { /* Action en fonction du caractère lu */ switch (cur.current_char) { - case 48 ... 57: - /* si on lit un entier */ - push(cur.current_char - 48, &pile); - break; - - case '>': - cur.current_dir = W; - break; + /* Si on est sur un pont, on ne lit pas l'instruction et on avance sur le pont */ + if (bridge) + { + bridge--; + break; + } - case ',': - if (is_empty(pile)) - tmp = '0'; - else - tmp = pop(&pile) + 48; - break; + /* Si on est en mode chaine de caractere on empile ce qu'on lit */ + if (string_mode) { + push(cur.current_char, &pile); + break; + } + + case '+': + a = pop(&pile); + b = pop(&pile); + push(a+b, &pile); + break; + + case '-': + a = pop(&pile); + b = pop(&pile); + push(b-a, &pile); + break; + + case '*': + a = pop(&pile); + b = pop(&pile); + push(a*b, &pile); + break; + + case ':': + a = pop(&pile); + if (a == 0) + push(42, &pile); + else + { + b = pop(&pile); + push(b/a, &pile); + } + break; + + case '%': + a = pop(&pile); + if (a == 0) + push(0xbadc0de, &pile); + else + { + b = pop(&pile); + push(b%a, &pile); + } + break; + + case '!': + a = pop(&pile); + push( a == 0 ? 1 : 0, &pile); + break; + + case '`': + a = pop(&pile); + b = pop(&pile); + push( b>a ? 1 : 0, &pile); + break; + + case '>': + cur.current_dir = E; + break; + + case '<': + cur.current_dir = W; + break; + + case 'v': + cur.current_dir = S; + break; + + case '^': + cur.current_dir = N; + break; + + case '?': + a = rand() % 8; + cur.current_dir = (direction) a; + break; + + case '\'': + a = pop(&pile); + cur.current_dir = (direction) a%8; + break; + + case ']': + cur.current_dir = (direction) cur.current_dir - 1 < 0 ? 7 : cur.current_dir - 1; + break; + + case '[': + cur.current_dir = (direction) (cur.current_dir + 1)%8; + break; + + case '_': + a = pop(&pile); + cur.current_dir = a == 0 ? E : W; + break; + + case '|': + a = pop(&pile); + cur.current_dir = a == 0 ? S : N; + break; + + case '/': + a = pop(&pile); + cur.current_dir = a == 0 ? NE : SW; + break; + + case '\\': + a = pop(&pile); + cur.current_dir = a == 0 ? SE : NW; + break; + + case '"': + string_mode = 1 - string_mode; + break; + + case '=': + if (is_empty(pile)) { + push(0, &pile); + push(0, &pile); + } + else + { + a = pop(&pile); + push(a, &pile); + push(a, &pile); + } + break; + + case '$': + a = pop(&pile); + b = pop(&pile); + push(a, &pile); + push(b, &pile); + break; + + case ';': + pop(&pile); + break; + + case '.': + a = pop(&pile); + printf("%i", a); + break; + + case ',': + a = pop(&pile); + printf("%c", a); + break; + + case '#': + a = pop(&pile); + bridge = a; + break; + + case 'g': + a = pop(&pile); + b = pop(&pile); + if (a<0 || b<0 || a>=height || b>=width) + push(0, &pile); + else + push(matrix[a][b], &pile); + break; + + case 'p': + a = pop(&pile); + b = pop(&pile); + int z = pop(&pile); + if (a>=0 && b>=0 && a<height && b<width) + matrix[a][b] = troncate(z); + break; + + case '&': + char buf[256]; + printf("Veuillez entrer un entier\n"); + fgets(buf, 256, stdin); + a = strtol(buf, NULL, 10); + while (buf == endptr) + { + printf("Erreur, veuillez saisir un nombre\n"); + fgets(buf, 256, stdin); + a = strtol(buf, endptr, 10); + } + break; - default: - break; + case '~': + printf("Veuillez entrer un caratere\n"); + tmp = fgetchar(); + push(tmp, &pile); + break; + + case 48 ... 57: + /* si on lit un entier */ + push(cur.current_char - 48, &pile); + break; + + case '@': + printf("Erreur: lecture @ sans fin de programme\n"); + exit(1); + break; + + case ' ': + break; + + default: + break; } /* Déplacement du curseur et lecture du prochain caractère */ switch (cur.current_dir) { case N: - cur.x = cur.x - 1; - /* Gérer les cas si on est au bord de la matrice */ - cur.current_char = matrix[cur.y][cur.x]; + cur.y = cur.y == 0 ? height-1 : cur.y - 1; break; - case NW: - cur.x = cur.x - 1; - cur.y = cur.y + 1; + case NE: + cur.x = cur.x == width-1 ? 0 : cur.x + 1; + cur.y = cur.y == 0 ? height-1 : cur.y - 1; break; + case E: + cur.x = cur.x == width-1 ? 0 : cur.x + 1; + break; + + case SE: + cur.x = cur.x == width-1 ? 0 : cur.x + 1; + cur.y = cur.y == height-1 ? 0 : cur.y + 1; + break; + + case S: + cur.y = cur.y == height-1 ? 0 : cur.y + 1; + break; + + case SW: + cur.y = cur.y == height-1 ? 0 : cur.y + 1; + cur.x = cur.x == 0 ? width-1 : cur.x - 1; + break; + + case W: + cur.x = cur.x == 0 ? width-1 : cur.x - 1; + break; + + case NW: + cur.x = cur.x == 0 ? width-1 : cur.x - 1; + cur.y = cur.y == 0 ? height-1 : cur.y - 1; + break; + default: + printf("Erreur de direction: %i\n", cur.current_dir); + exit(1); break; } + + cur.current_char = matrix[cur.y][cur.x]; + } + + printf("Contenu de la pile :\n"); + while (!is_empty(pile)) + { + printf("%i, ", pop(&pile)); } + printf("Fin de l'interpreteur\n"); + } \ No newline at end of file diff --git a/interpreteur.h b/interpreteur.h index 57ee305a1b58cfd7943b57ea6287442772883779..2952d2e50b8681a1d9301efb7a2d2e231c706fce 100644 --- a/interpreteur.h +++ b/interpreteur.h @@ -2,9 +2,11 @@ #define INTERPRETEUR_H #include "list.h" +#include <time.h> +/* type des directions pour qu'elles correspondent au cas ' */ typedef enum direction { - N, S, E, W, NE, NW, SE, SW + N, NE, E, SE, S, SW, W, NW } direction; typedef struct curseur { @@ -14,6 +16,8 @@ typedef struct curseur { direction current_dir; } curseur; +int troncate(int n); + void interpreteur(char **matrix, int height, int width); #endif \ No newline at end of file diff --git a/main.c b/main.c index 773dd3982c76d3d23aa0693e313590e1bffd84f8..e0cc210ac784f17acb3a80f3e15733fd90c45ff2 100644 --- a/main.c +++ b/main.c @@ -29,7 +29,6 @@ int main(int argc, char const *argv[]) width = 10*width + strtol(&c, NULL, 10); fread(&c, sizeof(char), 1, f); } - width = width/10; /* on récupère le nombre de lignes du fichier */ fread(&c, sizeof(char), 1, f); @@ -37,7 +36,6 @@ int main(int argc, char const *argv[]) height = 10*height + strtol(&c, NULL, 10); fread(&c, sizeof(char), 1, f); } - height = height/10; /* initialisation de la matrice */ matrix = (char **) malloc(height*sizeof(char *));