#include void DeserExprOperators_add_2_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_2_int_literals_twice(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20); test_assert(ecs_parse_expr(world, "10 + 20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_sub_2_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "20 - 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(int64_t*)v.ptr, 20 - 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_2_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "20 * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, 20 * 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_2_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 / 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 10 / 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 20 + 30", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20 + 30); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_3_int_literals_twice(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 20 + 30", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20 + 30); test_assert(ecs_parse_expr(world, "10 + 20 + 30", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20 + 30); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_sub_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "30 - 10 - 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, 30 - 10 - 5); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 * 5 * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, 2 * 5 * 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "40 / 5 / 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 40 / 5 / 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_int_to_bool(void) { ecs_world_t *world = ecs_init(); bool b = false; ecs_value_t v = { .type = ecs_id(ecs_bool_t), .ptr = &b }; test_assert(ecs_parse_expr(world, "10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_bool_t*)v.ptr, true); test_assert(ecs_parse_expr(world, "0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_bool_t*)v.ptr, false); test_assert(ecs_parse_expr(world, "256", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_bool_t*)v.ptr, true); ecs_fini(world); } void DeserExprOperators_bool_to_int(void) { ecs_world_t *world = ecs_init(); int32_t i = 0; ecs_value_t v = { .type = ecs_id(ecs_i32_t), .ptr = &i }; test_assert(ecs_parse_expr(world, "true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i32_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_i32_t*)v.ptr, 1); test_assert(ecs_parse_expr(world, "false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i32_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_i32_t*)v.ptr, 0); ecs_fini(world); } void DeserExprOperators_bool_to_uint(void) { ecs_world_t *world = ecs_init(); uint32_t i = 0; ecs_value_t v = { .type = ecs_id(ecs_u32_t), .ptr = &i }; test_assert(ecs_parse_expr(world, "true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u32_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_u32_t*)v.ptr, 1); test_assert(ecs_parse_expr(world, "false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u32_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_u32_t*)v.ptr, 0); ecs_fini(world); } void DeserExprOperators_add_mul_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 20 * 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 + 20 * 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_sub_mul_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "50 - 10 * 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(int64_t*)v.ptr, 50 - 10 * 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_mul_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 / 5 * 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 10 / 5 * 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_div_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 30 / 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_f64_t*)v.ptr, 10 + 30 / 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_sub_div_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "30 - 10 / 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_f64_t*)v.ptr, 30 - 10 / 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_div_3_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "20 * 10 / 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_f64_t*)v.ptr, 20 * 10 / 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_add_mul_add_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 * 4 + 6 * 8 + 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, 2 * 4 + 6 * 8 + 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_sub_mul_sub_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 * 4 - 6 * 8 - 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, 2 * 4 - 6 * 8 - 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_div_mul_div_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 * 4 / 6 * 8 / 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 2.0 * 4.0 / 6.0 * 8.0 / 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_add_div_add_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 / 4 + 6 / 8 + 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 2.0 / 4.0 + 6.0 / 8.0 + 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_sub_div_sub_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 / 4 - 6 / 8 - 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 2.0 / 4.0 - 6.0 / 8.0 - 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_mul_div_mul_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 / 4 * 6 / 8 * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 2.0 / 4.0 * 6.0 / 8.0 * 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_sub_div_mul_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "2 / 4 - 6 / 8 * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 2.0 / 4.0 - 6.0 / 8.0 * 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_2_flt_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10.5 + 20.0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 10.5 + 20.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_sub_2_flt_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "20.5 - 10.0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 20.5 - 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_2_flt_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "20.5 * 10.0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 20.5 * 10.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_2_flt_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10.5 / 2.0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, 10.5 / 2.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_2_int_neg_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "-10 + -20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, -10 + -20); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_sub_2_int_neg_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "-10 - -20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, -10 - -20); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_2_int_neg_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "-10 * -20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, -10 * -20); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_div_2_int_neg_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "-10 / -20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f64_t)); test_assert(v.ptr != NULL); test_flt(*(ecs_f64_t*)v.ptr, -10.0 / -20.0); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_lparen_add_add_rparen_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 * (20 + 30)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, 10 * (20 + 30)); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_lparen_add_add_add_rparen_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 * (20 + 30 + 40)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, 10 * (20 + 30 + 40)); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_lparen_add_add_rparen_add_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 * (20 + 30) + 40", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, 10 * (20 + 30) + 40); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_lparen_add_add_rparen_mul_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "(20 + 30) * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, (20 + 30) * 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_lparen_add_add_add_rparen_mul_int_literals(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "(20 + 30 + 40) * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, (20 + 30 + 40) * 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_double_paren_add_add(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "((20 + 30))", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, ((20 + 30))); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_double_paren_literal(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "((20))", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, ((20))); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_lparen_add_add_rparen_mul_lparen_add_add_rparen(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "(10 + 20) * (20 + 30)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_u64_t*)v.ptr, (10 + 20) * (20 + 30)); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_float_result_add_2_int_literals(void) { ecs_world_t *world = ecs_init(); float value = 0; ecs_value_t v = { .type = ecs_id(ecs_f32_t), .ptr = &value }; test_assert(ecs_parse_expr(world, "10 + 20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_f32_t)); test_assert(v.ptr != NULL); test_flt(value, 10 + 20); ecs_fini(world); } void DeserExprOperators_struct_result_add_2_int_literals(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t value; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"value", ecs_id(ecs_i32_t)} } }); Mass v = {0}; const char *ptr = ecs_parse_expr(world, "{10 + 20}", &(ecs_value_t){ .type = t, .ptr = &v }, NULL); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.value, 10 + 20); ecs_fini(world); } void DeserExprOperators_struct_result_add_2_2_fields_int_literals(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t x; int32_t y; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); Mass v = {0}; const char *ptr = ecs_parse_expr(world, "{10 + 20, 20 + 30}", &(ecs_value_t){ .type = t, .ptr = &v }, NULL); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.x, 10 + 20); test_uint(v.y, 20 + 30); ecs_fini(world); } void DeserExprOperators_struct_result_add_3_int_literals(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t value; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"value", ecs_id(ecs_i32_t)} } }); Mass v = {0}; const char *ptr = ecs_parse_expr(world, "{10 + 20 + 30}", &(ecs_value_t){ .type = t, .ptr = &v }, NULL); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.value, 10 + 20 + 30); ecs_fini(world); } void DeserExprOperators_struct_result_lparen_int_rparen(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t value; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"value", ecs_id(ecs_i32_t)} } }); Mass v = {0}; const char *ptr = ecs_parse_expr(world, "{(10)}", &(ecs_value_t){ .type = t, .ptr = &v }, NULL); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.value, 10); ecs_fini(world); } void DeserExprOperators_add_to_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); *(int32_t*)var->value.ptr = 10; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; const char *ptr = ecs_parse_expr(world, "$foo + 20", &v, &desc); test_assert(ptr != NULL); test_assert(!ptr[0]); test_int(*(int32_t*)v.ptr, 10 + 20); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_add_var_to(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); *(int32_t*)var->value.ptr = 10; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; const char *ptr = ecs_parse_expr(world, "20 + $foo", &v, &desc); test_assert(ptr != NULL); test_assert(!ptr[0]); test_int(*(int32_t*)v.ptr, 20 + 10); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_var_member(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { { .name = "x", .type = ecs_id(ecs_i32_t) }, { .name = "y", .type = ecs_id(ecs_i32_t) } } }); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(Position)); *(Position*)var->value.ptr = (Position){10, 20}; ecs_parse_expr_desc_t desc = { .vars = &vars }; { ecs_value_t v = {0}; const char *ptr = ecs_parse_expr(world, "$foo.x", &v, &desc); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.type, ecs_id(ecs_i32_t)); test_int(*(ecs_i32_t*)v.ptr, 10); ecs_value_free(world, v.type, v.ptr); } { ecs_value_t v = {0}; const char *ptr = ecs_parse_expr(world, "$foo.y", &v, &desc); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.type, ecs_id(ecs_i32_t)); test_int(*(ecs_i32_t*)v.ptr, 20); ecs_value_free(world, v.type, v.ptr); } ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_bool_cond_and_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true && true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true && false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false && true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false && false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_bool_cond_or_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true || true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true || false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false || true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false || false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_int_cond_and_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 && 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 && 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "0 && 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "0 && 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_int_cond_or_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 || 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 || 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "0 || 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "0 || 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_bool_cond_and_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true && 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true && 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false && 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false && 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_int_cond_and_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 && true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 && false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "0 && true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "0 && false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_bool_cond_or_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true || 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true || 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false || 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false || 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_int_cond_or_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 || true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 || false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "0 || true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "0 || false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_eq_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true == true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true == false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false == true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false == false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_eq_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 == 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 == 20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "10 == 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "0 == 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_neq_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true != true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "true != false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false != true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false != false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_neq_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 != 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "10 != 20", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 != 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "0 != 0", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_eq_bool_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; ecs_log_set_level(-4); test_assert(ecs_parse_expr(world, "true == 1", &v, NULL) == NULL); test_assert(ecs_parse_expr(world, "true == 0", &v, NULL) == NULL); test_assert(ecs_parse_expr(world, "false == 0", &v, NULL) == NULL); ecs_fini(world); } void DeserExprOperators_cond_eq_int_flt(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; ecs_log_set_level(-4); test_assert(ecs_parse_expr(world, "1 == 1.0", &v, NULL) == NULL); test_assert(ecs_parse_expr(world, "1 == 0.0", &v, NULL) == NULL); test_assert(ecs_parse_expr(world, "0 == 0.0", &v, NULL) == NULL); ecs_fini(world); } void DeserExprOperators_cond_eq_cond_and(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true == true && false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true == true && false); test_assert(ecs_parse_expr(world, "true && false == false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true && false == false); test_assert(ecs_parse_expr(world, "true && true == true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true && true == true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_eq_cond_or(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true == true || false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true == true || false); test_assert(ecs_parse_expr(world, "true || false == false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true || false == false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_gt_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true > false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true > true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false > true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false > false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_gt_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 > 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 > 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5 > 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5 > 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_gt_flt(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10.5 > 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10.5 > 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5.5 > 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5.5 > 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_gteq_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true >= false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "true >= true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false >= true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false >= false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_gteq_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 >= 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10 >= 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5 >= 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5 >= 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_gteq_flt(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10.5 >= 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "10.5 >= 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5.5 >= 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5.5 >= 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_lt_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true < false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "true < true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "false < true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false < false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_lt_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 < 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "10 < 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5 < 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5 < 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_lt_flt(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10.5 < 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "10.5 < 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "5.5 < 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5.5 < 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_lteq_bool(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "true <= false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "true <= true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false <= true", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "false <= false", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_lteq_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 <= 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "10 <= 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5 <= 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5 <= 5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_cond_lteq_flt(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10.5 <= 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, false); test_assert(ecs_parse_expr(world, "10.5 <= 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5.5 <= 10.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); test_assert(ecs_parse_expr(world, "5.5 <= 5.5", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_bool_t)); test_assert(v.ptr != NULL); test_bool(*(bool*)v.ptr, true); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_min_lparen_int_rparen(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "-(10)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, -10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_min_lparen_int_add_int_rparen(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "-(10 + 20)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, -30); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_min_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare( &vars, "foo", ecs_id(ecs_u64_t)); *(ecs_u64_t*)var->value.ptr = 10; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; test_assert(ecs_parse_expr(world, "-$foo", &v, &desc) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(*(ecs_i64_t*)v.ptr, -10); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_min_lparen_int_rparen_to_i64(void) { ecs_world_t *world = ecs_init(); ecs_i64_t vi = 0; ecs_value_t v = { .type = ecs_id(ecs_i64_t), .ptr = &vi }; test_assert(ecs_parse_expr(world, "-(10)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i64_t)); test_assert(v.ptr != NULL); test_int(vi, -10); ecs_fini(world); } void DeserExprOperators_min_lparen_int_rparen_to_i32(void) { ecs_world_t *world = ecs_init(); ecs_i32_t vi = 0; ecs_value_t v = { .type = ecs_id(ecs_i32_t), .ptr = &vi }; test_assert(ecs_parse_expr(world, "-(10)", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_i32_t)); test_assert(v.ptr != NULL); test_int(vi, -10); ecs_fini(world); } void DeserExprOperators_struct_w_min_var(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t value; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"value", ecs_id(ecs_i32_t)} } }); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare( &vars, "foo", ecs_id(ecs_u64_t)); *(ecs_u64_t*)var->value.ptr = 10; Mass v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; const char *ptr = ecs_parse_expr(world, "{-$foo}", &(ecs_value_t){ .type = t, .ptr = &v }, &desc); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.value, -10); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_struct_w_min_lparen_int_rparen(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t value; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"value", ecs_id(ecs_i32_t)} } }); Mass v = {0}; const char *ptr = ecs_parse_expr(world, "{-(10)}", &(ecs_value_t){ .type = t, .ptr = &v }, NULL); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.value, -10); ecs_fini(world); } void DeserExprOperators_struct_w_min_lparen_var_rparen(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t value; } Mass; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .members = { {"value", ecs_id(ecs_i32_t)} } }); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare( &vars, "foo", ecs_id(ecs_u64_t)); *(ecs_u64_t*)var->value.ptr = 10; Mass v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; const char *ptr = ecs_parse_expr(world, "{-($foo)}", &(ecs_value_t){ .type = t, .ptr = &v }, &desc); test_assert(ptr != NULL); test_assert(!ptr[0]); test_uint(v.value, -10); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_shift_left_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "1 << 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 1 << 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_shift_right_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "4 >> 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 4 >> 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_shift_left_int_add_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "1 << 2 + 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 1 << (2 + 10)); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_shift_left_int_mul_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "1 << 2 * 10", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 1 << 2 * 10); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_int_shift_left_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 1 << 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, (10 + 1) << 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_int_shift_left_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 * 1 << 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 * 1 << 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_add_int_shift_left_int_add_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 + 1 << 2 + 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, (10 + 1) << (2 + 2)); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_mul_int_shift_left_int_mul_int(void) { ecs_world_t *world = ecs_init(); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "10 * 1 << 2 * 2", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_u64_t)); test_assert(v.ptr != NULL); test_uint(*(uint64_t*)v.ptr, 10 * 1 << 2 * 2); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_entity_expr(void) { ecs_world_t *world = ecs_init(); ecs_entity_t foo = ecs_new_entity(world, "foo"); test_assert(foo != 0); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "foo", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_entity_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_entity_t*)v.ptr, foo); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_entity_path_expr(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t foo = ecs_new_entity(world, "parent.foo"); test_assert(foo != 0); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "parent.foo", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_entity_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_entity_t*)v.ptr, foo); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_entity_parent_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t foo = ecs_new_entity(world, "parent.foo"); test_assert(foo != 0); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "parent.foo.parent()", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_entity_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_entity_t*)v.ptr, parent); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_entity_name_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t foo = ecs_new_entity(world, "parent.foo"); test_assert(foo != 0); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "parent.foo.name()", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_string_t)); test_assert(v.ptr != NULL); test_str(*(char**)v.ptr, "foo"); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_entity_doc_name_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t foo = ecs_new_entity(world, "parent.foo"); test_assert(foo != 0); ecs_doc_set_name(world, foo, "FooDoc"); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "parent.foo.doc_name()", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_string_t)); test_assert(v.ptr != NULL); test_str(*(char**)v.ptr, "FooDoc"); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_entity_chain_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t foo = ecs_new_entity(world, "parent.foo"); test_assert(foo != 0); ecs_value_t v = {0}; test_assert(ecs_parse_expr(world, "parent.foo.parent().name()", &v, NULL) != NULL); test_assert(v.type == ecs_id(ecs_string_t)); test_assert(v.ptr != NULL); test_str(*(char**)v.ptr, "parent"); ecs_value_free(world, v.type, v.ptr); ecs_fini(world); } void DeserExprOperators_var_parent_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t child = ecs_new_entity(world, "parent.child"); test_assert(child != 0); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(ecs_entity_t)); test_assert(var != NULL); *(ecs_entity_t*)var->value.ptr = child; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; test_assert(ecs_parse_expr(world, "$foo.parent()", &v, &desc) != NULL); test_assert(v.type == ecs_id(ecs_entity_t)); test_assert(v.ptr != NULL); test_uint(*(ecs_entity_t*)v.ptr, parent); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_var_name_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t child = ecs_new_entity(world, "parent.child"); test_assert(child != 0); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(ecs_entity_t)); test_assert(var != NULL); *(ecs_entity_t*)var->value.ptr = child; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; test_assert(ecs_parse_expr(world, "$foo.name()", &v, &desc) != NULL); test_assert(v.type == ecs_id(ecs_string_t)); test_assert(v.ptr != NULL); test_str(*(char**)v.ptr, "child"); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_var_doc_name_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t child = ecs_new_entity(world, "parent.child"); test_assert(child != 0); ecs_doc_set_name(world, child, "ChildDoc"); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(ecs_entity_t)); test_assert(var != NULL); *(ecs_entity_t*)var->value.ptr = child; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; test_assert(ecs_parse_expr(world, "$foo.doc_name()", &v, &desc) != NULL); test_assert(v.type == ecs_id(ecs_string_t)); test_assert(v.ptr != NULL); test_str(*(char**)v.ptr, "ChildDoc"); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_var_chain_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t child = ecs_new_entity(world, "parent.child"); test_assert(child != 0); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(ecs_entity_t)); test_assert(var != NULL); *(ecs_entity_t*)var->value.ptr = child; ecs_value_t v = {0}; ecs_parse_expr_desc_t desc = { .vars = &vars }; test_assert(ecs_parse_expr(world, "$foo.parent().name()", &v, &desc) != NULL); test_assert(v.type == ecs_id(ecs_string_t)); test_assert(v.ptr != NULL); test_str(*(char**)v.ptr, "parent"); ecs_value_free(world, v.type, v.ptr); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_i32_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); test_assert(v != NULL); *(int32_t*)v->value.ptr = 10; char *result = ecs_interpolate_string(world, "$foo", &vars); test_assert(result != NULL); test_str(result, "10"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_string_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_string_t)); test_assert(v != NULL); *(ecs_string_t*)v->value.ptr = ecs_os_strdup("Hello World"); char *result = ecs_interpolate_string(world, "$foo", &vars); test_assert(result != NULL); test_str(result, "Hello World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_entity_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_entity_t)); test_assert(v != NULL); *(ecs_entity_t*)v->value.ptr = ecs_id(ecs_i32_t); char *result = ecs_interpolate_string(world, "$foo", &vars); test_assert(result != NULL); test_str(result, "flecs.meta.i32"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_var_not_found(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_log_set_level(-4); char *result = ecs_interpolate_string(world, "$foo", &vars); test_assert(result == NULL); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_entity_var_0(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_entity_t)); test_assert(v != NULL); *(ecs_entity_t*)v->value.ptr = 0; char *result = ecs_interpolate_string(world, "$foo", &vars); test_assert(result != NULL); test_str(result, "0"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_var_special_chars(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "_foo_bar_10", ecs_id(ecs_i32_t)); test_assert(v != NULL); *(int32_t*)v->value.ptr = 10; char *result = ecs_interpolate_string(world, "$_foo_bar_10", &vars); test_assert(result != NULL); test_str(result, "10"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_var_before_after_text(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); test_assert(v != NULL); *(int32_t*)v->value.ptr = 10; char *result = ecs_interpolate_string(world, "Hello $foo World", &vars); test_assert(result != NULL); test_str(result, "Hello 10 World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_curly_brackets_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); test_assert(v != NULL); *(int32_t*)v->value.ptr = 10; char *result = ecs_interpolate_string(world, "Hello {$foo}World", &vars); test_assert(result != NULL); test_str(result, "Hello 10World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_curly_brackets_expr(void) { ecs_world_t *world = ecs_init(); char *result = ecs_interpolate_string(world, "Hello {10 + 20}World", NULL); test_assert(result != NULL); test_str(result, "Hello 30World"); ecs_os_free(result); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_curly_brackets_expr_w_var(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); test_assert(v != NULL); *(int32_t*)v->value.ptr = 10; char *result = ecs_interpolate_string(world, "Hello {$foo + 5}World", &vars); test_assert(result != NULL); test_str(result, "Hello 15World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_curly_brackets_expr_w_composite_var(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { { .name = "x", .type = ecs_id(ecs_i32_t) }, { .name = "y", .type = ecs_id(ecs_i32_t) } } }); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(Position)); test_assert(v != NULL); *(Position*)v->value.ptr = (Position){10, 20}; char *result = ecs_interpolate_string(world, "Hello {$foo.x + $foo.y}World", &vars); test_assert(result != NULL); test_str(result, "Hello 30World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_escape_var_operator(void) { ecs_world_t *world = ecs_init(); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *v = ecs_vars_declare( &vars, "foo", ecs_id(ecs_i32_t)); test_assert(v != NULL); *(int32_t*)v->value.ptr = 10; char *result = ecs_interpolate_string(world, "Hello \\$foo World", &vars); test_assert(result != NULL); test_str(result, "Hello $foo World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_escape_curly_brackets(void) { ecs_world_t *world = ecs_init(); char *result = ecs_interpolate_string(world, "Hello \\{10 + 20}World", NULL); test_assert(result != NULL); test_str(result, "Hello {10 + 20}World"); ecs_os_free(result); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_func(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_entity_t child = ecs_new_entity(world, "parent.child"); test_assert(child != 0); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(ecs_entity_t)); test_assert(var != NULL); *(ecs_entity_t*)var->value.ptr = child; char *result = ecs_interpolate_string(world, "Hello {$foo.name()} World", &vars); test_assert(result != NULL); test_str(result, "Hello child World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_interpolate_string_w_func_chain(void) { ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new_entity(world, "parent"); test_assert(parent != 0); ecs_doc_set_name(world, parent, "Parent"); ecs_entity_t child = ecs_new_entity(world, "parent.child"); test_assert(child != 0); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_expr_var_t *var = ecs_vars_declare(&vars, "foo", ecs_id(ecs_entity_t)); test_assert(var != NULL); *(ecs_entity_t*)var->value.ptr = child; char *result = ecs_interpolate_string(world, "Hello {$foo.parent().doc_name()} World", &vars); test_assert(result != NULL); test_str(result, "Hello Parent World"); ecs_os_free(result); ecs_vars_fini(&vars); ecs_fini(world); } void DeserExprOperators_iter_to_vars_no_data(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Foo); ecs_rule_t *rule = ecs_rule(world, { .expr = "Foo" }); test_assert(rule != NULL); ecs_entity_t e1 = ecs_new(world, Foo); ecs_entity_t e2 = ecs_new(world, Foo); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_iter_t it = ecs_rule_iter(world, rule); test_bool(ecs_rule_next(&it), true); test_int(it.count, 2); test_uint(it.entities[0], e1); test_uint(it.entities[1], e2); ecs_iter_to_vars(&it, &vars, 0); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e1); } ecs_iter_to_vars(&it, &vars, 1); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e2); } test_bool(ecs_rule_next(&it), false); ecs_vars_fini(&vars); ecs_rule_fini(rule); ecs_fini(world); } void DeserExprOperators_iter_to_vars_1_comp(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_rule_t *rule = ecs_rule(world, { .expr = "Position" }); test_assert(rule != NULL); ecs_entity_t e1 = ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_iter_t it = ecs_rule_iter(world, rule); test_bool(ecs_rule_next(&it), true); test_int(it.count, 2); test_uint(it.entities[0], e1); test_uint(it.entities[1], e2); ecs_iter_to_vars(&it, &vars, 0); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e1); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Position)); } ecs_iter_to_vars(&it, &vars, 1); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e2); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Position)); } test_bool(ecs_rule_next(&it), false); ecs_vars_fini(&vars); ecs_rule_fini(rule); ecs_fini(world); } void DeserExprOperators_iter_to_vars_2_comps(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ecs_rule_t *rule = ecs_rule(world, { .expr = "Position, Velocity" }); test_assert(rule != NULL); ecs_entity_t e1 = ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_add(world, e1, Velocity); ecs_add(world, e2, Velocity); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_iter_t it = ecs_rule_iter(world, rule); test_bool(ecs_rule_next(&it), true); test_int(it.count, 2); test_uint(it.entities[0], e1); test_uint(it.entities[1], e2); ecs_iter_to_vars(&it, &vars, 0); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e1); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Position)); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "2"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Velocity)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Velocity)); } ecs_iter_to_vars(&it, &vars, 1); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e2); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Position)); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "2"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Velocity)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Velocity)); } test_bool(ecs_rule_next(&it), false); ecs_vars_fini(&vars); ecs_rule_fini(rule); ecs_fini(world); } void DeserExprOperators_iter_to_vars_1_comp_1_tag(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, Velocity); ECS_TAG(world, Foo); ecs_rule_t *rule = ecs_rule(world, { .expr = "Position, Foo, Velocity" }); test_assert(rule != NULL); ecs_entity_t e1 = ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_add(world, e1, Velocity); ecs_add(world, e2, Velocity); ecs_add(world, e1, Foo); ecs_add(world, e2, Foo); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_iter_t it = ecs_rule_iter(world, rule); test_bool(ecs_rule_next(&it), true); test_int(it.count, 2); test_uint(it.entities[0], e1); test_uint(it.entities[1], e2); ecs_iter_to_vars(&it, &vars, 0); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e1); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Position)); } test_assert(ecs_vars_lookup(&vars, "2") == NULL); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "3"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Velocity)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Velocity)); } ecs_iter_to_vars(&it, &vars, 1); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "this"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_uint(*(ecs_entity_t*)v->value.ptr, e2); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Position)); } test_assert(ecs_vars_lookup(&vars, "2") == NULL); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "3"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Velocity)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Velocity)); } test_bool(ecs_rule_next(&it), false); ecs_vars_fini(&vars); ecs_rule_fini(rule); ecs_fini(world); } void DeserExprOperators_iter_to_vars_w_1_query_var(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_rule_t *rule = ecs_rule(world, { .expr = "Position($x)" }); test_assert(rule != NULL); ecs_entity_t e1 = ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_iter_t it = ecs_rule_iter(world, rule); test_bool(ecs_rule_next(&it), true); test_int(it.count, 0); ecs_iter_to_vars(&it, &vars, 0); test_assert(ecs_vars_lookup(&vars, "this") == NULL); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "x"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_assert(*(ecs_entity_t*)v->value.ptr == e1); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Position)); } test_bool(ecs_rule_next(&it), true); test_int(it.count, 0); ecs_iter_to_vars(&it, &vars, 0); test_assert(ecs_vars_lookup(&vars, "this") == NULL); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "x"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_assert(*(ecs_entity_t*)v->value.ptr == e2); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Position)); } test_bool(ecs_rule_next(&it), false); ecs_vars_fini(&vars); ecs_rule_fini(rule); ecs_fini(world); } void DeserExprOperators_iter_to_vars_w_2_query_vars(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_rule_t *rule = ecs_rule(world, { .expr = "Position($x), ChildOf($x, $y)" }); test_assert(rule != NULL); ecs_entity_t parent = ecs_new_id(world); ecs_entity_t e1 = ecs_new(world, Position); ecs_entity_t e2 = ecs_new(world, Position); ecs_add_pair(world, e1, EcsChildOf, parent); ecs_add_pair(world, e2, EcsChildOf, parent); ecs_vars_t vars = {0}; ecs_vars_init(world, &vars); ecs_iter_t it = ecs_rule_iter(world, rule); test_bool(ecs_rule_next(&it), true); test_int(it.count, 0); ecs_iter_to_vars(&it, &vars, 0); test_assert(ecs_vars_lookup(&vars, "this") == NULL); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "x"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_assert(*(ecs_entity_t*)v->value.ptr == e1); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "y"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_assert(*(ecs_entity_t*)v->value.ptr == parent); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e1, Position)); } test_bool(ecs_rule_next(&it), true); test_int(it.count, 0); ecs_iter_to_vars(&it, &vars, 0); test_assert(ecs_vars_lookup(&vars, "this") == NULL); { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "x"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_assert(*(ecs_entity_t*)v->value.ptr == e2); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "y"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(ecs_entity_t)); test_assert(v->value.ptr != NULL); test_assert(*(ecs_entity_t*)v->value.ptr == parent); } { ecs_expr_var_t *v = ecs_vars_lookup(&vars, "1"); test_assert(v != NULL); test_assert(v->value.type == ecs_id(Position)); test_assert(v->value.ptr != NULL); test_assert(v->value.ptr == ecs_get(world, e2, Position)); } test_bool(ecs_rule_next(&it), false); ecs_vars_fini(&vars); ecs_rule_fini(rule); ecs_fini(world); }