mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-14 07:39:37 +00:00
Make some expression tree operations more generic.
This commit is contained in:
parent
6a3642e49a
commit
2aa43f17f7
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
112
extree.c
112
extree.c
@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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;
|
||||
|
||||
22
extree.h
22
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user