Moved intermediate representation into functions and files and load program into RAM. Benchmarks shows an increase of aproximately 256 times in execution speed !
This commit is contained in:
parent
9bfa557615
commit
4cbc8b8262
|
|
@ -1,5 +1,6 @@
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.c
|
main.c \
|
||||||
|
ir.c
|
||||||
|
|
||||||
INCLUDES +=
|
INCLUDES +=
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,283 @@
|
||||||
|
#include "ir.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
operation_t char_to_operation(int c)
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case '>':
|
||||||
|
return MEM_POINTER_ADD;
|
||||||
|
case '<':
|
||||||
|
return MEM_POINTER_SUB;
|
||||||
|
case '+':
|
||||||
|
return MEM_ADD;
|
||||||
|
case '-':
|
||||||
|
return MEM_SUB;
|
||||||
|
case '[':
|
||||||
|
return JUMP_IF_0;
|
||||||
|
case ']':
|
||||||
|
return JUMP_IF_NOT_0;
|
||||||
|
case '.':
|
||||||
|
return PRINT_CHAR;
|
||||||
|
case ',':
|
||||||
|
return GET_CHAR;
|
||||||
|
default:
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_operation_into_ir_file(FILE *ir_file, operation_t operation, operation_t *last_operation)
|
||||||
|
{
|
||||||
|
if(operation == NONE)
|
||||||
|
{
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(ir_file, -1, SEEK_CUR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fwrite(&operation, sizeof(operation_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
operand_t nb = 2;
|
||||||
|
|
||||||
|
if(fwrite(&nb, sizeof(operand_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(operation + 1 == *last_operation)
|
||||||
|
{
|
||||||
|
operation++;
|
||||||
|
|
||||||
|
operand_t nb;
|
||||||
|
|
||||||
|
if(fseek(ir_file, -sizeof(operand_t), SEEK_CUR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fread(&nb, sizeof(operand_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error reading file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nb++;
|
||||||
|
|
||||||
|
if(fseek(ir_file, -sizeof(operand_t), SEEK_CUR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fwrite(&nb, sizeof(operand_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fwrite(&operation, sizeof(operation_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JUMP_IF_0:
|
||||||
|
case JUMP_IF_NOT_0:
|
||||||
|
if(fwrite(&operation, sizeof(operation), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
operand_t jump_pos = 0;
|
||||||
|
|
||||||
|
if(fwrite(&jump_pos, sizeof(operand_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PRINT_CHAR:
|
||||||
|
case GET_CHAR:
|
||||||
|
if(fwrite(&operation, sizeof(operation), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: invalid operation nb.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*last_operation = operation;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculate_jump_operands(FILE *ir_file)
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
operation_t operation;
|
||||||
|
|
||||||
|
if(fread(&operation, sizeof(operation_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
if(feof(ir_file))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error reading file: %d\n", ferror(ir_file));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(operation == JUMP_IF_0)
|
||||||
|
{
|
||||||
|
long bracket_pos = ftell(ir_file);
|
||||||
|
|
||||||
|
if(bracket_pos == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error getting file pointer: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find corresponding closing bracket index
|
||||||
|
for(size_t bracket_index = 1; bracket_index;)
|
||||||
|
{
|
||||||
|
operation_t operation_search;
|
||||||
|
|
||||||
|
if(fread(&operation_search, sizeof(operation_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
if(feof(ir_file))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Reached end of file before finding closing bracket.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error reading file: %d\n", ferror(ir_file));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(ir_file, sizeof(operand_t), SEEK_CUR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(operation_search == JUMP_IF_0)
|
||||||
|
{
|
||||||
|
bracket_index++;
|
||||||
|
}
|
||||||
|
else if(operation_search == JUMP_IF_NOT_0)
|
||||||
|
{
|
||||||
|
bracket_index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long corresponding_bracket_pos = ftell(ir_file);
|
||||||
|
|
||||||
|
if(corresponding_bracket_pos == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error getting file pointer: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fseek(ir_file, -sizeof(operand_t), SEEK_CUR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
operand_t bracket_pos_operand = (operand_t)bracket_pos + sizeof(operand_t);
|
||||||
|
|
||||||
|
if(fwrite(&bracket_pos_operand, sizeof(operand_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fseek(ir_file, bracket_pos, SEEK_SET))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
operand_t corresponding_bracket_pos_operand = (operand_t)corresponding_bracket_pos;
|
||||||
|
if(fwrite(&corresponding_bracket_pos_operand, sizeof(operand_t), 1, ir_file) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error writing file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
if(fseek(ir_file, sizeof(operand_t), SEEK_CUR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef _IR_H
|
||||||
|
#define _IR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// The advanced version of operations 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;
|
||||||
|
|
||||||
|
typedef uint32_t operand_t;
|
||||||
|
|
||||||
|
operation_t char_to_operation(int c);
|
||||||
|
|
||||||
|
int process_operation_into_ir_file(FILE *ir_file, operation_t operation, operation_t *last_operation);
|
||||||
|
|
||||||
|
int calculate_jump_operands(FILE *ir_file);
|
||||||
|
|
||||||
|
#endif // _IR_H
|
||||||
410
src/main.c
410
src/main.c
|
|
@ -3,32 +3,12 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include "ir.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define BRACKETS_NB_MAX 1024
|
|
||||||
#define DATA_SIZE_MAX 65536
|
#define DATA_SIZE_MAX 65536
|
||||||
|
#define PROGRAM_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;
|
|
||||||
|
|
||||||
typedef int operand_t;
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
@ -41,7 +21,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *program_file = NULL;
|
FILE *program_file = NULL;
|
||||||
FILE *intermediate_representation_file = NULL;
|
FILE *ir_file = NULL;
|
||||||
|
|
||||||
program_file = fopen(argv[1], "r");
|
program_file = fopen(argv[1], "r");
|
||||||
if(program_file == NULL)
|
if(program_file == NULL)
|
||||||
|
|
@ -50,14 +30,14 @@ int main(int argc, char *argv[])
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
intermediate_representation_file = tmpfile();
|
ir_file = tmpfile();
|
||||||
if(intermediate_representation_file == NULL)
|
if(ir_file == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error creating tmp file: %d\n", errno);
|
fprintf(stderr, "Error creating tmp file: %d\n", errno);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip program file
|
// Convert into intermediate representation
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
int c = fgetc(program_file);
|
int c = fgetc(program_file);
|
||||||
|
|
@ -75,327 +55,84 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
operation_t operation = NONE;
|
|
||||||
static operation_t last_operation = NONE;
|
static operation_t last_operation = NONE;
|
||||||
|
operation_t operation = char_to_operation(c);
|
||||||
|
|
||||||
switch(c)
|
if(process_operation_into_ir_file(ir_file, operation, &last_operation))
|
||||||
{
|
{
|
||||||
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 ',':
|
|
||||||
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;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fwrite(&operation, sizeof(operation_t), 1, intermediate_representation_file) != 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error writing file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
operand_t nb = 2;
|
|
||||||
|
|
||||||
if(fwrite(&nb, sizeof(operand_t), 1, intermediate_representation_file) != 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error writing file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(operation + 1 == last_operation)
|
|
||||||
{
|
|
||||||
operation++;
|
|
||||||
|
|
||||||
operand_t nb;
|
|
||||||
|
|
||||||
if(fseek(intermediate_representation_file, -sizeof(operand_t), SEEK_CUR))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error seeking file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fread(&nb, sizeof(operand_t), 1, intermediate_representation_file) != 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
nb++;
|
|
||||||
|
|
||||||
if(fseek(intermediate_representation_file, -sizeof(operand_t), SEEK_CUR))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error seeking file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fwrite(&nb, sizeof(operand_t), 1, intermediate_representation_file) != 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error writing file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(fwrite(&operation, sizeof(operation_t), 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
operand_t jump_pos = 0;
|
|
||||||
|
|
||||||
if(fwrite(&jump_pos, sizeof(operand_t), 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)
|
||||||
{
|
{
|
||||||
program_file = NULL;
|
program_file = NULL;
|
||||||
|
|
||||||
fprintf(stderr, "Error closing program file: %d\n", errno);
|
fprintf(stderr, "Error closing program file: %d\n", errno);
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
program_file = NULL;
|
program_file = NULL;
|
||||||
|
|
||||||
// Parse brackets
|
if(fseek(ir_file, 0, SEEK_END))
|
||||||
rewind(intermediate_representation_file);
|
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
operation_t operation;
|
fprintf(stderr, "Error seeking file: %d\n", errno);
|
||||||
size_t nb_read = fread(&operation, sizeof(operation_t), 1, intermediate_representation_file);
|
|
||||||
|
|
||||||
if(nb_read != 1)
|
|
||||||
{
|
|
||||||
if(feof(intermediate_representation_file))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(operation == JUMP_IF_0)
|
long program_size = ftell(ir_file);
|
||||||
{
|
if(program_size == -1)
|
||||||
long bracket_pos = ftell(intermediate_representation_file);
|
|
||||||
|
|
||||||
if(bracket_pos == -1)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error getting file pointer: %d\n", errno);
|
fprintf(stderr, "Error getting file pointer: %d\n", errno);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(program_size > PROGRAM_SIZE_MAX)
|
||||||
|
{
|
||||||
|
fputs("Program too big.\n", stderr);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find corresponding closing bracket index
|
rewind(ir_file);
|
||||||
for(size_t bracket_index = 1; bracket_index;)
|
|
||||||
{
|
|
||||||
operation_t operation_search;
|
|
||||||
nb_read = fread(&operation_search, sizeof(operation_t), 1, intermediate_representation_file);
|
|
||||||
|
|
||||||
if(nb_read != 1)
|
if(calculate_jump_operands(ir_file))
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(operation_search)
|
rewind(ir_file);
|
||||||
{
|
|
||||||
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(operand_t), SEEK_CUR))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error seeking file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
uint8_t program[PROGRAM_SIZE_MAX];
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(operation_search == JUMP_IF_0)
|
if(fread(program, sizeof(uint8_t), program_size, ir_file) != program_size)
|
||||||
{
|
{
|
||||||
bracket_index++;
|
fprintf(stderr, "Error reading file: %d\n", errno);
|
||||||
}
|
|
||||||
else if(operation_search == JUMP_IF_NOT_0)
|
|
||||||
{
|
|
||||||
bracket_index--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long corresponding_bracket_pos = ftell(intermediate_representation_file);
|
|
||||||
|
|
||||||
if(corresponding_bracket_pos == -1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error getting file pointer: %d\n", errno);
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fseek(intermediate_representation_file, -sizeof(operand_t), SEEK_CUR))
|
if(fclose(ir_file))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error seeking file: %d\n", errno);
|
ir_file = NULL;
|
||||||
|
fprintf(stderr, "Error closing ir file: %d\n", errno);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
operand_t bracket_pos_operand = (operand_t)bracket_pos + sizeof(operand_t);
|
ir_file = NULL;
|
||||||
|
|
||||||
if(fwrite(&bracket_pos_operand, sizeof(operand_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
operand_t corresponding_bracket_pos_operand = (operand_t)corresponding_bracket_pos;
|
|
||||||
if(fwrite(&corresponding_bracket_pos_operand, sizeof(operand_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(operand_t), SEEK_CUR);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rewind(intermediate_representation_file);
|
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
uint8_t nb_read;
|
|
||||||
operand_t operand;
|
operand_t operand;
|
||||||
|
size_t program_pointer = 0;
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
operation_t operation;
|
operation_t operation = program[program_pointer];
|
||||||
nb_read = fread(&operation, sizeof(operation_t), 1, intermediate_representation_file);
|
program_pointer++;
|
||||||
|
|
||||||
if(nb_read != 1)
|
if(program_pointer > program_size)
|
||||||
{
|
|
||||||
if(feof(intermediate_representation_file))
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(operation)
|
switch(operation)
|
||||||
{
|
{
|
||||||
|
|
@ -404,12 +141,8 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM_POINTER_ADD_NB:
|
case MEM_POINTER_ADD_NB:
|
||||||
nb_read = fread(&operand, sizeof(operand_t), 1, intermediate_representation_file);
|
operand = *(operand_t *)&program[program_pointer];
|
||||||
if(nb_read != 1)
|
program_pointer += sizeof(operand_t);
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
mem_pointer += operand;
|
mem_pointer += operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -418,12 +151,8 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM_POINTER_SUB_NB:
|
case MEM_POINTER_SUB_NB:
|
||||||
nb_read = fread(&operand, sizeof(operand_t), 1, intermediate_representation_file);
|
operand = *(operand_t *)&program[program_pointer];
|
||||||
if(nb_read != 1)
|
program_pointer += sizeof(operand_t);
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
mem_pointer -= operand;
|
mem_pointer -= operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -432,12 +161,8 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM_ADD_NB:
|
case MEM_ADD_NB:
|
||||||
nb_read = fread(&operand, sizeof(operand_t), 1, intermediate_representation_file);
|
operand = *(operand_t *)&program[program_pointer];
|
||||||
if(nb_read != 1)
|
program_pointer += sizeof(operand_t);
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
mem[mem_pointer] += operand;
|
mem[mem_pointer] += operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -446,64 +171,21 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEM_SUB_NB:
|
case MEM_SUB_NB:
|
||||||
nb_read = fread(&operand, sizeof(operand_t), 1, intermediate_representation_file);
|
operand = *(operand_t *)&program[program_pointer];
|
||||||
if(nb_read != 1)
|
program_pointer += sizeof(operand_t);
|
||||||
{
|
|
||||||
fprintf(stderr, "Error reading file: %d\n", ferror(intermediate_representation_file));
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
mem[mem_pointer] -= operand;
|
mem[mem_pointer] -= operand;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JUMP_IF_0:
|
case JUMP_IF_0:
|
||||||
if(mem[mem_pointer] == 0)
|
|
||||||
{
|
|
||||||
nb_read = fread(&operand, sizeof(operand_t), 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(operand_t), SEEK_CUR))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error seeking file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JUMP_IF_NOT_0:
|
case JUMP_IF_NOT_0:
|
||||||
if(mem[mem_pointer])
|
if(operation == JUMP_IF_0 ? mem[mem_pointer] == 0 : mem[mem_pointer] != 0)
|
||||||
{
|
{
|
||||||
nb_read = fread(&operand, sizeof(operand_t), 1, intermediate_representation_file);
|
operand = *(operand_t *)&program[program_pointer];
|
||||||
if(nb_read != 1)
|
program_pointer = operand;
|
||||||
{
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
if(fseek(intermediate_representation_file, sizeof(operand_t), SEEK_CUR))
|
program_pointer += sizeof(operand_t);
|
||||||
{
|
|
||||||
fprintf(stderr, "Error seeking file: %d\n", errno);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -524,9 +206,9 @@ int main(int argc, char *argv[])
|
||||||
status = EXIT_SUCCESS;
|
status = EXIT_SUCCESS;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if(intermediate_representation_file != NULL)
|
if(ir_file != NULL)
|
||||||
{
|
{
|
||||||
if(fclose(intermediate_representation_file))
|
if(fclose(ir_file))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error closing tmp file: %d\n", errno);
|
fprintf(stderr, "Error closing tmp file: %d\n", errno);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue