diff --git a/src/main.c b/src/main.c index 468ad3b..53511b9 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ -#include -#include -#include #include +#include +#include +#include #include #include @@ -9,10 +9,27 @@ #define BRACKETS_NB_MAX 1024 #define DATA_SIZE_MAX 65536 +// The advanced version of operations should always have value = simple version + 1 +enum operations_t { + NONE, + MEM_POINTER_ADD, + MEM_POINTER_ADD_NB, + MEM_POINTER_SUB, + MEM_POINTER_SUB_NB, + MEM_ADD, + MEM_ADD_NB, + MEM_SUB, + MEM_SUB_NB, + JUMP_IF_0, + JUMP_IF_NOT_0, + PRINT_CHAR, + GET_CHAR +}; + +typedef uint8_t operation_t; + int main(int argc, char *argv[]) { - clock_t start_time, end_time; - int status = EXIT_FAILURE; if(argc != 2) @@ -22,7 +39,7 @@ int main(int argc, char *argv[]) } FILE *program_file = NULL; - FILE *stripped_file = NULL; + FILE *intermediate_representation_file = NULL; program_file = fopen(argv[1], "r"); if(program_file == NULL) @@ -31,15 +48,13 @@ int main(int argc, char *argv[]) goto end; } - stripped_file = tmpfile(); - if(stripped_file == NULL) + intermediate_representation_file = tmpfile(); + if(intermediate_representation_file == NULL) { fprintf(stderr, "Error creating tmp file: %d\n", errno); goto end; } - start_time = clock(); - // Strip program file while(true) { @@ -52,27 +67,164 @@ int main(int argc, char *argv[]) if(err) { fprintf(stderr, "Error reading file: %d\n", ferror(program_file)); - return EXIT_FAILURE; + goto end; } break; } + operation_t operation = NONE; + static operation_t last_operation = NONE; + switch(c) { case '>': + operation = MEM_POINTER_ADD; + break; + case '<': + operation = MEM_POINTER_SUB; + break; + case '+': + operation = MEM_ADD; + break; + case '-': + operation = MEM_SUB; + break; + case '[': + operation = JUMP_IF_0; + break; + case ']': + operation = JUMP_IF_NOT_0; + break; + case '.': + operation = PRINT_CHAR; + break; + case ',': - fputc(c, stripped_file); + operation = GET_CHAR; + break; default: break; } + + if(operation == NONE) + { + continue; + } + + switch(operation) + { + case MEM_POINTER_ADD: + case MEM_POINTER_SUB: + case MEM_ADD: + case MEM_SUB: + if(operation == last_operation) + { + operation++; // Go to advanced version of operation + + if(fseek(intermediate_representation_file, -1, SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + + if(fwrite(&operation, sizeof(operation), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + + size_t nb = 2; + + if(fwrite(&nb, sizeof(nb), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + } + else if(operation + 1 == last_operation) + { + operation++; + + size_t nb; + + if(fseek(intermediate_representation_file, -sizeof(nb), SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + + if(fread(&nb, sizeof(nb), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error reading file: %d\n", errno); + goto end; + } + + nb++; + + if(fseek(intermediate_representation_file, -sizeof(nb), SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + + if(fwrite(&nb, sizeof(nb), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + } + else + { + if(fwrite(&operation, sizeof(operation), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + } + + break; + + case JUMP_IF_0: + case JUMP_IF_NOT_0: + if(fwrite(&operation, sizeof(operation), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + + size_t jump_pos = 0; + + if(fwrite(&jump_pos, sizeof(jump_pos), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + + break; + + case PRINT_CHAR: + case GET_CHAR: + if(fwrite(&operation, sizeof(operation), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + + break; + + default: + break; + } + + last_operation = operation; } if(fclose(program_file) == EOF) @@ -86,162 +238,293 @@ int main(int argc, char *argv[]) program_file = NULL; - rewind(stripped_file); - - size_t brackets_pos[BRACKETS_NB_MAX]; - size_t brackets_correspondances[BRACKETS_NB_MAX]; - // Parse brackets - size_t bracket_nb = 0; + rewind(intermediate_representation_file); while(true) { - int c = fgetc(stripped_file); + operation_t operation; + size_t nb_read = fread(&operation, sizeof(operation), 1, intermediate_representation_file); - if(c == EOF) + if(nb_read != 1) { - int err = ferror(stripped_file); - - if(err) + if(feof(intermediate_representation_file)) { - fprintf(stderr, "Error reading file: %d\n", ferror(stripped_file)); + break; + } + else + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + } + + if(operation == JUMP_IF_0) + { + long bracket_pos = ftell(intermediate_representation_file); + + if(bracket_pos == -1) + { + fprintf(stderr, "Error getting file pointer: %d\n", errno); goto end; } - break; - } - - if(c == '[' || c == ']') - { - brackets_pos[bracket_nb] = ftell(stripped_file); - - if(c == '[') + // Find corresponding closing bracket index + for(size_t bracket_index = 1; bracket_index;) { - // Find corresponding closing bracket index - size_t corresponding_bracket_nb = bracket_nb; + operation_t operation_search; + nb_read = fread(&operation_search, sizeof(operation_search), 1, intermediate_representation_file); - for(size_t bracket_index = 1; bracket_index;) + if(nb_read != 1) { - int d = fgetc(stripped_file); - - if(d == EOF) + if(feof(intermediate_representation_file)) { - int err = ferror(stripped_file); - - if(err) - { - fprintf(stderr, "Error reading file: %d\n", ferror(stripped_file)); - } - else - { - fprintf(stderr, "Reached EOF before finding closing bracket."); - } - - goto end; + fprintf(stderr, "Reached end of file before finding closing bracket.\n"); + } + else + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); } - if(d == '[' || d == ']') - { - corresponding_bracket_nb++; - } - - if(d == '[') - { - bracket_index++; - } - else if(d == ']') - { - bracket_index--; - } + goto end; } - brackets_correspondances[bracket_nb] = corresponding_bracket_nb; - brackets_correspondances[corresponding_bracket_nb] = bracket_nb; + switch(operation_search) + { + case MEM_POINTER_ADD_NB: + case MEM_POINTER_SUB_NB: + case MEM_ADD_NB: + case MEM_SUB_NB: + case JUMP_IF_NOT_0: + if(fseek(intermediate_representation_file, sizeof(size_t), SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + break; - fseek(stripped_file, brackets_pos[bracket_nb], SEEK_SET); + default: + break; + } + + if(operation_search == JUMP_IF_0) + { + bracket_index++; + } + else if(operation_search == JUMP_IF_NOT_0) + { + bracket_index--; + } } - bracket_nb++; + long corresponding_bracket_pos = ftell(intermediate_representation_file); + + if(corresponding_bracket_pos == -1) + { + fprintf(stderr, "Error getting file pointer: %d\n", errno); + goto end; + } + + if(fseek(intermediate_representation_file, -sizeof(size_t), SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + + size_t bracket_pos_size_t = (size_t)bracket_pos + sizeof(size_t); + + if(fwrite(&bracket_pos_size_t, sizeof(bracket_pos_size_t), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + + if(fseek(intermediate_representation_file, bracket_pos, SEEK_SET)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + + size_t corresponding_bracket_pos_size_t = corresponding_bracket_pos; + if(fwrite(&corresponding_bracket_pos_size_t, sizeof(corresponding_bracket_pos_size_t), 1, intermediate_representation_file) != 1) + { + fprintf(stderr, "Error writing file: %d\n", errno); + goto end; + } + } + + switch(operation) + { + case MEM_POINTER_ADD_NB: + case MEM_POINTER_SUB_NB: + case MEM_ADD_NB: + case MEM_SUB_NB: + case JUMP_IF_NOT_0: + fseek(intermediate_representation_file, sizeof(size_t), SEEK_CUR); + break; + + default: + break; } } - end_time = clock(); - - fprintf(stderr, "Parsing time : %fs\n", (float)(end_time - start_time) / (float)CLOCKS_PER_SEC); - - rewind(stripped_file); + rewind(intermediate_representation_file); // Program memory uint8_t mem[DATA_SIZE_MAX] = {0}; size_t mem_pointer = 0; - size_t bracket_index = 0; - - start_time = clock(); + size_t nb_read; + size_t operand; while(true) { - int c = fgetc(stripped_file); + operation_t operation; + nb_read = fread(&operation, sizeof(operation), 1, intermediate_representation_file); - if(c == EOF) + if(nb_read != 1) { - int err = ferror(stripped_file); - - if(err) + if(feof(intermediate_representation_file)) { - fprintf(stderr, "Error reading file: %d\n", ferror(stripped_file)); + break; + } + else + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); goto end; } - - break; } - if(c == '[' || c == ']') - { - if(c == '[' ? !mem[mem_pointer] : mem[mem_pointer]) - { - bracket_index = brackets_correspondances[bracket_index]; - fseek(stripped_file, brackets_pos[bracket_index], SEEK_SET); - } - - bracket_index++; - } - else if(c == '>') + switch(operation) { + case MEM_POINTER_ADD: mem_pointer++; - } - else if(c == '<') - { + break; + + case MEM_POINTER_ADD_NB: + nb_read = fread(&operand, sizeof(operand), 1, intermediate_representation_file); + if(nb_read != 1) + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + mem_pointer += operand; + break; + + case MEM_POINTER_SUB: mem_pointer--; - } - else if(c == '+') - { + break; + + case MEM_POINTER_SUB_NB: + nb_read = fread(&operand, sizeof(operand), 1, intermediate_representation_file); + if(nb_read != 1) + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + mem_pointer -= operand; + break; + + case MEM_ADD: mem[mem_pointer]++; - } - else if(c == '-') - { + break; + + case MEM_ADD_NB: + nb_read = fread(&operand, sizeof(operand), 1, intermediate_representation_file); + if(nb_read != 1) + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + mem[mem_pointer] += operand; + break; + + case MEM_SUB: mem[mem_pointer]--; - } - else if(c == '.') - { + break; + + case MEM_SUB_NB: + nb_read = fread(&operand, sizeof(operand), 1, intermediate_representation_file); + if(nb_read != 1) + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + mem[mem_pointer] -= operand; + break; + + case JUMP_IF_0: + if(mem[mem_pointer] == 0) + { + nb_read = fread(&operand, sizeof(operand), 1, intermediate_representation_file); + if(nb_read != 1) + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + + if(fseek(intermediate_representation_file, operand, SEEK_SET)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + } + else + { + if(fseek(intermediate_representation_file, sizeof(size_t), SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + } + break; + + case JUMP_IF_NOT_0: + if(mem[mem_pointer]) + { + nb_read = fread(&operand, sizeof(operand), 1, intermediate_representation_file); + if(nb_read != 1) + { + fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file)); + goto end; + } + + if(fseek(intermediate_representation_file, operand, SEEK_SET)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + } + else + { + if(fseek(intermediate_representation_file, sizeof(size_t), SEEK_CUR)) + { + fprintf(stderr, "Error seeking file: %d\n", errno); + goto end; + } + } + break; + + case PRINT_CHAR: putchar(mem[mem_pointer]); - } - else if(c == ',') - { + break; + + case GET_CHAR: mem[mem_pointer] = getchar(); + break; + + default: + fprintf(stderr, "Invalid operation : %02d\n", operation); + goto end; } } - end_time = clock(); - - fprintf(stderr, "\nExecution time : %fs\n", (float)(end_time - start_time) / (float)CLOCKS_PER_SEC); - status = EXIT_SUCCESS; end: - if(stripped_file != NULL) + if(intermediate_representation_file != NULL) { - if(fclose(stripped_file)) + if(fclose(intermediate_representation_file)) { fprintf(stderr, "Error closing tmp file: %d\n", errno); }