Sélectionner une révision Git
interpreteur.c 8,11 Kio
#include "common.h"
/**
* \brief tronque un entier entre 0 et 255
*/
int troncate(int n) {
if (n<0)
return 0;
else if (n>255)
return 255;
else
return n;
}
/**
* \brief interprete le fichier d'entrée en déplaçant le curseur
*/
void interpreteur(char **matrix, int height, int width) {
curseur cur;
int a, b;
list pile = empty();
char tmp;
time_t t;
int string_mode = 0;
int bridge = 0;
char buf[256];
char *endptr;
/* initialisation du module random */
srand((unsigned) time(&t));
cur.x = 0;
cur.y = 0;
/* on commence en haut à gauche, direction à droite */
cur.current_char = matrix[0][0];
cur.current_dir = E;
while (cur.current_char != '@') {
/*printf("=-=-=-=-=-=-=\n");
printf("current char: %i = %c\n", cur.current_char, cur.current_char);*/
/* Action en fonction du caractère lu */
/* Si on est sur un pont, on ne lit pas l'instruction et on avance sur le pont */
if (bridge)
{
bridge--;
}
/* Si on est en mode chaine de caractere on empile ce qu'on lit */
else if (string_mode == 1) {
if (cur.current_char == '"')
string_mode = 1 - string_mode;
else
push(cur.current_char, &pile);
}
else {
/* switch pour les actions en fonction du caractère lu */
switch (cur.current_char)
{
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 '$':
if (is_empty(pile))
a = 0;
else
a = pop(&pile);
if (is_empty(pile))
b = 0;
else
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 '&':
printf("Veuillez entrer un entier\n");
fgets(buf, 256, stdin);
a = strtol(buf, &endptr, 10);
while (buf == endptr)
{
printf("Erreur, veuillez saisir un nombre\n");
fgets(buf, 256, stdin);
a = strtol(buf, &endptr, 10);
}
push(a, &pile);
break;
case '~':
printf("Veuillez entrer un caratere\n");
tmp = getchar();
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.y = cur.y == 0 ? height-1 : cur.y - 1;
break;
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];
/*print_list(pile);
printf("string_mode: %i\n", string_mode);
printf("bridge: %i\n", bridge);*/
}
printf("Fin de l'interpreteur\n");
}