This commit is contained in:
anon
2024-07-06 23:53:41 +02:00
parent bfd7a1ab04
commit 4dcc219a3f
9 changed files with 134 additions and 46 deletions

View File

@ -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:

View File

@ -6,3 +6,4 @@
./eaxhla debug/double_declare.eax
./eaxhla debug/empty.eax
./eaxhla debug/double_program.eax
./eaxhla debug/overflows.eax

6
debug/overflows.eax Normal file
View File

@ -0,0 +1,6 @@
program main
u8 a = 10
u8 b = 10000
u8 c = -200
begin
end program

View File

@ -1,3 +1,2 @@
program a
begin
[
u8 var = [

View File

@ -1,4 +1,5 @@
unix
program main
begin
exit 1
end rpogram

View File

@ -10,6 +10,8 @@
#include <stdio.h>
#include <stdarg.h>
#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);

View File

@ -3,8 +3,7 @@
#include <tommyds/tommyhashtbl.h>
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);

View File

@ -1,7 +1,6 @@
%{
#include <stdlib.h>
#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 --- */
<IN_END>{
program { BEGIN INITIAL; free(scope); scope = NULL; return END_PROGRAM; }
procedure { BEGIN INITIAL; free(scope); scope = NULL; return END_PROCEDURE; }

View File

@ -63,7 +63,8 @@
%token TIN
%token S8 S16 S32 S64
%token U8 U16 U32 U64
%type<varval> type
%type<intval> type
%type<varval> declaration
// Registers
%type<intval> 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
;
%%