diff --git a/Makefile b/Makefile index 5097bb3..226efd8 100644 --- a/Makefile +++ b/Makefile @@ -68,9 +68,9 @@ bootstrap: test: ${OUT} #fcpp -C -LL debug/xop.eax > debug/xop.eax.pp #${WRAP} ./${OUT} debug/xop.eax - ./${OUT} debug/xop.eax + #./${OUT} debug/xop.eax # NOTE as of now broken, but only because of undefined instructions #${WRAP} ./${OUT} debug/artimetrics.eax - @echo " --- ERROR TESTING BEGINS BELOW ---" + @echo -e "\033[31;1m --- ERROR TESTING BEGINS BELOW ---\033[0m" debug/error_test.sh clean: diff --git a/debug/error_test.sh b/debug/error_test.sh index 831ce83..22c80b2 100755 --- a/debug/error_test.sh +++ b/debug/error_test.sh @@ -6,3 +6,4 @@ ./eaxhla debug/double_declare.eax ./eaxhla debug/empty.eax ./eaxhla debug/double_program.eax +./eaxhla debug/overflows.eax diff --git a/debug/overflows.eax b/debug/overflows.eax new file mode 100644 index 0000000..06fbd55 --- /dev/null +++ b/debug/overflows.eax @@ -0,0 +1,6 @@ +program main + u8 a = 10 + u8 b = 10000 + u8 c = -200 +begin +end program diff --git a/debug/unclosed_artimetric.eax b/debug/unclosed_artimetric.eax index 03dd5ce..fc2e15a 100644 --- a/debug/unclosed_artimetric.eax +++ b/debug/unclosed_artimetric.eax @@ -1,3 +1,2 @@ program a -begin -[ + u8 var = [ diff --git a/debug/unclosed_program.eax b/debug/unclosed_program.eax index 62ad896..df35de8 100644 --- a/debug/unclosed_program.eax +++ b/debug/unclosed_program.eax @@ -1,4 +1,5 @@ unix program main +begin exit 1 end rpogram diff --git a/source/eaxhla.c b/source/eaxhla.c index c82dda9..b886b95 100644 --- a/source/eaxhla.c +++ b/source/eaxhla.c @@ -10,6 +10,8 @@ #include #include +#include "eaxhla.tab.h" + tommy_hashtable variable_table; char * scope = NULL; @@ -54,6 +56,45 @@ void add_variable(variable_t variable) { ); } +/* Are these literals ugly? yes. + * However it would be much more painful to calculate the values inline. + */ +int can_fit(int type, long long value) { + unsigned long long max = 0; + long long min = 0; + switch (type) { + case U8: { + max = 255; + } break; + case U16: { + max = 65535; + } break; + case U32: { + max = 4294967295; + } break; + case U64: { + max = 9223372036854775807; + } break; + case S8: { + min = -128; + max = 127; + } break; + case S16: { + min = -256; + max = 255; + } break; + case S32: { + min = -65536; + max = 65535; + } break; + case S64: { + min = -4294967296; + max = 4294967295; + } break; + } + return value > 0 ? (unsigned long long)value < max : value > min; +} + char * make_scoped_name(const char * const scope, char * name) { char * r; const long scl = strlen(scope); diff --git a/source/eaxhla.h b/source/eaxhla.h index 4f5ead1..b4e059e 100644 --- a/source/eaxhla.h +++ b/source/eaxhla.h @@ -3,8 +3,7 @@ #include typedef struct { - short size; - long address; + int size; long value; char * name; unsigned _hash; @@ -17,6 +16,7 @@ extern int eaxhla_init(void); extern int eaxhla_destroy(void); extern char * make_scoped_name(const char * const scope, char * name); +extern int can_fit(int type, long long value); extern void add_variable(variable_t variable); extern variable_t * get_variable(const char * const name); diff --git a/source/eaxhla.l b/source/eaxhla.l index 8c09324..dea5456 100644 --- a/source/eaxhla.l +++ b/source/eaxhla.l @@ -1,7 +1,6 @@ %{ #include #include "eaxhla.tab.h" - #include "table.h" char * string_literal_buffer; int string_litral_buffer_size = 0; @@ -96,10 +95,19 @@ u64{wsnl}+ { return U64; } \+|\-|\*|\/|\%|\^|\: { return yytext[0]; } -xor{wsnl}+ { return TXOR; } -inc{wsnl}+ { return TINC; } fastcall{wsnl}+ { return FASTCALL; } + /* --- Instrunctions begin here --- */ + /* + xor{wsnl}+ { return TXOR; } + inc{wsnl}+ { return TINC; } + */ +add{wsnl}+ { return IADD; } +syscall{wsnl}+ { return ISYSCALL; } +mov{wsnl}+ { return IMOV; } +xor{wsnl}+ { return IXOR; } + /* --- Instrunctions end here --- */ + { program { BEGIN INITIAL; free(scope); scope = NULL; return END_PROGRAM; } procedure { BEGIN INITIAL; free(scope); scope = NULL; return END_PROCEDURE; } diff --git a/source/eaxhla.y b/source/eaxhla.y index 3117de4..5270d45 100644 --- a/source/eaxhla.y +++ b/source/eaxhla.y @@ -63,7 +63,8 @@ %token TIN %token S8 S16 S32 S64 %token U8 U16 U32 U64 -%type type +%type type +%type declaration // Registers %type register @@ -76,6 +77,11 @@ // Instructions %token TADD TOR TADC TBB TXOR TAND TSUB TCMP TSYSCALL TINC +%token INOP // better temp prefix? +%token IADD +%token ISYSCALL +%token IMOV +%token IXOR // Instruction-likes %token FASTCALL @@ -120,18 +126,21 @@ declaration_section: %empty declaration: variable_specifier type IDENTIFIER { - $2.name = make_scoped_name(scope, $3); - add_variable($2); + $$.name = make_scoped_name(scope, $3); + add_variable($$); } - | variable_specifier type IDENTIFIER '=' immediate { - $2.name = make_scoped_name(scope, $3); - $2.value = $5; - add_variable($2); + | variable_specifier type IDENTIFIER '=' LITERAL { + $$.name = make_scoped_name(scope, $3); + if (!can_fit($2, $5)) { + issue_warning("the value \033[1m'%lld'\033[0m will overflow in assignement", $5); + } + $$.value = $5; + add_variable($$); } | variable_specifier type IDENTIFIER '=' STRING_LITERAL { - $2.name = make_scoped_name(scope, $3); - $2.value = $5; - add_variable($2); + $$.name = make_scoped_name(scope, $3); + $$.value = $5; + add_variable($$); } ; @@ -139,14 +148,26 @@ variable_specifier: %empty | TIN ; -type: S8 { $$ = (variable_t){ .size = 8, .address = new_static( 8), .value = 0 }; } - | S16 { $$ = (variable_t){ .size = 16, .address = new_static(16), .value = 0 }; } - | S32 { $$ = (variable_t){ .size = 32, .address = new_static(32), .value = 0 }; } - | S64 { $$ = (variable_t){ .size = 64, .address = new_static(64), .value = 0 }; } - | U8 { $$ = (variable_t){ .size = 8, .address = new_static( 8), .value = 0 }; } - | U16 { $$ = (variable_t){ .size = 16, .address = new_static(16), .value = 0 }; } - | U32 { $$ = (variable_t){ .size = 32, .address = new_static(32), .value = 0 }; } - | U64 { $$ = (variable_t){ .size = 64, .address = new_static(64), .value = 0 }; } +type: S8 { $$ = S8; } + | S16 { $$ = S16; } + | S32 { $$ = S32; } + | S64 { $$ = S64; } + | U8 { $$ = U8; } + | U16 { $$ = U16; } + | U32 { $$ = U32; } + | U64 { $$ = U64; } + ; + +immediate: LITERAL + | IDENTIFIER + ; + +memory: artimetric_block + ; + +value: artimetric_block + | LITERAL + | IDENTIFIER ; code: %empty @@ -158,11 +179,28 @@ code: %empty | machine code | BREAK code | exit code - | TXOR register register code { /* assemble_xor(size_64b, type_register_register, $2, $3); */ } - | TXOR register immediate code { /* assemble_xor(size_64b, type_register_register, $2, $3); */ } - | TXOR IDENTIFIER register code { /* assemble_xor(size_64b, type_register_register, $2, $3); */ free($2); } + | instruction code + ; + +instruction: INOP { ; } + /* + | TXOR register register code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / } + | TXOR register immediate code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / } + | TXOR IDENTIFIER register code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / free($2); } | TINC register code | TINC IDENTIFIER code { free($2); } + */ + | IADD register register + | IADD register immediate + | IADD register memory + | ISYSCALL + | IMOV register register + | IMOV memory register + | IMOV register memory + | IMOV register immediate + | IMOV memory immediate + | IXOR register register + | IXOR register memory ; loop: TLOOP code END_LOOP @@ -182,17 +220,14 @@ logic: logical_operand TAND logical_operand logical_operand: sublogic | register - | immediate + | artimetric_block + | LITERAL | IDENTIFIER ; sublogic: '(' logic ')' ; -memory: immediate - | IDENTIFIER - ; - machine: MACHINE machine_code END_MACHINE ; @@ -209,10 +244,11 @@ calltype: FASTCALL ; arguments: %empty - | IDENTIFIER arguments { free($1); } - | STRING_LITERAL arguments { free($1); } - | register arguments - | immediate arguments + | IDENTIFIER arguments { free($1); } + | STRING_LITERAL arguments { free($1); } + | LITERAL arguments + | register arguments + | artimetric_block arguments ; register: RAX { $$ = R0; } @@ -241,10 +277,6 @@ register: RAX { $$ = R0; } | RGXMM7 { $$ = 0; } ; -immediate: LITERAL - | artimetric_block - ; - artimetric_block: '[' artimetric_expression ']' { $$ = $2; } ; @@ -258,11 +290,11 @@ artimetric_expression: %empty { $$ = 0; } | artimetric_expression '^' artimetric_operand { $$ = pow($1, $3); } ; -artimetric_operand: immediate +artimetric_operand: LITERAL + | STRING_LITERAL | IDENTIFIER { $$ = 0; /*XXX*/ } ; -exit: EXIT immediate - | EXIT IDENTIFIER { free($2); } +exit: EXIT value ; %%