mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 10:41:43 +00:00
factor check for assignment-to-constant into a function; improve its error output; closes #122
This commit is contained in:
parent
87b9fca732
commit
79219ae201
1 changed files with 22 additions and 23 deletions
45
parser.c
45
parser.c
|
@ -282,6 +282,21 @@ static bool rotate_entfield_array_index_nodes(ast_expression **out)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool check_write_to(lex_ctx_t ctx, ast_expression *expr)
|
||||
{
|
||||
if (ast_istype(expr, ast_value)) {
|
||||
ast_value *val = (ast_value*)expr;
|
||||
if (val->cvq == CV_CONST) {
|
||||
if (val->name[0] == '#')
|
||||
compile_error(ctx, "invalid assignment to a literal constant");
|
||||
else
|
||||
compile_error(ctx, "assignment to constant `%s`", val->name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
||||
{
|
||||
const oper_info *op;
|
||||
|
@ -289,7 +304,6 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
ast_expression *out = NULL;
|
||||
ast_expression *exprs[3];
|
||||
ast_block *blocks[3];
|
||||
ast_value *asvalue[3];
|
||||
ast_binstore *asbinstore;
|
||||
size_t i, assignop, addop, subop;
|
||||
qcint_t generated_op = 0;
|
||||
|
@ -328,7 +342,6 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
for (i = 0; i < op->operands; ++i) {
|
||||
exprs[i] = sy->out[vec_size(sy->out)+i].out;
|
||||
blocks[i] = sy->out[vec_size(sy->out)+i].block;
|
||||
asvalue[i] = (ast_value*)exprs[i];
|
||||
|
||||
if (exprs[i]->vtype == TYPE_NOEXPR &&
|
||||
!(i != 0 && op->id == opid2('?',':')) &&
|
||||
|
@ -881,9 +894,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
compile_error(ctx, "invalid types in assignment: cannot assign %s to %s", ty2, ty1);
|
||||
}
|
||||
}
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ctx, exprs[0]);
|
||||
out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]);
|
||||
break;
|
||||
case opid3('+','+','P'):
|
||||
|
@ -898,9 +909,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
addop = INSTR_ADD_F;
|
||||
else
|
||||
addop = INSTR_SUB_F;
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ast_ctx(exprs[0]), "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ast_ctx(exprs[0]), exprs[0]);
|
||||
if (ast_istype(exprs[0], ast_entfield)) {
|
||||
out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
|
||||
exprs[0],
|
||||
|
@ -926,9 +935,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
addop = INSTR_SUB_F;
|
||||
subop = INSTR_ADD_F;
|
||||
}
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ast_ctx(exprs[0]), "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ast_ctx(exprs[0]), exprs[0]);
|
||||
if (ast_istype(exprs[0], ast_entfield)) {
|
||||
out = (ast_expression*)ast_binstore_new(ctx, INSTR_STOREP_F, addop,
|
||||
exprs[0],
|
||||
|
@ -955,9 +962,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
ty1, ty2);
|
||||
return false;
|
||||
}
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ctx, exprs[0]);
|
||||
if (ast_istype(exprs[0], ast_entfield))
|
||||
assignop = type_storep_instr[exprs[0]->vtype];
|
||||
else
|
||||
|
@ -992,9 +997,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
ty1, ty2);
|
||||
return false;
|
||||
}
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ctx, exprs[0]);
|
||||
if (ast_istype(exprs[0], ast_entfield))
|
||||
assignop = type_storep_instr[exprs[0]->vtype];
|
||||
else
|
||||
|
@ -1038,9 +1041,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
ty1, ty2);
|
||||
return false;
|
||||
}
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ctx, exprs[0]);
|
||||
if (ast_istype(exprs[0], ast_entfield))
|
||||
assignop = type_storep_instr[exprs[0]->vtype];
|
||||
else
|
||||
|
@ -1076,9 +1077,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
|
|||
out = (ast_expression*)ast_binary_new(ctx, VINSTR_BITAND_V, exprs[0], exprs[1]);
|
||||
if (!out)
|
||||
return false;
|
||||
if (ast_istype(exprs[0], ast_value) && asvalue[0]->cvq == CV_CONST) {
|
||||
compile_error(ctx, "assignment to constant `%s`", asvalue[0]->name);
|
||||
}
|
||||
(void)check_write_to(ctx, exprs[0]);
|
||||
if (exprs[0]->vtype == TYPE_FLOAT)
|
||||
asbinstore = ast_binstore_new(ctx, assignop, INSTR_SUB_F, exprs[0], out);
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue