This commit is contained in:
anon 2024-07-16 18:56:55 +02:00
parent 7c6cdaae7f
commit fed0841193
6 changed files with 108 additions and 48 deletions

View File

@ -27,7 +27,10 @@ int compile_deinit(void) {
static static
void dump_variable_to_assembler(void * data) { void dump_variable_to_assembler(void * data) {
variable_t * variable = (variable_t*)data; symbol_t * variable = (symbol_t*)data;
if (variable->symbol_type != VARIABLE) {
return;
}
append_instructions(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type)); append_instructions(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type));
@ -44,7 +47,7 @@ void dump_variable_to_assembler(void * data) {
static static
void dump_variables_to_assembler(void) { void dump_variables_to_assembler(void) {
tommy_hashtable_foreach(&variable_table, dump_variable_to_assembler); tommy_hashtable_foreach(&symbol_table, dump_variable_to_assembler);
} }
static static

View File

@ -13,10 +13,6 @@ extern int compile(void);
extern void append_label (int rel); extern void append_label (int rel);
extern void append_fastcall_begin (int rel);
extern void append_fastcall_end (void);
extern void append_fastcall_arguments (int rel, int wid, int imm);
/* --- Token appending /* --- Token appending
* The core problem is that we want an interface where we can append {instructoin} * The core problem is that we want an interface where we can append {instructoin}
* tokens without modifying the counter as that gets old fast and error prone * tokens without modifying the counter as that gets old fast and error prone

View File

@ -18,7 +18,7 @@ void debug_printf(const char * const fmt, ...) {
static static
void dump_variable(void * data) { void dump_variable(void * data) {
variable_t * variable = (variable_t*)data; symbol_t * variable = (symbol_t*)data;
if (variable->elements == 1) { if (variable->elements == 1) {
printf("{ .name = '%s', .value = '%ld' }\n", printf("{ .name = '%s', .value = '%ld' }\n",
variable->name, variable->name,
@ -36,7 +36,7 @@ void dump_variable(void * data) {
static static
void debug_dump_variables(void) { void debug_dump_variables(void) {
tommy_hashtable_foreach(&variable_table, dump_variable); tommy_hashtable_foreach(&symbol_table, dump_variable);
} }
static static

View File

@ -18,7 +18,8 @@
unsigned long long anon_variable_counter = 0; unsigned long long anon_variable_counter = 0;
tommy_hashtable variable_table; static unsigned symbol_id = 0;
tommy_hashtable symbol_table;
int has_encountered_error = 0; int has_encountered_error = 0;
int is_program_found = 0; int is_program_found = 0;
@ -29,20 +30,20 @@ char * yyfilename = "";
int eaxhla_init(void) { int eaxhla_init(void) {
tommy_hashtable_init(&variable_table, 256); tommy_hashtable_init(&symbol_table, 256);
return 0; return 0;
} }
static static
void free_variable(void * data) { void free_variable(void * data) {
variable_t * variable = (variable_t*)data; symbol_t * variable = (symbol_t*)data;
free(variable->name); free(variable->name);
free(variable); free(variable);
} }
int eaxhla_deinit(void) { int eaxhla_deinit(void) {
tommy_hashtable_foreach(&variable_table, free_variable); tommy_hashtable_foreach(&symbol_table, free_variable);
tommy_hashtable_done(&variable_table); tommy_hashtable_done(&symbol_table);
return 0; return 0;
} }
@ -50,31 +51,46 @@ int eaxhla_deinit(void) {
static static
int table_compare_unsigned(const void * arg, const void * obj) { int table_compare_unsigned(const void * arg, const void * obj) {
return *(const unsigned *) arg != ((const variable_t*)obj)->_hash; return *(const unsigned *) arg != ((const symbol_t*)obj)->_hash;
} }
void add_variable(variable_t variable) { void add_variable(symbol_t variable) {
static unsigned vid = 0;
if (get_variable(variable.name)) { if (get_variable(variable.name)) {
// XXX: this should say the varname, but this function does not know it // XXX: this should say the varname, but this function does not know it
// in fact this source file should not be reporting errors, // in fact this source file should not be reporting errors,
// it should be returning an error and the parser should check. // it should be returning an error and the parser should check.
issue_error("variable declared twice"); issue_error("symbol '%s' declared twice", variable.name);
return; return;
} }
variable._id = vid++; variable._id = symbol_id++;
// XXX this is cursed // XXX this is cursed
variable_t * heap_variable = malloc(sizeof(variable)); symbol_t * heap_variable = malloc(sizeof(variable));
memcpy(heap_variable, &variable, sizeof(variable)); memcpy(heap_variable, &variable, sizeof(variable));
// */ // */
heap_variable->_hash = tommy_strhash_u32(0, heap_variable->name); heap_variable->_hash = tommy_strhash_u32(0, heap_variable->name);
tommy_hashtable_insert(&variable_table, tommy_hashtable_insert(&symbol_table,
&heap_variable->_node, &heap_variable->_node,
heap_variable, heap_variable,
heap_variable->_hash heap_variable->_hash
); );
} }
void add_procedure(symbol_t procedure) {
procedure._id = symbol_id++;
// XXX this is cursed
symbol_t * heap_procedure = malloc(sizeof(procedure));
memcpy(heap_procedure, &procedure, sizeof(procedure));
// */
heap_procedure->_hash = tommy_strhash_u32(0, heap_procedure->name);
tommy_hashtable_insert(&symbol_table,
&heap_procedure->_node,
heap_procedure,
heap_procedure->_hash
);
//
append_instructions(ASMDIRMEM, procedure._id);
}
/* Are these literals ugly? yes. /* Are these literals ugly? yes.
* However it would be much more painful to calculate the values inline. * However it would be much more painful to calculate the values inline.
*/ */
@ -161,9 +177,10 @@ char * make_scoped_name(const char * const scope, char * name) {
return r; return r;
} }
variable_t * get_variable(const char * const name) { static
void * symbol_lookup(const char * const name) {
unsigned lookup_hash = tommy_strhash_u32(0, name); unsigned lookup_hash = tommy_strhash_u32(0, name);
variable_t * r = tommy_hashtable_search(&variable_table, void * r = tommy_hashtable_search(&symbol_table,
table_compare_unsigned, table_compare_unsigned,
&lookup_hash, &lookup_hash,
lookup_hash lookup_hash
@ -171,6 +188,25 @@ variable_t * get_variable(const char * const name) {
return r; return r;
} }
symbol_t * get_variable(const char * const name) {
symbol_t *r = symbol_lookup(name);
if (r
&& r->symbol_type != VARIABLE) {
issue_error("the symbol '%s' is not a variable", name);
return NULL;
}
return r;
}
symbol_t * get_function(const char * const name) {
symbol_t * r = symbol_lookup(name);
if (r
&& r->symbol_type != FUNCTION) {
issue_error("the symbol '%s' is not a function", name);
return NULL;
}
return r;
}
void issue_warning(const char * const format, ...) { void issue_warning(const char * const format, ...) {

View File

@ -4,21 +4,35 @@
#define WORD_SIZE_IN_BYTES (64/8) #define WORD_SIZE_IN_BYTES (64/8)
typedef enum {
VARIABLE,
FUNCTION,
} symbol_type_t;
typedef struct { typedef struct {
symbol_type_t symbol_type;
union {
struct { // VARIABLE
int type;
unsigned long long elements;
union { union {
long value; long value;
void * array_value; void * array_value;
}; };
unsigned long long elements; };
struct { // FUNCTION
void * unused;
};
};
char * name; char * name;
int type;
unsigned _id; unsigned _id;
unsigned _hash; unsigned _hash;
tommy_node _node; tommy_node _node;
} variable_t; } symbol_t;
extern tommy_hashtable variable_table; extern tommy_hashtable symbol_table;
// Used for naming variables constructed from literals
extern unsigned long long anon_variable_counter; extern unsigned long long anon_variable_counter;
typedef struct { typedef struct {
@ -43,8 +57,12 @@ extern char * make_scoped_name(const char * const scope, char * name);
extern int can_fit(int type, long long value); extern int can_fit(int type, long long value);
extern int validate_array_size(int size); extern int validate_array_size(int size);
extern void add_variable(variable_t variable); extern void add_variable(symbol_t variable);
extern variable_t * get_variable(const char * const name); extern symbol_t * get_variable(const char * const name);
//extern void add_function(symbol_t function);
extern symbol_t * get_function(const char * const name);
extern void add_procedure(symbol_t procedure);
extern int type2size(int type); extern int type2size(int type);

View File

@ -29,7 +29,7 @@
unsigned long long len; unsigned long long len;
void * data; void * data;
} blobval; } blobval;
variable_t varval; symbol_t varval;
cpuregister_t regval; cpuregister_t regval;
} }
@ -127,10 +127,17 @@ system_specifier: UNIX { system_type = UNIX; }
; ;
// XXX: end procedure thing // XXX: end procedure thing
function: function_head declaration_section MYBEGIN code END_PROCEDURE { scope = NULL; } function: function_head declaration_section MYBEGIN code END_PROCEDURE {
scope = NULL;
append_instructions(RETN);
}
; ;
function_head: function_specifier PROCEDURE IDENTIFIER { scope = $3; } function_head: function_specifier PROCEDURE IDENTIFIER {
scope = $3;
symbol_t procedure;
add_procedure(procedure);
}
; ;
function_specifier: %empty function_specifier: %empty
@ -207,7 +214,7 @@ type: S8 { $$ = S8; }
immediate: LITERAL { $$.type = IMM; $$.value = $1; } immediate: LITERAL { $$.type = IMM; $$.value = $1; }
| IDENTIFIER { | IDENTIFIER {
char * varname = make_scoped_name(scope, $1); char * varname = make_scoped_name(scope, $1);
variable_t * variable = get_variable(varname); symbol_t * variable = get_variable(varname);
$$.type = REL; $$.type = REL;
$$.value = variable->_id; $$.value = variable->_id;
free(varname); free(varname);
@ -227,7 +234,7 @@ value: artimetric_block
| LITERAL | LITERAL
| IDENTIFIER { | IDENTIFIER {
char * varname = make_scoped_name(scope, $1); char * varname = make_scoped_name(scope, $1);
variable_t * var = get_variable(varname); symbol_t * var = get_variable(varname);
$$ = var->value; $$ = var->value;
free(var); free(var);
} }
@ -292,9 +299,9 @@ machine_code: %empty
; ;
call: FASTCALL IDENTIFIER arguments { call: FASTCALL IDENTIFIER arguments {
//append_fastcall_begin(/**/); // XXX
//append_fastcall_arguments(); symbol_t * function = get_function($2);
append_fastcall_end(); append_instructions(CALL, REL, function->_id);
free($2); free($2);
} }
; ;