perhaps
This commit is contained in:
parent
7c6cdaae7f
commit
fed0841193
@ -27,7 +27,10 @@ int compile_deinit(void) {
|
||||
|
||||
static
|
||||
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));
|
||||
|
||||
@ -44,7 +47,7 @@ void dump_variable_to_assembler(void * data) {
|
||||
|
||||
static
|
||||
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
|
||||
|
@ -13,10 +13,6 @@ extern int compile(void);
|
||||
|
||||
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
|
||||
* 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
|
||||
|
@ -18,7 +18,7 @@ void debug_printf(const char * const fmt, ...) {
|
||||
|
||||
static
|
||||
void dump_variable(void * data) {
|
||||
variable_t * variable = (variable_t*)data;
|
||||
symbol_t * variable = (symbol_t*)data;
|
||||
if (variable->elements == 1) {
|
||||
printf("{ .name = '%s', .value = '%ld' }\n",
|
||||
variable->name,
|
||||
@ -36,7 +36,7 @@ void dump_variable(void * data) {
|
||||
|
||||
static
|
||||
void debug_dump_variables(void) {
|
||||
tommy_hashtable_foreach(&variable_table, dump_variable);
|
||||
tommy_hashtable_foreach(&symbol_table, dump_variable);
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
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 is_program_found = 0;
|
||||
@ -29,20 +30,20 @@ char * yyfilename = "";
|
||||
|
||||
|
||||
int eaxhla_init(void) {
|
||||
tommy_hashtable_init(&variable_table, 256);
|
||||
tommy_hashtable_init(&symbol_table, 256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void free_variable(void * data) {
|
||||
variable_t * variable = (variable_t*)data;
|
||||
symbol_t * variable = (symbol_t*)data;
|
||||
free(variable->name);
|
||||
free(variable);
|
||||
}
|
||||
|
||||
int eaxhla_deinit(void) {
|
||||
tommy_hashtable_foreach(&variable_table, free_variable);
|
||||
tommy_hashtable_done(&variable_table);
|
||||
tommy_hashtable_foreach(&symbol_table, free_variable);
|
||||
tommy_hashtable_done(&symbol_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -50,31 +51,46 @@ int eaxhla_deinit(void) {
|
||||
|
||||
static
|
||||
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) {
|
||||
static unsigned vid = 0;
|
||||
void add_variable(symbol_t variable) {
|
||||
if (get_variable(variable.name)) {
|
||||
// XXX: this should say the varname, but this function does not know it
|
||||
// in fact this source file should not be reporting errors,
|
||||
// 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;
|
||||
}
|
||||
variable._id = vid++;
|
||||
variable._id = symbol_id++;
|
||||
// XXX this is cursed
|
||||
variable_t * heap_variable = malloc(sizeof(variable));
|
||||
symbol_t * heap_variable = malloc(sizeof(variable));
|
||||
memcpy(heap_variable, &variable, sizeof(variable));
|
||||
// */
|
||||
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,
|
||||
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.
|
||||
* However it would be much more painful to calculate the values inline.
|
||||
*/
|
||||
@ -161,16 +177,36 @@ char * make_scoped_name(const char * const scope, char * name) {
|
||||
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);
|
||||
variable_t * r = tommy_hashtable_search(&variable_table,
|
||||
table_compare_unsigned,
|
||||
&lookup_hash,
|
||||
lookup_hash
|
||||
);
|
||||
void * r = tommy_hashtable_search(&symbol_table,
|
||||
table_compare_unsigned,
|
||||
&lookup_hash,
|
||||
lookup_hash
|
||||
);
|
||||
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, ...) {
|
||||
|
@ -4,21 +4,35 @@
|
||||
|
||||
#define WORD_SIZE_IN_BYTES (64/8)
|
||||
|
||||
typedef enum {
|
||||
VARIABLE,
|
||||
FUNCTION,
|
||||
} symbol_type_t;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
long value;
|
||||
void * array_value;
|
||||
};
|
||||
unsigned long long elements;
|
||||
char * name;
|
||||
int type;
|
||||
unsigned _id;
|
||||
unsigned _hash;
|
||||
tommy_node _node;
|
||||
} variable_t;
|
||||
symbol_type_t symbol_type;
|
||||
union {
|
||||
struct { // VARIABLE
|
||||
int type;
|
||||
unsigned long long elements;
|
||||
union {
|
||||
long value;
|
||||
void * array_value;
|
||||
};
|
||||
};
|
||||
struct { // FUNCTION
|
||||
void * unused;
|
||||
};
|
||||
};
|
||||
char * name;
|
||||
unsigned _id;
|
||||
unsigned _hash;
|
||||
tommy_node _node;
|
||||
} 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;
|
||||
|
||||
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 validate_array_size(int size);
|
||||
|
||||
extern void add_variable(variable_t variable);
|
||||
extern variable_t * get_variable(const char * const name);
|
||||
extern void add_variable(symbol_t variable);
|
||||
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);
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
unsigned long long len;
|
||||
void * data;
|
||||
} blobval;
|
||||
variable_t varval;
|
||||
symbol_t varval;
|
||||
cpuregister_t regval;
|
||||
}
|
||||
|
||||
@ -127,10 +127,17 @@ system_specifier: UNIX { system_type = UNIX; }
|
||||
;
|
||||
|
||||
// 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
|
||||
@ -207,7 +214,7 @@ type: S8 { $$ = S8; }
|
||||
immediate: LITERAL { $$.type = IMM; $$.value = $1; }
|
||||
| IDENTIFIER {
|
||||
char * varname = make_scoped_name(scope, $1);
|
||||
variable_t * variable = get_variable(varname);
|
||||
symbol_t * variable = get_variable(varname);
|
||||
$$.type = REL;
|
||||
$$.value = variable->_id;
|
||||
free(varname);
|
||||
@ -227,7 +234,7 @@ value: artimetric_block
|
||||
| LITERAL
|
||||
| IDENTIFIER {
|
||||
char * varname = make_scoped_name(scope, $1);
|
||||
variable_t * var = get_variable(varname);
|
||||
symbol_t * var = get_variable(varname);
|
||||
$$ = var->value;
|
||||
free(var);
|
||||
}
|
||||
@ -292,9 +299,9 @@ machine_code: %empty
|
||||
;
|
||||
|
||||
call: FASTCALL IDENTIFIER arguments {
|
||||
//append_fastcall_begin(/**/);
|
||||
//append_fastcall_arguments();
|
||||
append_fastcall_end();
|
||||
// XXX
|
||||
symbol_t * function = get_function($2);
|
||||
append_instructions(CALL, REL, function->_id);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
|
Loading…
x
Reference in New Issue
Block a user