diff --git a/assemble_aux.c b/assemble_aux.c index 5b6395e..7069d07 100644 --- a/assemble_aux.c +++ b/assemble_aux.c @@ -201,57 +201,52 @@ unsigned get_register( void implicit_gbl( EX_TREE *value) { - if (pass) + if (pass || !value) return; /* Only do this in first pass */ - switch (value->type) { - case EX_UNDEFINED_SYM: - { - if (!(value->data.symbol->flags & SYMBOLFLAG_LOCAL)) { - /* Unless it's a local symbol, */ - if (enabl_gbl) { - /* either make the undefined symbol into an - implicit global */ - add_sym(value->data.symbol->label, 0, SYMBOLFLAG_GLOBAL, - &absolute_section, &implicit_st); - } else { - /* or add it to the undefined symbol table, - purely for listing purposes. - It also works to add it to symbol_st, - all code is carefully made for that. */ + switch (num_subtrees(value)) { + case 0: + switch (value->type) { + case EX_UNDEFINED_SYM: + { + if (!(value->data.symbol->flags & SYMBOLFLAG_LOCAL)) { + /* Unless it's a local symbol, */ + if (enabl_gbl) { + /* either make the undefined symbol into an + implicit global */ + add_sym(value->data.symbol->label, 0, SYMBOLFLAG_GLOBAL, + &absolute_section, &implicit_st); + } else { + /* or add it to the undefined symbol table, + purely for listing purposes. + It also works to add it to symbol_st, + all code is carefully made for that. */ #define ADD_UNDEFINED_SYMBOLS_TO_MAIN_SYMBOL_TABLE 0 #if ADD_UNDEFINED_SYMBOLS_TO_MAIN_SYMBOL_TABLE - add_sym(value->data.symbol->label, 0, SYMBOLFLAG_UNDEFINED, - &absolute_section, &symbol_st); + add_sym(value->data.symbol->label, 0, SYMBOLFLAG_UNDEFINED, + &absolute_section, &symbol_st); #else - add_sym(value->data.symbol->label, 0, SYMBOLFLAG_UNDEFINED, - &absolute_section, &undefined_st); + add_sym(value->data.symbol->label, 0, SYMBOLFLAG_UNDEFINED, + &absolute_section, &undefined_st); #endif + } } } + break; + case EX_LIT: + case EX_SYM: + case EX_TEMP_SYM: // Impossible on this pass + return; + default: + break; } break; - case EX_LIT: - case EX_SYM: - case EX_TEMP_SYM: // Impossible on this pass - return; - case EX_ADD: - case EX_SUB: - case EX_MUL: - case EX_DIV: - case EX_AND: - case EX_OR: - case EX_LSH: + case 2: implicit_gbl(value->data.child.right); /* FALLS THROUGH */ - case EX_COM: - case EX_NEG: + case 1: implicit_gbl(value->data.child.left); break; - case EX_ERR: - if (value->data.child.left) - implicit_gbl(value->data.child.left); - break; } } diff --git a/extree.c b/extree.c index 4003a77..d11c84e 100644 --- a/extree.c +++ b/extree.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "extree.h" /* my own definitions */ @@ -130,31 +131,23 @@ void print_tree( fputc('\n', printfile); } -/* free_tree frees an expression tree. */ +/* num_subtrees tells you how many subtrees this EX_TREE has. */ -void free_tree( +int num_subtrees( EX_TREE *tp) { switch (tp->type) { case EX_UNDEFINED_SYM: case EX_TEMP_SYM: - free(tp->data.symbol->label); - free(tp->data.symbol); - break; - - case EX_LIT: case EX_SYM: + case EX_LIT: + return 0; break; case EX_COM: case EX_NEG: - free_tree(tp->data.child.left); - break; - case EX_ERR: - if (tp->data.child.left) - free_tree(tp->data.child.left); - break; + return 1; case EX_ADD: case EX_SUB: @@ -163,10 +156,46 @@ void free_tree( case EX_AND: case EX_OR: case EX_LSH: - free_tree(tp->data.child.left); - free_tree(tp->data.child.right); - break; + return 2; } + + return 0; +} + +/* free_tree frees an expression tree. */ + +void free_tree( + EX_TREE *tp) +{ + if (!tp) + return; + + switch (num_subtrees(tp)) { + case 0: + switch (tp->type) { + case EX_UNDEFINED_SYM: + case EX_TEMP_SYM: + free(tp->data.symbol->label); + free(tp->data.symbol); + break; + + case EX_SYM: + case EX_LIT: + break; + + default: + assert(0); + break; + } + break; + case 2: + free_tree(tp->data.child.right); + /* FALLTHROUGH */ + case 1: + free_tree(tp->data.child.left); + break; + } + free(tp); } @@ -228,37 +257,34 @@ EX_TREE *dup_tree( res = new_ex_tree(tp->type); res->cp = tp->cp; - switch (tp->type) { - case EX_UNDEFINED_SYM: - case EX_TEMP_SYM: - res->data.symbol = dup_symbol(tp->data.symbol); - break; + switch (num_subtrees(tp)) { + case 0: + switch (tp->type) { + case EX_UNDEFINED_SYM: + case EX_TEMP_SYM: + res->data.symbol = dup_symbol(tp->data.symbol); + break; - /* The symbol reference in EX_SYM is not freed in free_tree() */ - case EX_SYM: - res->data.symbol = tp->data.symbol; - break; + /* The symbol reference in EX_SYM is not freed in free_tree() */ + case EX_SYM: + res->data.symbol = tp->data.symbol; + break; - case EX_LIT: - res->data.lit = tp->data.lit; - break; + case EX_LIT: + res->data.lit = tp->data.lit; + break; - case EX_COM: - case EX_NEG: - case EX_ERR: - res->data.child.left = dup_tree(tp->data.child.left); - break; - - case EX_ADD: - case EX_SUB: - case EX_MUL: - case EX_DIV: - case EX_AND: - case EX_OR: - case EX_LSH: - res->data.child.left = dup_tree(tp->data.child.left); - res->data.child.right = dup_tree(tp->data.child.right); + default: + assert(0); + break; + } break; + case 2: + res->data.child.right = dup_tree(tp->data.child.right); + /* FALLTHROUGH */ + case 1: + res->data.child.left = dup_tree(tp->data.child.left); + break; } return res; diff --git a/extree.h b/extree.h index 26fd9a1..4d73a4c 100644 --- a/extree.h +++ b/extree.h @@ -8,7 +8,8 @@ typedef struct ex_tree { enum ex_type { EX_LIT = 1, /* Expression is a literal value */ EX_SYM = 2, - /* Expression has a symbol reference */ + /* Expression has a symbol reference + * (symbol from symbol table, so not freed) */ EX_UNDEFINED_SYM = 3, /* Expression is undefined sym reference */ EX_TEMP_SYM = 4, @@ -18,22 +19,22 @@ typedef struct ex_tree { /* One's complement */ EX_NEG = 6, /* Negate */ - EX_ERR = 7, + EX_ERR = 8, /* Expression with an error */ - EX_ADD = 8, + EX_ADD = 9, /* Add */ - EX_SUB = 9, + EX_SUB = 10, /* Subtract */ - EX_MUL = 10, + EX_MUL = 11, /* Multiply */ - EX_DIV = 11, + EX_DIV = 12, /* Divide */ - EX_AND = 12, + EX_AND = 13, /* bitwise and */ - EX_OR = 13, + EX_OR = 14, /* bitwise or */ - EX_LSH = 14 + EX_LSH = 15, /* left shift */ } type; @@ -67,7 +68,8 @@ EX_TREE *new_ex_bin( EX_TREE *new_ex_una( int type, EX_TREE *left); - +int num_subtrees( + EX_TREE *tp); EX_TREE *evaluate( EX_TREE *tp, int flags);