perhaps
This commit is contained in:
parent
7c6cdaae7f
commit
fed0841193
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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, ...) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user