Store the source expression in a statement.

This makes problem reporting more informative.
This commit is contained in:
Bill Currie 2011-02-08 18:18:34 +09:00
parent faab931ffc
commit 0d5ab6600d
3 changed files with 19 additions and 17 deletions

View file

@ -58,6 +58,7 @@ typedef struct statement_s {
operand_t *opa;
operand_t *opb;
operand_t *opc;
struct expr_s *expr; ///< source expression for this statement
} statement_t;
typedef struct sblock_s {

View file

@ -79,7 +79,7 @@ get_value_def (ex_value_t *value, etype_t type)
}
static def_t *
get_operand_def (operand_t *op)
get_operand_def (expr_t *expr, operand_t *op)
{
def_t *def;
@ -99,7 +99,7 @@ get_operand_def (operand_t *op)
return get_value_def (&op->o.symbol->s.value, op->type);
case sy_type:
case sy_expr:
internal_error (0, "invalid operand type");
internal_error (expr, "invalid operand type");
}
break;
case op_value:
@ -154,14 +154,14 @@ static void
emit_statement (statement_t *statement)
{
const char *opcode = statement->opcode;
def_t *def_a = get_operand_def (statement->opa);
def_t *def_b = get_operand_def (statement->opb);
def_t *def_c = get_operand_def (statement->opc);
def_t *def_a = get_operand_def (statement->expr, statement->opa);
def_t *def_b = get_operand_def (statement->expr, statement->opb);
def_t *def_c = get_operand_def (statement->expr, statement->opc);
opcode_t *op = opcode_find (opcode, def_a, def_b, def_c);
dstatement_t *s;
if (!op)
internal_error (0, "ice ice baby");
internal_error (statement->expr, "ice ice baby");
s = codespace_newstatement (pr.code);
s->op = op->opcode;
s->a = def_a ? def_a->offset : 0;

View file

@ -156,11 +156,12 @@ sblock_add_statement (sblock_t *sblock, statement_t *statement)
}
static statement_t *
new_statement (const char *opcode)
new_statement (const char *opcode, expr_t *expr)
{
statement_t *statement;
ALLOC (256, statement_t, statements, statement);
statement->opcode = save_string (opcode);
statement->expr = expr;
return statement;
}
@ -259,12 +260,12 @@ statement_branch (sblock_t *sblock, expr_t *e)
const char *opcode;
if (e->type == ex_uexpr && e->e.expr.op == 'g') {
s = new_statement ("<GOTO>");
s = new_statement ("<GOTO>", e);
s->opa = new_operand (op_label);
s->opa->o.label = &e->e.expr.e1->e.label;
} else {
opcode = convert_op (e->e.expr.op);
s = new_statement (opcode);
s = new_statement (opcode, e);
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
s->opb = new_operand (op_label);
s->opb->o.label = &e->e.expr.e2->e.label;
@ -313,7 +314,7 @@ expr_assign (sblock_t *sblock, expr_t *e, operand_t **op)
if (op)
*op = src;
}
s = new_statement (opcode);
s = new_statement (opcode, e);
s->opa = src;
s->opb = dst;
s->opc = ofs;
@ -389,7 +390,7 @@ expr_call (sblock_t *sblock, expr_t *call, operand_t **op)
arg = p;
sblock = statement_subexpr (sblock, a, &arg);
if (arg != p) {
s = new_statement ("=");
s = new_statement ("=", a);
s->opa = arg;
s->opb = p;
sblock_add_statement (sblock, s);
@ -398,7 +399,7 @@ expr_call (sblock_t *sblock, expr_t *call, operand_t **op)
}
}
opcode = va ("<%sCALL%d>", pref, count);
s = new_statement (opcode);
s = new_statement (opcode, call);
sblock = statement_subexpr (sblock, func, &s->opa);
s->opb = arguments[0];
s->opc = arguments[1];
@ -429,7 +430,7 @@ expr_deref (sblock_t *sblock, expr_t *e, operand_t **op)
(*op)->type = low_level_type (type);
(*op)->o.symbol = e->e.expr.e1->e.symbol;
} else if (e->type == ex_expr && e->e.expr.op == '&') {
statement_t *s = new_statement ("=");
statement_t *s = new_statement ("=", e);
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
sblock = statement_subexpr (sblock, e->e.expr.e2, &s->opb);
if (!*op) {
@ -473,7 +474,7 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
opcode = convert_op (e->e.expr.op);
if (!opcode)
internal_error (e, "ice ice baby");
s = new_statement (opcode);
s = new_statement (opcode, e);
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
sblock = statement_subexpr (sblock, e->e.expr.e2, &s->opb);
if (!*op) {
@ -587,7 +588,7 @@ statement_state (sblock_t *sblock, expr_t *e)
{
statement_t *s;
s = new_statement ("<STATE>");
s = new_statement ("<STATE>", e);
sblock = statement_subexpr (sblock, e->e.state.frame, &s->opa);
sblock = statement_subexpr (sblock, e->e.state.think, &s->opb);
sblock = statement_subexpr (sblock, e->e.state.step, &s->opc);
@ -780,7 +781,7 @@ statement_uexpr (sblock_t *sblock, expr_t *e)
opcode = "<RETURN>";
if (!e->e.expr.e1 && !options.traditional)
opcode = "<RETURN_V>";
s = new_statement (opcode);
s = new_statement (opcode, e);
if (e->e.expr.e1)
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
sblock_add_statement (sblock, s);
@ -931,7 +932,7 @@ check_final_block (sblock_t *sblock)
return_operand->type = ev_void;
return_operand->o.symbol = return_symbol;
}
s = new_statement (return_opcode);
s = new_statement (return_opcode, 0);
s->opa = return_operand;
sblock_add_statement (sblock, s);
}