bugfix: Fix infinite loop error

This commit is contained in:
XOR 2023-02-25 19:41:58 +01:00
parent e1c947a455
commit 6431d32c36
11 changed files with 151 additions and 82 deletions

15
.clang-format Normal file
View file

@ -0,0 +1,15 @@
#BasedOnStyle: None
AlignTrailingComments: true
BreakBeforeBraces: Allman
ColumnLimit: 0
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
TabWidth: 4
UseTab: Never
AlignArrayOfStructures: Right
SpaceBeforeSquareBrackets: false

4
.gitignore vendored
View file

@ -61,3 +61,7 @@ dkms.conf
#Code editor
.vscode/*
compile_commands.json
.cache/*
#Code analysis
softwipe*.*

View file

@ -4,5 +4,6 @@ Check for Errors in the EIPA Assembly (using the tokens)
#Add command line options
#COMMENTS!
function return errors + handling of those
Consider what happens when the input file contains too many instructions or one token is too long
Consider using a hashtable for the token array to eliminate the if else ladder in get_target_code

View file

@ -11,6 +11,6 @@
const char *argp_program_version =
VER_MAJOR "." VER_MINOR "." VER_PATCH " || " TAG;
const char *argp_program_bug_address = "eipabugs@outlook.com";
const char *argp_program_bug_address = EIPA_BUG_ADRESS;
#endif

View file

@ -9,12 +9,14 @@ Here, common macros are specified
// Maximum Memory Adresses
#define MAX_MEMORY 268435456
// Maximum size (charachters) of one token
#define MAX_TOKEN_SIZE 10
#define VER_MAJOR "0"
#define VER_MINOR "1"
#define VER_PATCH "0"
// alpha, beta or stable
#define TAG "alpha"
@ -37,4 +39,7 @@ Here, common macros are specified
// get the character which the next fgetc() call would return
#define PREFGETC(file) *file->_IO_read_ptr
// const char *argp_program_bug_address = "eipabugs@outlook.com";
#define EIPA_BUG_ADRESS "eipabugs@outlook.com"
#endif

View file

@ -3,11 +3,13 @@
#ifndef _TAGET_CODE_GENERATOR_H_
#define _TAGET_CODE_GENERATOR_H_
// Get a machine code instruction from opcode and and optional adress. Returns 0 on failure
#include <stdio.h>
// Get a machine code instruction from opcode and and optional adress. Returns 0 if the provides adress is too big
__uint32_t get_target_instruction(__uint8_t opcode, __uint8_t use_adress, __uint32_t adress);
// Generate the machine code from tokens into target_code
void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code);
// Generate the machine code from tokens into target_code. Returns 0 on success, errno integer on failure
int gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code);
//Print out the machine code in target_code
void print_target_code(__uint32_t *target_code);

View file

@ -23,6 +23,6 @@ int save_img(char *out_path, __uint32_t *target_code){
// Couldn't save the image
return EIO;
}
return count;
return 0;
}

View file

@ -70,7 +70,7 @@ void lexer(FILE *input_file, char tokens[][MAX_TOKEN_SIZE])
break;
case ';':
// Loop over the comment
while (PREFGETC(input_file) != ASCII_NEWLINE)
while (PREFGETC(input_file) != ASCII_NEWLINE && PREFGETC(input_file) != '\0')
{
current_char = fgetc(input_file);
}

View file

@ -5,18 +5,18 @@ This code is the entry point of the EIPA Assembler and calls the needed function
It also is responsible for Argument Parsing
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <argp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../header/argp_commons.h"
#include "../header/common.h"
#include "../header/image_saver.h"
#include "../header/lexer.h"
#include "../header/target_code_generator.h"
#include "../header/image_saver.h"
#include "../header/argp_commons.h"
//Here, the argumets get stored by the parser, so acess them from here
// Here, the argumets get stored by the parser, so acess them from here
struct cmd_arguments
{
char *input_file;
@ -50,7 +50,7 @@ error_t parser_function(int key, char *arg, struct argp_state *state)
save_arguments->input_file = arg;
break;
case ARGP_KEY_END:
//If we didn't receive 1 Argument yet
// If we didn't receive 1 Argument yet
if (state->arg_num < 1)
{
argp_usage(state);
@ -64,42 +64,35 @@ error_t parser_function(int key, char *arg, struct argp_state *state)
// This array stores structs containing information about the cli options
struct argp_option argp_options[] =
{
{
.name = "output",
.key = 'o',
.arg = "FILE",
.flags = 0,
.doc = "Output file",
.group = 0
},
{
.name = "print_tokens",
.key = 't',
.arg = 0,
.flags = 0,
.doc = "Print the tokens generated by the Lexer to stdout",
.group = 0
},
{
.name = "print_target_code",
.key = 'b',
.arg = 0,
.flags = 0,
.doc = "Print the (Binary) target code generated to stdout",
.group = 0
},
{0}
{.name = "output",
.key = 'o',
.arg = "FILE",
.flags = 0,
.doc = "Output file",
.group = 0},
{.name = "print_tokens",
.key = 't',
.arg = 0,
.flags = 0,
.doc = "Print the tokens generated by the Lexer to stdout",
.group = 0},
{.name = "print_target_code",
.key = 'b',
.arg = 0,
.flags = 0,
.doc = "Print the (Binary) target code generated to stdout",
.group = 0},
{0}
};
// Contains the neccesary stuff for argp
struct argp argument_parser =
{
{
.options = argp_options,
.parser = parser_function,
.args_doc = ARGUMENT_DOC,
.doc = LONG_DOC
};
.doc = LONG_DOC};
int main(int argc, char **argv)
{
@ -112,26 +105,56 @@ int main(int argc, char **argv)
arguments.print_target_code = 0;
arguments.print_tokens = 0;
argp_parse(&argument_parser, argc, argv, 0, 0, &arguments);
if (argp_parse(&argument_parser, argc, argv, 0, 0, &arguments) != 0)
{
printf("Error: Failed to parse CLI Arguments - Error code\n");
return EXIT_FAILURE;
}
FILE *assembly_file;
assembly_file = fopen(arguments.input_file, "r");
FILE *assembly_file = fopen(arguments.input_file, "r");
if (assembly_file == NULL) return 0;
if (assembly_file == NULL)
return EXIT_FAILURE;
// Stores the generated tokens
char(*tokens)[MAX_TOKEN_SIZE] = malloc(sizeof(*tokens) * MAX_MEMORY);
char(*tokens)[MAX_TOKEN_SIZE] = calloc(MAX_MEMORY, sizeof(*tokens));
if(tokens == NULL){
printf("Error: Could not allocate memory for the tokens array\n");
return EXIT_FAILURE;
}
lexer(assembly_file, tokens);
fclose(assembly_file);
// Stores the generated binary target code
__uint32_t *target_code = malloc(MAX_MEMORY * sizeof(target_code));
__uint32_t *target_code = calloc(MAX_MEMORY, sizeof(target_code));
gen_target_code(tokens, target_code);
save_img(arguments.output_file, target_code);
if(target_code == NULL)
{
printf("Error: Could not allocate memory for the target code\n");
return EXIT_FAILURE;
}
int error = gen_target_code(tokens, target_code);
if (error != 0)
{
printf("Error: Could not generate target code - Error %s\n", strerror(error));
return EXIT_FAILURE;
}
if (save_img(arguments.output_file, target_code) != 0)
{
printf("Couldn't save the output file\n");
exit(EXIT_FAILURE);
}
// If the requested, we print the tokens and/or the target code
if (arguments.print_tokens) print_tokens(tokens);
if (arguments.print_target_code) print_target_code(target_code);
if (arguments.print_tokens)
print_tokens(tokens);
if (arguments.print_target_code)
print_target_code(target_code);
return 0;
return EXIT_SUCCESS;
}

View file

@ -6,6 +6,8 @@ This code contains the implementations for all the functions related to the targ
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "../header/common.h"
@ -32,7 +34,7 @@ __uint32_t get_target_instruction(__uint8_t opcode, __uint8_t use_adress, __uint
return instruction;
}
void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
int gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
{
// stores which token we are currently looking at
unsigned int token_index = 0;
@ -56,9 +58,9 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_INP, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "OUT") == 0)
@ -69,9 +71,9 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_OUT, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "LDA") == 0)
@ -82,9 +84,9 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_LDA, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "STA") == 0)
@ -95,18 +97,28 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_STA, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "INC") == 0)
{
target_code[instruction_index] = get_target_instruction(INSTR_INC, 0, 0);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "DEC") == 0)
{
target_code[instruction_index] = get_target_instruction(INSTR_DEC, 0, 0);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "JPP") == 0)
{
@ -116,9 +128,9 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_JPP, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "JPZ") == 0)
@ -129,9 +141,9 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_JPZ, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "JPN") == 0)
@ -142,9 +154,9 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_JPN, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "JPU") == 0)
@ -155,18 +167,24 @@ void gen_target_code(char tokens[][MAX_TOKEN_SIZE], __uint32_t *target_code)
sscanf(tokens[token_index], "%d", &adress);
target_code[instruction_index] = get_target_instruction(INSTR_JPU, 1, adress);
if (!target_code)
{
printf("Adress in %d. Instruction is too large\n", instruction_index);
};
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
else if (strcmp(tokens[token_index], "EOJ") == 0)
{
target_code[instruction_index] = get_target_instruction(INSTR_EOJ, 0, 0);
if(target_code[instruction_index] == 0){
printf("Error: Received andress bigger than %d\nThis error shoudn't occur! Please report at %s\n", MAX_MEMORY, EIPA_BUG_ADRESS);
return EOVERFLOW;
}
}
token_index++;
}
return EXIT_SUCCESS;
}
void print_target_code(__uint32_t *target_code)

View file

@ -0,0 +1 @@
INP 268435457; This adress is too big