Skip to content

Commit a7fba6c

Browse files
SanderMertens#1957 Fix issue with resolving enum type in binary expressions
1 parent 3899dbe commit a7fba6c

6 files changed

Lines changed: 764 additions & 158 deletions

File tree

distr/flecs.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95944,7 +95944,16 @@ int flecs_expr_binary_visit_type(
9594495944
goto error;
9594595945
}
9594695946

95947-
if (flecs_expr_visit_type_priv(script, node->right, cur, desc)) {
95947+
ecs_meta_cursor_t right_cur = *cur;
95948+
if (node->right->kind == EcsExprIdentifier) {
95949+
if (ecs_get(script->world, node->left->type, EcsEnum) != NULL) {
95950+
/* If the left hand side is an enum, interpret untyped identifiers
95951+
* on the right hand side as enum constants of the same type. */
95952+
right_cur = ecs_meta_cursor(script->world, node->left->type, NULL);
95953+
}
95954+
}
95955+
95956+
if (flecs_expr_visit_type_priv(script, node->right, &right_cur, desc)) {
9594895957
goto error;
9594995958
}
9595095959

src/addons/script/expr/visit_type.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,16 @@ int flecs_expr_binary_visit_type(
10961096
goto error;
10971097
}
10981098

1099-
if (flecs_expr_visit_type_priv(script, node->right, cur, desc)) {
1099+
ecs_meta_cursor_t right_cur = *cur;
1100+
if (node->right->kind == EcsExprIdentifier) {
1101+
if (ecs_get(script->world, node->left->type, EcsEnum) != NULL) {
1102+
/* If the left hand side is an enum, interpret untyped identifiers
1103+
* on the right hand side as enum constants of the same type. */
1104+
right_cur = ecs_meta_cursor(script->world, node->left->type, NULL);
1105+
}
1106+
}
1107+
1108+
if (flecs_expr_visit_type_priv(script, node->right, &right_cur, desc)) {
11001109
goto error;
11011110
}
11021111

test/script/project.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,9 @@
419419
"tree_parent_nested_w_for_scope",
420420
"tree_parent_nested_w_pair_scope",
421421
"tree_parent_nested_w_with_scope",
422-
"update_after_add_remove_tree_parent"
422+
"update_after_add_remove_tree_parent",
423+
"assign_eq_enum_to_component",
424+
"assign_eq_enum_to_const"
423425
]
424426
}, {
425427
"id": "Template",
@@ -704,11 +706,13 @@
704706
"cond_eq_bool",
705707
"cond_eq_int",
706708
"cond_eq_enum",
709+
"cond_eq_enum_literal",
707710
"cond_eq_string",
708711
"cond_eq_entity",
709712
"cond_neq_bool",
710713
"cond_neq_int",
711714
"cond_neq_enum",
715+
"cond_neq_enum_literal",
712716
"cond_neq_string",
713717
"cond_neq_entity",
714718
"cond_eq_bool_int",
@@ -718,15 +722,23 @@
718722
"cond_gt_bool",
719723
"cond_gt_int",
720724
"cond_gt_flt",
725+
"cond_gt_enum",
726+
"cond_gt_enum_literal",
721727
"cond_gteq_bool",
722728
"cond_gteq_int",
723729
"cond_gteq_flt",
730+
"cond_gteq_enum",
731+
"cond_gteq_enum_literal",
724732
"cond_lt_bool",
725733
"cond_lt_int",
726734
"cond_lt_flt",
735+
"cond_lt_enum",
736+
"cond_lt_enum_literal",
727737
"cond_lteq_bool",
728738
"cond_lteq_int",
729739
"cond_lteq_flt",
740+
"cond_lteq_enum",
741+
"cond_lteq_enum_literal",
730742
"min_lparen_int_rparen",
731743
"min_lparen_int_add_int_rparen",
732744
"min_number_hex",

test/script/src/Eval.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13745,3 +13745,107 @@ void Eval_update_after_add_remove_tree_parent(void) {
1374513745

1374613746
ecs_fini(world);
1374713747
}
13748+
13749+
void Eval_assign_eq_enum_to_component(void) {
13750+
ecs_world_t *world = ecs_init();
13751+
13752+
typedef struct {
13753+
bool value;
13754+
} SomeType;
13755+
13756+
ecs_entity_t ecs_id(SomeType) = ecs_struct(world, {
13757+
.entity = ecs_entity(world, { .name = "SomeType" }),
13758+
.members = {{ "value", ecs_id(ecs_bool_t) }}
13759+
});
13760+
13761+
const char *expr =
13762+
HEAD "enum Color {"
13763+
LINE " Red, Green, Blue"
13764+
LINE "}"
13765+
LINE ""
13766+
LINE "const c = Color: Red"
13767+
LINE ""
13768+
LINE "e1 {"
13769+
LINE " SomeType: {value: c == Red}"
13770+
LINE "}"
13771+
LINE "e2 {"
13772+
LINE " SomeType: {value: c == Green}"
13773+
LINE "}";
13774+
13775+
test_assert(ecs_script_run(world, NULL, expr, NULL) == 0);
13776+
13777+
{
13778+
ecs_entity_t e = ecs_lookup(world, "e1");
13779+
test_assert(e != 0);
13780+
test_assert(ecs_has(world, e, SomeType));
13781+
13782+
const SomeType *ptr = ecs_get(world, e, SomeType);
13783+
test_assert(ptr != NULL);
13784+
test_int(ptr->value, true);
13785+
}
13786+
13787+
{
13788+
ecs_entity_t e = ecs_lookup(world, "e2");
13789+
test_assert(e != 0);
13790+
test_assert(ecs_has(world, e, SomeType));
13791+
13792+
const SomeType *ptr = ecs_get(world, e, SomeType);
13793+
test_assert(ptr != NULL);
13794+
test_int(ptr->value, false);
13795+
}
13796+
13797+
ecs_fini(world);
13798+
}
13799+
13800+
void Eval_assign_eq_enum_to_const(void) {
13801+
ecs_world_t *world = ecs_init();
13802+
13803+
typedef struct {
13804+
bool value;
13805+
} SomeType;
13806+
13807+
ecs_entity_t ecs_id(SomeType) = ecs_struct(world, {
13808+
.entity = ecs_entity(world, { .name = "SomeType" }),
13809+
.members = {{ "value", ecs_id(ecs_bool_t) }}
13810+
});
13811+
13812+
const char *expr =
13813+
HEAD "enum Color {"
13814+
LINE " Red, Green, Blue"
13815+
LINE "}"
13816+
LINE ""
13817+
LINE "const c = Color: Red"
13818+
LINE "const r1: c == Red"
13819+
LINE "const r2: c == Green"
13820+
LINE ""
13821+
LINE "e1 {"
13822+
LINE " SomeType: {value: r1}"
13823+
LINE "}"
13824+
LINE "e2 {"
13825+
LINE " SomeType: {value: r2}"
13826+
LINE "}";
13827+
13828+
test_assert(ecs_script_run(world, NULL, expr, NULL) == 0);
13829+
13830+
{
13831+
ecs_entity_t e = ecs_lookup(world, "e1");
13832+
test_assert(e != 0);
13833+
test_assert(ecs_has(world, e, SomeType));
13834+
13835+
const SomeType *ptr = ecs_get(world, e, SomeType);
13836+
test_assert(ptr != NULL);
13837+
test_int(ptr->value, true);
13838+
}
13839+
13840+
{
13841+
ecs_entity_t e = ecs_lookup(world, "e2");
13842+
test_assert(e != 0);
13843+
test_assert(ecs_has(world, e, SomeType));
13844+
13845+
const SomeType *ptr = ecs_get(world, e, SomeType);
13846+
test_assert(ptr != NULL);
13847+
test_int(ptr->value, false);
13848+
}
13849+
13850+
ecs_fini(world);
13851+
}

0 commit comments

Comments
 (0)