[qfcc] Use indexed initializers for expr functions

This will make adding new expression types easier (though the current
reason for doing so has been abandoned for now).
This commit is contained in:
Bill Currie 2021-06-27 14:53:08 +09:00
parent 365e298908
commit 38a6ccdc85
5 changed files with 62 additions and 56 deletions

View file

@ -58,6 +58,8 @@ typedef enum {
ex_value, ///< constant value (::ex_value_t) ex_value, ///< constant value (::ex_value_t)
ex_compound, ///< compound initializer ex_compound, ///< compound initializer
ex_memset, ///< memset needs three params... ex_memset, ///< memset needs three params...
ex_count, ///< number of valid expression types
} expr_type; } expr_type;
/** Binary and unary expressions. /** Binary and unary expressions.
@ -570,7 +572,7 @@ short expr_short (expr_t *e) __attribute__((pure));
int expr_integral (expr_t *e) __attribute__((pure)); int expr_integral (expr_t *e) __attribute__((pure));
/** Check of the expression refers to a constant value. /** Check if the expression refers to a constant value.
\param e The expression to check. \param e The expression to check.
\return True if the expression is constant. \return True if the expression is constant.

View file

@ -545,23 +545,23 @@ print_memset (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
static void static void
_print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next) _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
{ {
static print_f print_funcs[] = { static print_f print_funcs[ex_count] = {
print_error, [ex_error] = print_error,
print_state, [ex_state] = print_state,
print_bool, [ex_bool] = print_bool,
print_label, [ex_label] = print_label,
print_labelref, [ex_labelref] = print_labelref,
print_block, [ex_block] = print_block,
print_subexpr, [ex_expr] = print_subexpr,
print_uexpr, [ex_uexpr] = print_uexpr,
print_def, [ex_def] = print_def,
print_symbol, [ex_symbol] = print_symbol,
print_temp, [ex_temp] = print_temp,
print_vector, [ex_vector] = print_vector,
print_nil, [ex_nil] = print_nil,
print_value, [ex_value] = print_value,
print_compound, [ex_compound] = print_compound,
print_memset, [ex_memset] = print_memset,
}; };
int indent = level * 2 + 2; int indent = level * 2 + 2;
@ -573,7 +573,7 @@ _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
return; return;
e->printid = id; e->printid = id;
if ((int) e->type < 0 || e->type > ex_memset) { if ((int) e->type < 0 || e->type > ex_memset || !print_funcs[e->type]) {
dasprintf (dstr, "%*se_%p [label=\"(bad expr type)\\n%d\"];\n", dasprintf (dstr, "%*se_%p [label=\"(bad expr type)\\n%d\"];\n",
indent, "", e, e->line); indent, "", e, e->line);
return; return;

View file

@ -256,6 +256,8 @@ get_type (expr_t *e)
break; break;
case ex_vector: case ex_vector:
return e->e.vector.type; return e->e.vector.type;
case ex_count:
internal_error (e, "invalid expression");
} }
return (type_t *) unalias_type (type);//FIXME cast return (type_t *) unalias_type (type);//FIXME cast
} }
@ -435,6 +437,7 @@ copy_expr (expr_t *e)
return n; return n;
case ex_vector: case ex_vector:
n = new_expr (); n = new_expr ();
*n = *e;
n->e.vector.type = e->e.vector.type; n->e.vector.type = e->e.vector.type;
n->e.vector.list = copy_expr (e->e.vector.list); n->e.vector.list = copy_expr (e->e.vector.list);
t = e->e.vector.list; t = e->e.vector.list;
@ -459,6 +462,8 @@ copy_expr (expr_t *e)
n->e.memset.val = copy_expr (e->e.memset.val); n->e.memset.val = copy_expr (e->e.memset.val);
n->e.memset.count = copy_expr (e->e.memset.count); n->e.memset.count = copy_expr (e->e.memset.count);
return n; return n;
case ex_count:
break;
} }
internal_error (e, "invalid expression"); internal_error (e, "invalid expression");
} }
@ -1683,6 +1688,8 @@ unary_expr (int op, expr_t *e)
} }
case ex_nil: case ex_nil:
return error (e, "invalid type for unary -"); return error (e, "invalid type for unary -");
case ex_count:
internal_error (e, "invalid expression");
} }
break; break;
case '!': case '!':
@ -1749,6 +1756,8 @@ unary_expr (int op, expr_t *e)
} }
case ex_nil: case ex_nil:
return error (e, "invalid type for unary !"); return error (e, "invalid type for unary !");
case ex_count:
internal_error (e, "invalid expression");
} }
break; break;
case '~': case '~':
@ -1824,6 +1833,8 @@ bitnot_expr:
} }
case ex_nil: case ex_nil:
return error (e, "invalid type for unary ~"); return error (e, "invalid type for unary ~");
case ex_count:
internal_error (e, "invalid expression");
} }
break; break;
case '.': case '.':

View file

@ -136,6 +136,8 @@ is_lvalue (const expr_t *expr)
case ex_value: case ex_value:
case ex_error: case ex_error:
break; break;
case ex_count:
internal_error (expr, "invalid expression");
} }
return 0; return 0;
} }

View file

@ -1449,30 +1449,23 @@ expr_value (sblock_t *sblock, expr_t *e, operand_t **op)
static sblock_t * static sblock_t *
statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op) statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op)
{ {
static expr_f sfuncs[] = { static expr_f sfuncs[ex_count] = {
0, // ex_error [ex_block] = expr_block,
0, // ex_state [ex_expr] = expr_expr,
0, // ex_bool [ex_uexpr] = expr_uexpr,
0, // ex_label [ex_def] = expr_def,
0, // ex_labelref [ex_symbol] = expr_symbol,
expr_block, // ex_block [ex_temp] = expr_temp,
expr_expr, [ex_vector] = expr_vector_e,
expr_uexpr, [ex_nil] = expr_nil,
expr_def, [ex_value] = expr_value,
expr_symbol,
expr_temp,
expr_vector_e, // ex_vector
expr_nil,
expr_value,
0, // ex_compound
0, // ex_memset
}; };
if (!e) { if (!e) {
*op = 0; *op = 0;
return sblock; return sblock;
} }
if (e->type > ex_memset) if (e->type >= ex_count)
internal_error (e, "bad sub-expression type"); internal_error (e, "bad sub-expression type");
if (!sfuncs[e->type]) if (!sfuncs[e->type])
internal_error (e, "unexpected sub-expression type: %s", internal_error (e, "unexpected sub-expression type: %s",
@ -1767,27 +1760,25 @@ statement_nonexec (sblock_t *sblock, expr_t *e)
static sblock_t * static sblock_t *
statement_slist (sblock_t *sblock, expr_t *e) statement_slist (sblock_t *sblock, expr_t *e)
{ {
static statement_f sfuncs[] = { static statement_f sfuncs[ex_count] = {
statement_ignore, // ex_error [ex_error] = statement_ignore,
statement_state, [ex_state] = statement_state,
statement_bool, [ex_bool] = statement_bool,
statement_label, [ex_label] = statement_label,
0, // ex_labelref [ex_block] = statement_block,
statement_block, [ex_expr] = statement_expr,
statement_expr, [ex_uexpr] = statement_uexpr,
statement_uexpr, [ex_def] = statement_nonexec,
statement_nonexec, // ex_def [ex_symbol] = statement_nonexec,
statement_nonexec, // ex_symbol [ex_temp] = statement_nonexec,
statement_nonexec, // ex_temp [ex_vector] = statement_nonexec,
statement_nonexec, // ex_vector [ex_nil] = statement_nonexec,
statement_nonexec, // ex_nil [ex_value] = statement_nonexec,
statement_nonexec, // ex_value [ex_memset] = statement_memset,
0, // ex_compound
statement_memset,
}; };
for (/**/; e; e = e->next) { for (/**/; e; e = e->next) {
if (e->type > ex_memset) if (e->type >= ex_count || !sfuncs[e->type])
internal_error (e, "bad expression type"); internal_error (e, "bad expression type");
sblock = sfuncs[e->type] (sblock, e); sblock = sfuncs[e->type] (sblock, e);
} }