eolian: fix evaluation of "undefined" enum fields
This commit is contained in:
parent
e6ed156e39
commit
e90e3af8b5
|
@ -495,6 +495,7 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
|
|||
const Eolian_Variable *var = eolian_variable_constant_get_by_name
|
||||
(expr->value.s);
|
||||
const Eolian_Expression *exp = NULL;
|
||||
int fl_nadd = 0;
|
||||
|
||||
if (!var)
|
||||
{
|
||||
|
@ -507,6 +508,10 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
|
|||
if (!split_enum_name(expr->value.s, &fulln, &memb))
|
||||
return expr_error(expr, "undefined variable");
|
||||
|
||||
/* assert int here, as we're clearly dealing with enum */
|
||||
if (!(mask & EOLIAN_MASK_INT))
|
||||
return expr_type_error(expr, EOLIAN_MASK_INT, mask);
|
||||
|
||||
etp = eolian_type_alias_get_by_name(fulln);
|
||||
while (etp && (etp->type == EOLIAN_TYPE_ALIAS
|
||||
|| etp->type == EOLIAN_TYPE_REGULAR))
|
||||
|
@ -520,7 +525,31 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
|
|||
}
|
||||
|
||||
fl = eolian_type_enum_field_get(etp, memb);
|
||||
if (fl) exp = eolian_type_enum_field_value_get(fl);
|
||||
if (fl)
|
||||
{
|
||||
/* we have the field, but the value might not exist
|
||||
* we should search for last valid enum field, use that */
|
||||
exp = fl->value;
|
||||
if (!exp)
|
||||
{
|
||||
Eina_List *flist = fl->base_enum->field_list;
|
||||
Eolian_Enum_Type_Field *lfl = eina_list_data_get(flist);
|
||||
while (lfl && lfl->name != fl->name)
|
||||
{
|
||||
flist = eina_list_next(flist);
|
||||
lfl = eina_list_data_get(flist);
|
||||
}
|
||||
/* we've found our list item, now let's go backwards */
|
||||
while (!lfl->value)
|
||||
{
|
||||
++fl_nadd;
|
||||
flist = eina_list_prev(flist);
|
||||
lfl = eina_list_data_get(flist);
|
||||
}
|
||||
/* we've found our first reachable value */
|
||||
exp = lfl->value;
|
||||
}
|
||||
}
|
||||
free(fulln);
|
||||
|
||||
if (!exp)
|
||||
|
@ -532,6 +561,25 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask,
|
|||
if (!exp)
|
||||
return expr_error(expr, "undefined variable");
|
||||
|
||||
if (fl_nadd)
|
||||
{
|
||||
Eolian_Expression eexp, vexp;
|
||||
eexp.base.file = exp->base.file;
|
||||
eexp.base.line = eexp.base.column = -1;
|
||||
vexp.base.file = exp->base.file;
|
||||
vexp.base.line = vexp.base.column = -1;
|
||||
|
||||
vexp.type = EOLIAN_EXPR_INT;
|
||||
vexp.value.i = fl_nadd;
|
||||
|
||||
eexp.type = EOLIAN_EXPR_BINARY;
|
||||
eexp.binop = EOLIAN_BINOP_ADD;
|
||||
eexp.lhs = (Eolian_Expression *)exp;
|
||||
eexp.rhs = &vexp;
|
||||
|
||||
return eval_exp(&eexp, mask, out);
|
||||
}
|
||||
|
||||
return eval_exp(exp, mask, out);
|
||||
}
|
||||
case EOLIAN_EXPR_UNARY:
|
||||
|
|
|
@ -16,6 +16,17 @@ enum Baz {
|
|||
flag3 = 1 << 2
|
||||
}
|
||||
|
||||
enum Value {
|
||||
foo,
|
||||
bar,
|
||||
baz = 2,
|
||||
bah,
|
||||
bam,
|
||||
pants
|
||||
}
|
||||
|
||||
const Pants: int = Value.pants;
|
||||
|
||||
const Bah: int = Baz.flag1;
|
||||
|
||||
class Enum {
|
||||
|
|
|
@ -916,6 +916,13 @@ START_TEST(eolian_enum)
|
|||
fail_if(v.type != EOLIAN_EXPR_INT);
|
||||
fail_if(v.value.i != (1 << 0));
|
||||
|
||||
fail_if(!(var = eolian_variable_constant_get_by_name("Pants")));
|
||||
fail_if(eolian_variable_type_get(var) != EOLIAN_VAR_CONSTANT);
|
||||
fail_if(!(exp = eolian_variable_value_get(var)));
|
||||
v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
|
||||
fail_if(v.type != EOLIAN_EXPR_INT);
|
||||
fail_if(v.value.i != 5);
|
||||
|
||||
eolian_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
|
Loading…
Reference in New Issue