[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_compound, ///< compound initializer
ex_memset, ///< memset needs three params...
ex_count, ///< number of valid expression types
} expr_type;
/** Binary and unary expressions.
@ -570,7 +572,7 @@ short expr_short (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.
\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
_print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
{
static print_f print_funcs[] = {
print_error,
print_state,
print_bool,
print_label,
print_labelref,
print_block,
print_subexpr,
print_uexpr,
print_def,
print_symbol,
print_temp,
print_vector,
print_nil,
print_value,
print_compound,
print_memset,
static print_f print_funcs[ex_count] = {
[ex_error] = print_error,
[ex_state] = print_state,
[ex_bool] = print_bool,
[ex_label] = print_label,
[ex_labelref] = print_labelref,
[ex_block] = print_block,
[ex_expr] = print_subexpr,
[ex_uexpr] = print_uexpr,
[ex_def] = print_def,
[ex_symbol] = print_symbol,
[ex_temp] = print_temp,
[ex_vector] = print_vector,
[ex_nil] = print_nil,
[ex_value] = print_value,
[ex_compound] = print_compound,
[ex_memset] = print_memset,
};
int indent = level * 2 + 2;
@ -573,12 +573,12 @@ _print_expr (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
return;
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",
indent, "", e, e->line);
return;
}
print_funcs [e->type] (dstr, e, level, id, next);
print_funcs[e->type] (dstr, e, level, id, next);
}

View file

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

View file

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

View file

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