[qfcc] Give select expressions their own type

While get_selector does the job of getting a selector from a selector
reference expression, I have long considered lumping various expression
types under ex_expr to be a mistake. Not only is this a step towards
sorting that out, it will make working on #24 easier.
This commit is contained in:
Bill Currie 2021-12-24 13:22:01 +09:00
parent bdd3870d2f
commit ff1cdb6f89
7 changed files with 49 additions and 4 deletions

View file

@ -53,6 +53,7 @@ typedef enum {
ex_symbol, ///< non-temporary variable (::symbol_t)
ex_temp, ///< temporary variable (::ex_temp_t)
ex_vector, ///< "vector" expression (::ex_vector_t)
ex_selector, ///< selector expression (::ex_selector_t)
ex_nil, ///< umm, nil, null. nuff said (0 of any type)
ex_value, ///< constant value (::ex_value_t)
@ -121,6 +122,11 @@ typedef struct {
struct expr_s *list; ///< Linked list of element expressions.
} ex_vector_t;
typedef struct {
struct expr_s *sel_ref; ///< Reference to selector in selector table
struct selector_s *sel; ///< selector
} ex_selector_t;
/** Pointer constant expression.
Represent a pointer to an absolute address in data space.
@ -237,6 +243,7 @@ typedef struct expr_s {
struct symbol_s *symbol; ///< symbol reference expression
ex_temp_t temp; ///< temporary variable expression
ex_vector_t vector; ///< vector expression list
ex_selector_t selector; ///< selector ref and name
ex_value_t *value; ///< constant value
element_chain_t compound; ///< compound initializer
ex_memset_t memset; ///< memset expr params

View file

@ -47,6 +47,7 @@
#include "qfalloca.h"
#include "tools/qfcc/include/expr.h"
#include "tools/qfcc/include/method.h"
#include "tools/qfcc/include/symtab.h"
#include "tools/qfcc/include/type.h"
#include "tools/qfcc/include/strpool.h"
@ -426,6 +427,15 @@ print_vector (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
e->line);
}
static void
print_selector (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
{
int indent = level * 2 + 2;
dasprintf (dstr, "%*se_%p [label=\"%s\"];\n", indent, "", e,
e->e.selector.sel->name);
}
static void
print_nil (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
{
@ -564,6 +574,7 @@ _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
[ex_symbol] = print_symbol,
[ex_temp] = print_temp,
[ex_vector] = print_vector,
[ex_selector] = print_selector,
[ex_nil] = print_nil,
[ex_value] = print_value,
[ex_compound] = print_compound,

View file

@ -256,6 +256,8 @@ get_type (expr_t *e)
break;
case ex_vector:
return e->e.vector.type;
case ex_selector:
return &type_SEL;
case ex_count:
internal_error (e, "invalid expression");
}
@ -448,6 +450,11 @@ copy_expr (expr_t *e)
t = t->next;
}
return n;
case ex_selector:
n = new_expr ();
*n = *e;
n->e.selector.sel_ref = copy_expr (e->e.selector.sel_ref);
return n;
case ex_compound:
n = new_expr ();
*n = *e;
@ -1641,6 +1648,7 @@ unary_expr (int op, expr_t *e)
case ex_state:
case ex_compound:
case ex_memset:
case ex_selector:
internal_error (e, 0);
case ex_uexpr:
if (e->e.expr.op == '-') {
@ -1732,6 +1740,7 @@ unary_expr (int op, expr_t *e)
case ex_state:
case ex_compound:
case ex_memset:
case ex_selector:
internal_error (e, 0);
case ex_bool:
return new_bool_expr (e->e.bool.false_list,
@ -1802,6 +1811,7 @@ unary_expr (int op, expr_t *e)
case ex_state:
case ex_compound:
case ex_memset:
case ex_selector:
internal_error (e, 0);
case ex_uexpr:
if (e->e.expr.op == '~')

View file

@ -135,6 +135,7 @@ is_lvalue (const expr_t *expr)
case ex_nil:
case ex_value:
case ex_error:
case ex_selector:
break;
case ex_count:
internal_error (expr, "invalid expression");

View file

@ -90,7 +90,7 @@ expr_t *
selector_expr (keywordarg_t *selector)
{
dstring_t *sel_id = dstring_newstr ();
expr_t *sel;
expr_t *sel_ref;
symbol_t *sel_sym;
symbol_t *sel_table;
int index;
@ -111,10 +111,15 @@ selector_expr (keywordarg_t *selector)
symtab_addsymbol (pr.symtab, sel_table);
reloc_def_def (sel_table->s.def, sel_sym->s.def);
}
sel = new_symbol_expr (sel_sym);
sel_ref = new_symbol_expr (sel_sym);
sel_ref = new_binary_expr ('&', sel_ref, new_short_expr (index));
sel_ref->e.expr.type = &type_SEL;
expr_t *sel = new_expr ();
sel->type = ex_selector;
sel->e.selector.sel_ref = sel_ref;
sel->e.selector.sel = get_selector (sel_ref);
dstring_delete (sel_id);
sel = new_binary_expr ('&', sel, new_short_expr (index));
sel->e.expr.type = &type_SEL;
return sel;
}

View file

@ -483,6 +483,9 @@ get_selector (expr_t *sel)
{
selector_t _sel = {0, 0, 0};
if (sel->type == ex_selector) {
return sel->e.selector.sel;
}
if (sel->type != ex_expr && sel->e.expr.op != '&'
&& !is_SEL(sel->e.expr.type)) {
error (sel, "not a selector");

View file

@ -50,6 +50,7 @@
#include "tools/qfcc/include/dot.h"
#include "tools/qfcc/include/expr.h"
#include "tools/qfcc/include/function.h"
#include "tools/qfcc/include/method.h"
#include "tools/qfcc/include/options.h"
#include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/reloc.h"
@ -1450,6 +1451,12 @@ expr_value (sblock_t *sblock, expr_t *e, operand_t **op)
return sblock;
}
static sblock_t *
expr_selector (sblock_t *sblock, expr_t *e, operand_t **op)
{
return statement_subexpr (sblock, e->e.selector.sel_ref, op);
}
static sblock_t *
statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op)
{
@ -1463,6 +1470,7 @@ statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op)
[ex_vector] = expr_vector_e,
[ex_nil] = expr_nil,
[ex_value] = expr_value,
[ex_selector] = expr_selector,
};
if (!e) {
*op = 0;