bugfix: Fix infinite loop error
This commit is contained in:
parent
e1c947a455
commit
6431d32c36
11 changed files with 151 additions and 82 deletions
15
.clang-format
Normal file
15
.clang-format
Normal 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
4
.gitignore
vendored
|
|
@ -61,3 +61,7 @@ dkms.conf
|
|||
#Code editor
|
||||
.vscode/*
|
||||
compile_commands.json
|
||||
.cache/*
|
||||
|
||||
#Code analysis
|
||||
softwipe*.*
|
||||
3
TODO.txt
3
TODO.txt
|
|
@ -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
|
||||
Consider using a hashtable for the token array to eliminate the if else ladder in get_target_code
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@
|
|||
#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);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
119
src/main.c
119
src/main.c
|
|
@ -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);
|
||||
|
|
@ -63,43 +63,36 @@ 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[] =
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
1
test/test_addr_to_big.eipa
Normal file
1
test/test_addr_to_big.eipa
Normal file
|
|
@ -0,0 +1 @@
|
|||
INP 268435457; This adress is too big
|
||||
Loading…
Add table
Add a link
Reference in a new issue