diff --git a/Makefile b/Makefile index e87876dd7ec55e7577ff9e5ac33e2be1385163ad..800cfd8b294482fcc7137fcc73cd82bfecdb2cc1 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,27 @@ CC=gcc -Wall -Wextra -ansi -TARGET=prog2d +TARGETS=interpreteur debogueur -OBJ=interpreteur.o list.o +OBJ=interpreteur.o list.o debogueur.o -all: $(TARGET) +all: $(TARGETS) -$(TARGET): $(OBJ) - $(CC) main.c $^ -o $(TARGET) +interpreteur : main.c list.o interpreteur.o + $(CC) $^ -o $@ + +debogueur : main.c list.o debogueur.o + $(CC) $^ -o $@ %.o: %.c %.h $(CC) -c $< -interpreteur.o: interpreteur.c interpreteur.h list.h +interpreteur.o: interpreteur.c common.h list.h + $(CC) -c $< + +debogueur.o: debogueur.c common.h list.h $(CC) -c $< clean: - rm $(OBJ) $(TARGET) + rm $(OBJ) $(TARGETS) re: clean all \ No newline at end of file diff --git a/README.md b/README.md index 980a1cc96912681dd007c8a5e42076f1da610382..40e8ce2501e770261c00f3a5a2c3df53bf8620f2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ gcc main.c list.c interpreteur.c ## Pour utiliser le Makefile : -- `make` pour générer l'exécutable `prog2d` -- `./prog2d fichier` pour exécuter le programme avec un fichier particulier +- `make` pour générer les exécutables `interpreteur` et `debogueur` +- `./interpreteur fichier` ou `./debogueur fichier` pour exécuter le programme avec un fichier particulier - `make clean` pour nettoyer l'espace -- `make re` pour nettoyer et re compiler \ No newline at end of file +- `make re` pour nettoyer et re compiler + +> Si vous compilez sous windows, il peut y avoir des bugs, enlevez `width/10` et `height/10` dans le main. \ No newline at end of file diff --git a/interpreteur.h b/common.h similarity index 60% rename from interpreteur.h rename to common.h index 2952d2e50b8681a1d9301efb7a2d2e231c706fce..3e1865385c82532ebafe2bf25c4edb7f2a80aa08 100644 --- a/interpreteur.h +++ b/common.h @@ -1,8 +1,11 @@ -#ifndef INTERPRETEUR_H -#define INTERPRETEUR_H +#ifndef COMMON_H +#define COMMON_H -#include "list.h" +#include <stdio.h> +#include <stdlib.h> #include <time.h> +#include <string.h> +#include "list.h" /* type des directions pour qu'elles correspondent au cas ' */ typedef enum direction { @@ -18,6 +21,10 @@ typedef struct curseur { int troncate(int n); +void affichage(char **matrix, int height, int width, list l, int x, int y); + +void copy_matrix(char **src, char **dest, int height, int width); + void interpreteur(char **matrix, int height, int width); #endif \ No newline at end of file diff --git a/debogueur.c b/debogueur.c new file mode 100644 index 0000000000000000000000000000000000000000..7ed5cc090deb91846ba0d23daaf105de986a2e0b --- /dev/null +++ b/debogueur.c @@ -0,0 +1,476 @@ +#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 affiche la grille avec la position courante du curseur + */ +void affichage(char **matrix, int height, int width, list l, int x, int y) { + int i, j; + + /* affichage du numéro des colonnes */ + printf("\n "); + for ( i = 0; i < width; i+=5) + printf("%2i ",i); + printf("\n"); + + printf(" "); + for (i = 0; i < width; i+=1) + if (i == x) + printf("v"); + else + printf("|"); + printf("\n"); + + /* affichage principal */ + for ( i = 0; i < height; i++) + { + /* affichage du numéro des lignes */ + if (i == y) + printf("%2i>", i); + else + printf("%2i-", i); + for ( j = 0; j < width; j++) + { + printf("%c", matrix[i][j]); + } + printf("\n"); + + } + + while (l != NULL) { + printf(" %i (%c) |", l->val, l->val); + l = l->next; + } + printf("\n"); + printf("x: %i, y: %i\n\n", x, y); + +} + +/** + * \brief copie la matrice src dans la matrice dest + * \attention les matrices doivent avoir la même taille + */ +void copy_matrix(char **src, char **dest, int height, int width) { + int i, j; + + for ( i = 0; i < height; i++) + for ( j = 0; j < width; j++) + dest[i][j] = src[i][j]; +} + +/** + * \brief debogue le fichier d'entrée en déplaçant le curseur + */ +void interpreteur(char **matrix, int height, int width) { + curseur cur; + int a, b, i; + list pile = empty(); + char tmp; + time_t t; + int string_mode = 0; + int bridge = 0; + int step = 1; + int flag_command = 1; + char buf[256]; + char prev_command[256]; + char *endptr; + char **init_matrix; + + /* initialisation pour une copie de la matrice de départ */ + init_matrix = (char **) malloc(height*sizeof(char *)); + + for (i=0 ; i<height ; i++) { + init_matrix[i] = (char *) malloc(width*sizeof(char)); + } + + copy_matrix(matrix, init_matrix, height, width); + + /* 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);*/ + + /* affichage de la grille */ + if (step == 1) + affichage(matrix, height, width, pile, cur.x, cur.y); + + /* Action en fonction de la commande lue */ + if (step == 1) { + printf("Veuillez saisir une commande :\n"); + + do + { + + fgets(buf, 256, stdin); + + if (strncmp(buf, "step", 4) == 0) { + flag_command = 1; + strcpy(prev_command, buf); + int n = strtol(buf+4, NULL, 10); + if (n > 0) + step = n; + else + step = 1; + } + else if (strncmp(buf, "run", 3) == 0) { + flag_command = 1; + step = 0; + } + else if (strncmp(buf, "restart", 7) == 0) { + /* retour à l'état initial */ + flag_command = 1; + strcpy(prev_command, buf); + copy_matrix(init_matrix, matrix, height, width); + cur.x = 0; + cur.y = 0; + cur.current_char = matrix[0][0]; + cur.current_dir = E; + string_mode = 0; + bridge = 0; + step = 1; + while (pile) + pop(&pile); + } + else if (strncmp(buf, "quit", 4) == 0) { + flag_command = 1; + printf("Arret du debogueur\n"); + return; + } + else if (strncmp(buf, "\n", 1) == 0) { + flag_command = 1; + /* actions en focntion de la commande précédente */ + if (strncmp(prev_command, "step", 4) == 0) { + int n = strtol(prev_command+4, NULL, 10); + if (n > 0) + step = n; + else + step = 1; + } + else if (strncmp(prev_command, "restart", 7) == 0) { + copy_matrix(init_matrix, matrix, height, width); + cur.x = 0; + cur.y = 0; + cur.current_char = matrix[0][0]; + cur.current_dir = E; + string_mode = 0; + bridge = 0; + step = 1; + while (pile) + pop(&pile); + } + else { + printf("Erreur de dernière commande\n"); + return; + } + } + else { + /* cas pour mauvaise commande */ + printf("\nMauvaise commande, veuillez en saisir une à nouveau :\n"); + flag_command = 0; + } + + } while (!flag_command); + } + else if (step > 1) + step --; + + /* 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 du debogueur\n"); + +} \ No newline at end of file diff --git a/interpreteur.c b/interpreteur.c index 6e33be17963cde7cd8934c2ffede5d5ff7fa3d3d..594cd340bbc7181b7cc064a544c2ebf1ebfc522b 100644 --- a/interpreteur.c +++ b/interpreteur.c @@ -1,6 +1,4 @@ -#include "interpreteur.h" -#include <stdio.h> -#include <stdlib.h> +#include "common.h" /** * \brief tronque un entier entre 0 et 255 diff --git a/main.c b/main.c index 71dc54b82ca7d5cb3809205a100475e7cb165714..002f268ddd4860c1cc9d52302774e0e817fb78cb 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ #include "list.h" -#include "interpreteur.h" +#include "common.h" #include <stdio.h> #include <stdlib.h> @@ -29,6 +29,8 @@ int main(int argc, char const *argv[]) width = 10*width + strtol(&c, NULL, 10); fread(&c, sizeof(char), 1, f); } + /* Enlever la ligne si y'a des bugs sous windows */ + width = width / 10; /* on récupère le nombre de lignes du fichier */ fread(&c, sizeof(char), 1, f); @@ -36,6 +38,8 @@ int main(int argc, char const *argv[]) height = 10*height + strtol(&c, NULL, 10); fread(&c, sizeof(char), 1, f); } + /* Enlever la ligne si y'a des bugs sous windows */ + height = height/10; /* initialisation de la matrice */ matrix = (char **) malloc(height*sizeof(char *));