@@ -4746,7 +4746,7 @@ ecs_table_t *flecs_traverse_from_expr(
47464746 const char *ptr = expr;
47474747 if (ptr) {
47484748 ecs_term_t term = {0};
4749- while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){
4749+ while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term, NULL ))){
47504750 if (!ecs_term_is_initialized(&term)) {
47514751 break;
47524752 }
@@ -4809,7 +4809,7 @@ void flecs_defer_from_expr(
48094809 const char *ptr = expr;
48104810 if (ptr) {
48114811 ecs_term_t term = {0};
4812- while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){
4812+ while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term, NULL ))) {
48134813 if (!ecs_term_is_initialized(&term)) {
48144814 break;
48154815 }
@@ -11053,23 +11053,50 @@ ecs_filter_t* ecs_filter_init(
1105311053 const char *name = NULL;
1105411054 const char *ptr = desc->expr;
1105511055 ecs_term_t term = {0};
11056+ ecs_term_id_t extra_args[ECS_PARSER_MAX_ARGS];
1105611057 int32_t expr_size = 0;
1105711058
11059+ ecs_os_zeromem(extra_args);
11060+
1105811061 if (entity) {
1105911062 name = ecs_get_name(world, entity);
1106011063 }
1106111064
11062- while (ptr[0] && (ptr = ecs_parse_term(world, name, expr, ptr, &term))){
11065+ while (ptr[0] &&
11066+ (ptr = ecs_parse_term(world, name, expr, ptr, &term, extra_args)))
11067+ {
1106311068 if (!ecs_term_is_initialized(&term)) {
1106411069 break;
1106511070 }
1106611071
11067- if (expr_count == expr_size) {
11068- expr_size = expr_size ? expr_size * 2 : 8;
11069- expr_terms = ecs_os_realloc_n(expr_terms, ecs_term_t, expr_size);
11070- }
11072+ int32_t arg = 0;
11073+
11074+ do {
11075+ ecs_assert(arg <= ECS_PARSER_MAX_ARGS, ECS_INTERNAL_ERROR, NULL);
11076+
11077+ if (expr_count == expr_size) {
11078+ expr_size = expr_size ? expr_size * 2 : 8;
11079+ expr_terms = ecs_os_realloc_n(expr_terms, ecs_term_t, expr_size);
11080+ }
11081+
11082+ ecs_term_t *expr_term = &expr_terms[expr_count ++];
11083+ *expr_term = term;
11084+
11085+ if (arg) {
11086+ expr_term->src = expr_term[-1].second;
11087+ expr_term->second = extra_args[arg - 1];
11088+
11089+ if (expr_term->first.name != NULL) {
11090+ expr_term->first.name = ecs_os_strdup(
11091+ expr_term->first.name);
11092+ }
11093+ if (expr_term->src.name != NULL) {
11094+ expr_term->src.name = ecs_os_strdup(
11095+ expr_term->src.name);
11096+ }
11097+ }
11098+ } while (ecs_term_id_is_set(&extra_args[arg ++]));
1107111099
11072- expr_terms[expr_count ++] = term;
1107311100 if (ptr[0] == '\n') {
1107411101 break;
1107511102 }
@@ -30577,15 +30604,24 @@ const char* flecs_parse_arguments(
3057730604 int64_t column,
3057830605 const char *ptr,
3057930606 char *token,
30580- ecs_term_t *term)
30607+ ecs_term_t *term,
30608+ ecs_term_id_t *extra_args)
3058130609{
3058230610 (void)column;
3058330611
3058430612 int32_t arg = 0;
3058530613
30614+ if (extra_args) {
30615+ ecs_os_memset_n(extra_args, 0, ecs_term_id_t, ECS_PARSER_MAX_ARGS);
30616+ }
30617+
30618+ if (!term) {
30619+ arg = 2;
30620+ }
30621+
3058630622 do {
3058730623 if (flecs_valid_token_start_char(ptr[0])) {
30588- if (arg == 2 ) {
30624+ if (( arg == ECS_PARSER_MAX_ARGS) || (!extra_args && arg == 2) ) {
3058930625 ecs_parser_error(name, expr, (ptr - expr),
3059030626 "too many arguments in term");
3059130627 return NULL;
@@ -30602,6 +30638,8 @@ const char* flecs_parse_arguments(
3060230638 term_id = &term->src;
3060330639 } else if (arg == 1) {
3060430640 term_id = &term->second;
30641+ } else {
30642+ term_id = &extra_args[arg - 2];
3060530643 }
3060630644
3060730645 /* If token is a colon, the token is an identifier followed by a
@@ -30643,7 +30681,9 @@ const char* flecs_parse_arguments(
3064330681 if (ptr[0] == TOK_AND) {
3064430682 ptr = ecs_parse_ws(ptr + 1);
3064530683
30646- term->id_flags = ECS_PAIR;
30684+ if (term) {
30685+ term->id_flags = ECS_PAIR;
30686+ }
3064730687
3064830688 } else if (ptr[0] == TOK_PAREN_CLOSE) {
3064930689 ptr = ecs_parse_ws(ptr + 1);
@@ -30689,7 +30729,8 @@ const char* flecs_parse_term(
3068930729 const ecs_world_t *world,
3069030730 const char *name,
3069130731 const char *expr,
30692- ecs_term_t *term_out)
30732+ ecs_term_t *term_out,
30733+ ecs_term_id_t *extra_args)
3069330734{
3069430735 const char *ptr = expr;
3069530736 char token[ECS_MAX_TOKEN_SIZE] = {0};
@@ -30837,7 +30878,7 @@ const char* flecs_parse_term(
3083730878 ptr = ecs_parse_ws(ptr);
3083830879 } else {
3083930880 ptr = flecs_parse_arguments(
30840- world, name, expr, (ptr - expr), ptr, token, &term);
30881+ world, name, expr, (ptr - expr), ptr, token, &term, extra_args );
3084130882 }
3084230883
3084330884 goto parse_done;
@@ -30955,8 +30996,7 @@ const char* flecs_parse_term(
3095530996 }
3095630997 }
3095730998
30958- if (ptr[0] == TOK_PAREN_CLOSE) {
30959- ptr ++;
30999+ if (ptr[0] == TOK_PAREN_CLOSE || ptr[0] == TOK_AND) {
3096031000 goto parse_pair_object;
3096131001 } else {
3096231002 flecs_parser_unexpected_char(name, expr, ptr, ptr[0]);
@@ -30983,6 +31023,17 @@ const char* flecs_parse_term(
3098331023 term.id_flags = ECS_PAIR;
3098431024 }
3098531025
31026+ if (ptr[0] == TOK_AND) {
31027+ ptr = ecs_parse_ws(ptr + 1);
31028+ ptr = flecs_parse_arguments(
31029+ world, name, expr, (ptr - expr), ptr, token, NULL, extra_args);
31030+ if (!ptr) {
31031+ goto error;
31032+ }
31033+ } else {
31034+ ptr ++;
31035+ }
31036+
3098631037 ptr = ecs_parse_ws(ptr);
3098731038 goto parse_done;
3098831039
@@ -31020,7 +31071,8 @@ char* ecs_parse_term(
3102031071 const char *name,
3102131072 const char *expr,
3102231073 const char *ptr,
31023- ecs_term_t *term)
31074+ ecs_term_t *term,
31075+ ecs_term_id_t *extra_args)
3102431076{
3102531077 ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
3102631078 ecs_check(ptr != NULL, ECS_INVALID_PARAMETER, NULL);
@@ -31056,7 +31108,7 @@ char* ecs_parse_term(
3105631108 }
3105731109
3105831110 /* Parse next element */
31059- ptr = flecs_parse_term(world, name, ptr, term);
31111+ ptr = flecs_parse_term(world, name, ptr, term, extra_args );
3106031112 if (!ptr) {
3106131113 goto error;
3106231114 }
@@ -32887,7 +32939,7 @@ const char *plecs_parse_plecs_term(
3288732939 decl_id = state->last_predicate;
3288832940 }
3288932941
32890- ptr = ecs_parse_term(world, name, expr, ptr, &term);
32942+ ptr = ecs_parse_term(world, name, expr, ptr, &term, NULL );
3289132943 if (!ptr) {
3289232944 return NULL;
3289332945 }
0 commit comments