Compare commits

...

3 Commits

Author SHA1 Message Date
Ulysse Cura 5ce1fddc8d Parsing file to an intermediate representation. 2026-10-11 00:20:51 +02:00
Ulysse Cura 8ce5ac41b1 Added c cpp properties for vscode. 2026-10-11 00:19:58 +02:00
Ulysse Cura 86409fd36d Added timers. 2026-10-09 14:20:44 +02:00
2 changed files with 410 additions and 135 deletions

18
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,18 @@
{
"version": 4,
"configurations": [
{
"name": "gcc",
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "c++17",
"browse": {
"path": [
"${workspaceFolder}/src"
]
}
}
]
}

View File

@ -1,7 +1,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
@ -9,10 +9,27 @@
#define BRACKETS_NB_MAX 1024 #define BRACKETS_NB_MAX 1024
#define DATA_SIZE_MAX 65536 #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[]) int main(int argc, char *argv[])
{ {
clock_t start_time = clock();
int status = EXIT_FAILURE; int status = EXIT_FAILURE;
if(argc != 2) if(argc != 2)
@ -22,7 +39,7 @@ int main(int argc, char *argv[])
} }
FILE *program_file = NULL; FILE *program_file = NULL;
FILE *stripped_file = NULL; FILE *intermediate_representation_file = NULL;
program_file = fopen(argv[1], "r"); program_file = fopen(argv[1], "r");
if(program_file == NULL) if(program_file == NULL)
@ -31,8 +48,8 @@ int main(int argc, char *argv[])
goto end; goto end;
} }
stripped_file = tmpfile(); intermediate_representation_file = tmpfile();
if(stripped_file == NULL) if(intermediate_representation_file == NULL)
{ {
fprintf(stderr, "Error creating tmp file: %d\n", errno); fprintf(stderr, "Error creating tmp file: %d\n", errno);
goto end; goto end;
@ -50,30 +67,165 @@ int main(int argc, char *argv[])
if(err) if(err)
{ {
fprintf(stderr, "Error reading file: %d\n", ferror(program_file)); fprintf(stderr, "Error reading file: %d\n", ferror(program_file));
return EXIT_FAILURE; goto end;
} }
break; break;
} }
operation_t operation = NONE;
static operation_t last_operation = NONE;
switch(c) switch(c)
{ {
case '>': case '>':
operation = MEM_POINTER_ADD;
break;
case '<': case '<':
operation = MEM_POINTER_SUB;
break;
case '+': case '+':
operation = MEM_ADD;
break;
case '-': case '-':
operation = MEM_SUB;
break;
case '[': case '[':
operation = JUMP_IF_0;
break;
case ']': case ']':
operation = JUMP_IF_NOT_0;
break;
case '.': case '.':
operation = PRINT_CHAR;
break;
case ',': case ',':
fputc(c, stripped_file); operation = GET_CHAR;
break;
default: default:
break; break;
} }
if(operation == NONE)
{
continue;
} }
rewind(stripped_file); 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) if(fclose(program_file) == EOF)
{ {
@ -86,186 +238,295 @@ int main(int argc, char *argv[])
program_file = NULL; program_file = NULL;
size_t brackets_pos[BRACKETS_NB_MAX];
size_t brackets_correspondances[BRACKETS_NB_MAX];
// Parse brackets // Parse brackets
size_t bracket_nb = 0; rewind(intermediate_representation_file);
while(true) 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(feof(intermediate_representation_file))
if(err)
{ {
fprintf(stderr, "Error reading file: %d\n", ferror(stripped_file));
goto end;
}
break; break;
} }
if(c == '[' || c == ']')
{
brackets_pos[bracket_nb] = ftell(stripped_file);
if(c == '[')
{
// Find corresponding closing bracket index
size_t corresponding_bracket_nb = bracket_nb;
for(size_t bracket_index = 1; bracket_index;)
{
int d = fgetc(stripped_file);
if(d == EOF)
{
int err = ferror(stripped_file);
if(err)
{
fprintf(stderr, "Error reading file: %d\n", argv[1], ferror(stripped_file));
}
else else
{ {
fprintf(stderr, "Reached EOF before finding closing bracket."); 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;
}
// Find corresponding closing bracket index
for(size_t bracket_index = 1; bracket_index;)
{
operation_t operation_search;
nb_read = fread(&operation_search, sizeof(operation_search), 1, intermediate_representation_file);
if(nb_read != 1)
{
if(feof(intermediate_representation_file))
{
fprintf(stderr, "Reached end of file before finding closing bracket.\n");
}
else
{
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
} }
goto end; goto end;
} }
if(d == '[' || d == ']') switch(operation_search)
{ {
corresponding_bracket_nb++; 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;
default:
break;
} }
if(d == '[') if(operation_search == JUMP_IF_0)
{ {
bracket_index++; bracket_index++;
} }
else if(d == ']') else if(operation_search == JUMP_IF_NOT_0)
{ {
bracket_index--; bracket_index--;
} }
} }
brackets_correspondances[bracket_nb] = corresponding_bracket_nb; long corresponding_bracket_pos = ftell(intermediate_representation_file);
brackets_correspondances[corresponding_bracket_nb] = bracket_nb;
fseek(stripped_file, brackets_pos[bracket_nb], SEEK_SET); if(corresponding_bracket_pos == -1)
{
fprintf(stderr, "Error getting file pointer: %d\n", errno);
goto end;
} }
bracket_nb++; 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;
} }
} }
rewind(stripped_file); 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;
}
}
rewind(intermediate_representation_file);
// Program memory // Program memory
uint8_t mem[DATA_SIZE_MAX] = {0}; uint8_t mem[DATA_SIZE_MAX] = {0};
size_t mem_pointer = 0; size_t mem_pointer = 0;
size_t bracket_index = 0; size_t nb_read;
size_t operand;
while(true) 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(feof(intermediate_representation_file))
{
break;
}
else
{
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
goto end;
}
}
if(err) switch(operation)
{ {
fprintf(stderr, "Error reading file: %d\n", ferror(stripped_file)); case MEM_POINTER_ADD:
mem_pointer++;
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--;
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]++;
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]--;
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; 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; 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(c == '[' || c == ']') if(fseek(intermediate_representation_file, operand, SEEK_SET))
{ {
if(c == '[' ? !mem[mem_pointer] : mem[mem_pointer]) fprintf(stderr, "Error seeking file: %d\n", errno);
{ goto end;
bracket_index = brackets_correspondances[bracket_index];
fseek(stripped_file, brackets_pos[bracket_index], SEEK_SET);
} }
} }
else if(c == '>') else
{ {
mem_pointer++; if(fseek(intermediate_representation_file, sizeof(size_t), SEEK_CUR))
{
fprintf(stderr, "Error seeking file: %d\n", errno);
goto end;
} }
else if(c == '<')
{
mem_pointer--;
} }
else if(c == '+') break;
{
mem[mem_pointer]++; case PRINT_CHAR:
}
else if(c == '-')
{
mem[mem_pointer]--;
}
else if(c == '.')
{
putchar(mem[mem_pointer]); putchar(mem[mem_pointer]);
fflush(stdout); break;
}
else if(c == ',')
{
/*
static int next_input = -1;
int input;
if(next_input != -1) case GET_CHAR:
{
input = next_input;
next_input = -1;
}
else
{
input = getchar();
}
next_input = getchar();
if(input != '\n')
{
mem[mem_pointer] = input;
}
else
{
if(next_input == '\n')
{
mem[mem_pointer] = '\n';
}
next_input = -1;
}
*/
mem[mem_pointer] = getchar(); mem[mem_pointer] = getchar();
} break;
if(c == '[' || c == ']') default:
{ fprintf(stderr, "Invalid operation : %02d\n", operation);
bracket_index++; goto end;
} }
} }
status = EXIT_SUCCESS; status = EXIT_SUCCESS;
end: end:
if(stripped_file != NULL) if(intermediate_representation_file != NULL)
{ {
if(fclose(stripped_file)) if(fclose(intermediate_representation_file))
{ {
fprintf(stderr, "Failed to close tmp file: %d\n", errno); fprintf(stderr, "Error closing tmp file: %d\n", errno);
} }
} }
@ -273,13 +534,9 @@ end:
{ {
if(fclose(program_file)) if(fclose(program_file))
{ {
fprintf(stderr, "Failed to close tmp file: %d\n", errno); fprintf(stderr, "Error closing tmp file: %d\n", errno);
} }
} }
clock_t end_time = clock();
fprintf(stderr, "\nExecution time : %fs\n", (float)(end_time - start_time) / (float)CLOCKS_PER_SEC);
return status; return status;
} }