expr: Remove refcount in body elements
This commit is contained in:
parent
90a80152e1
commit
f26759b3f0
6 changed files with 54 additions and 115 deletions
|
|
@ -242,7 +242,6 @@ struct apfl_expr_body {
|
|||
struct apfl_expr *items;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
unsigned refcount; // TODO: Probably better to not expose refcount
|
||||
};
|
||||
|
||||
enum apfl_expr_const_type {
|
||||
|
|
@ -300,7 +299,7 @@ struct apfl_expr_params_item {
|
|||
|
||||
struct apfl_expr_subfunc {
|
||||
struct apfl_expr_params params;
|
||||
struct apfl_expr_body *body;
|
||||
struct apfl_expr_body body;
|
||||
};
|
||||
|
||||
struct apfl_expr_complex_func {
|
||||
|
|
@ -391,7 +390,7 @@ struct apfl_expr {
|
|||
struct apfl_expr_list list;
|
||||
struct apfl_expr_dict dict;
|
||||
struct apfl_expr_call call;
|
||||
struct apfl_expr_body *simple_func;
|
||||
struct apfl_expr_body simple_func;
|
||||
struct apfl_expr_complex_func complex_func;
|
||||
struct apfl_expr_assignment assignment;
|
||||
struct apfl_expr_dot dot;
|
||||
|
|
@ -416,7 +415,7 @@ void apfl_expr_list_item_deinit(struct apfl_allocator allocator, struct apfl_exp
|
|||
void apfl_expr_dict_pair_deinit(struct apfl_allocator allocator, struct apfl_expr_dict_pair *);
|
||||
void apfl_expr_dict_deinit(struct apfl_allocator allocator, struct apfl_expr_dict *);
|
||||
void apfl_expr_call_deinit(struct apfl_allocator allocator, struct apfl_expr_call *);
|
||||
void apfl_expr_body_unref(struct apfl_allocator allocator, struct apfl_expr_body *);
|
||||
void apfl_expr_body_deinit(struct apfl_allocator allocator, struct apfl_expr_body *);
|
||||
void apfl_expr_const_deinit(struct apfl_allocator allocator, struct apfl_expr_const *);
|
||||
void apfl_expr_param_predicate_deinit(struct apfl_allocator allocator, struct apfl_expr_param_predicate *);
|
||||
void apfl_expr_params_deinit(struct apfl_allocator allocator, struct apfl_expr_params *);
|
||||
|
|
@ -445,7 +444,7 @@ struct apfl_expr_list_item apfl_expr_list_item_move(struct apfl_e
|
|||
struct apfl_expr_dict_pair apfl_expr_dict_pair_move(struct apfl_expr_dict_pair *);
|
||||
struct apfl_expr_dict apfl_expr_dict_move(struct apfl_expr_dict *);
|
||||
struct apfl_expr_call apfl_expr_call_move(struct apfl_expr_call *);
|
||||
struct apfl_expr_body * apfl_expr_body_move(struct apfl_expr_body **);
|
||||
struct apfl_expr_body apfl_expr_body_move(struct apfl_expr_body *);
|
||||
struct apfl_expr_const apfl_expr_const_move(struct apfl_expr_const *);
|
||||
struct apfl_expr_param_predicate apfl_expr_param_predicate_move(struct apfl_expr_param_predicate *);
|
||||
struct apfl_expr_params apfl_expr_params_move(struct apfl_expr_params *);
|
||||
|
|
|
|||
41
src/expr.c
41
src/expr.c
|
|
@ -21,8 +21,7 @@ apfl_expr_deinit(struct apfl_allocator allocator, struct apfl_expr *expr)
|
|||
apfl_expr_call_deinit(allocator, &expr->call);
|
||||
break;
|
||||
case APFL_EXPR_SIMPLE_FUNC:
|
||||
apfl_expr_body_unref(allocator, expr->simple_func);
|
||||
expr->simple_func = NULL;
|
||||
apfl_expr_body_deinit(allocator, &expr->simple_func);
|
||||
break;
|
||||
case APFL_EXPR_COMPLEX_FUNC:
|
||||
apfl_expr_complex_func_deinit(allocator, &expr->complex_func);
|
||||
|
|
@ -81,12 +80,9 @@ apfl_expr_call_deinit(struct apfl_allocator allocator, struct apfl_expr_call *ca
|
|||
}
|
||||
|
||||
void
|
||||
apfl_expr_body_unref(struct apfl_allocator allocator, struct apfl_expr_body *body)
|
||||
apfl_expr_body_deinit(struct apfl_allocator allocator, struct apfl_expr_body *body)
|
||||
{
|
||||
if (body != NULL && apfl_refcount_dec(&body->refcount)) {
|
||||
DEINIT_CAP_LIST(allocator, body->items, body->len, body->cap, apfl_expr_deinit);
|
||||
FREE_OBJ(allocator, body);
|
||||
}
|
||||
DEINIT_CAP_LIST(allocator, body->items, body->len, body->cap, apfl_expr_deinit);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -154,8 +150,7 @@ void
|
|||
apfl_expr_subfunc_deinit(struct apfl_allocator allocator, struct apfl_expr_subfunc *subfunc)
|
||||
{
|
||||
apfl_expr_params_deinit(allocator, &subfunc->params);
|
||||
apfl_expr_body_unref(allocator, subfunc->body);
|
||||
subfunc->body = NULL;
|
||||
apfl_expr_body_deinit(allocator, &subfunc->body);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -358,11 +353,11 @@ apfl_expr_call_move(struct apfl_expr_call *in)
|
|||
return out;
|
||||
}
|
||||
|
||||
struct apfl_expr_body *
|
||||
apfl_expr_body_move(struct apfl_expr_body **in)
|
||||
struct apfl_expr_body
|
||||
apfl_expr_body_move(struct apfl_expr_body *in)
|
||||
{
|
||||
struct apfl_expr_body *out = *in;
|
||||
*in = NULL;
|
||||
struct apfl_expr_body out;
|
||||
MOVE_CAP_LIST(out, in, items, len, cap);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
@ -737,7 +732,7 @@ print_expr(struct apfl_expr *expr, unsigned indent, FILE *f)
|
|||
break;
|
||||
case APFL_EXPR_SIMPLE_FUNC:
|
||||
apfl_print_indented(indent, f, "Simple function @ " POSFMT "\n", POSARGS(expr->position));
|
||||
print_body(expr->simple_func, indent+1, f);
|
||||
print_body(&expr->simple_func, indent+1, f);
|
||||
break;
|
||||
case APFL_EXPR_COMPLEX_FUNC:
|
||||
apfl_print_indented(indent, f, "Complex function @ " POSFMT "\n", POSARGS(expr->position));
|
||||
|
|
@ -749,7 +744,7 @@ print_expr(struct apfl_expr *expr, unsigned indent, FILE *f)
|
|||
print_params_item(&sub->params.params[j], indent+3, f);
|
||||
}
|
||||
apfl_print_indented(indent+2, f, "Body\n");
|
||||
print_body(sub->body, indent+3, f);
|
||||
print_body(&sub->body, indent+3, f);
|
||||
}
|
||||
break;
|
||||
case APFL_EXPR_ASSIGNMENT:
|
||||
|
|
@ -810,22 +805,14 @@ expr_list_eq(struct apfl_expr_list a, struct apfl_expr_list b)
|
|||
}
|
||||
|
||||
static bool
|
||||
body_eq(struct apfl_expr_body *a, struct apfl_expr_body *b)
|
||||
body_eq(struct apfl_expr_body a, struct apfl_expr_body b)
|
||||
{
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a == NULL || b == NULL) {
|
||||
if (a.len != b.len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a->len != b->len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < a->len; i++) {
|
||||
if (!apfl_expr_eq(a->items[i], b->items[i])) {
|
||||
for (size_t i = 0; i < a.len; i++) {
|
||||
if (!apfl_expr_eq(a.items[i], b.items[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,3 @@ apfl_print_indented(unsigned indent, FILE *f, const char* fmt, ...)
|
|||
vfprintf(f, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
bool
|
||||
apfl_refcount_dec(unsigned *rc)
|
||||
{
|
||||
if (rc == NULL) {
|
||||
return false;
|
||||
}
|
||||
return --(*rc) == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,10 +87,6 @@ do { \
|
|||
|
||||
void apfl_print_indented(unsigned indent, FILE *, const char* fmt, ...);
|
||||
|
||||
/* Decrease a refererence count. Returns true, if the object should be freed.
|
||||
*/
|
||||
bool apfl_refcount_dec(unsigned *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
40
src/parser.c
40
src/parser.c
|
|
@ -1777,20 +1777,14 @@ error:
|
|||
return PF_ERROR;
|
||||
}
|
||||
|
||||
static bool
|
||||
init_body(apfl_parser_ptr p, struct apfl_expr_body **body)
|
||||
static struct apfl_expr_body
|
||||
init_body(void)
|
||||
{
|
||||
if ((*body = ALLOC_OBJ(p->allocator, struct apfl_expr_body)) == NULL) {
|
||||
p->error = apfl_error_simple(APFL_ERR_MALLOC_FAILED);
|
||||
return false;
|
||||
}
|
||||
**body = (struct apfl_expr_body) {
|
||||
return (struct apfl_expr_body) {
|
||||
.items = NULL,
|
||||
.len = 0,
|
||||
.cap = 0,
|
||||
.refcount = 1,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1812,17 +1806,7 @@ parse_braces(
|
|||
struct fragment_list fragments;
|
||||
apfl_resizable_init(APFL_RESIZABLE_ARGS(fragments, children));
|
||||
|
||||
struct apfl_expr_body *body;
|
||||
if (!init_body(p, &body)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*body = (struct apfl_expr_body) {
|
||||
.items = NULL,
|
||||
.len = 0,
|
||||
.cap = 0,
|
||||
.refcount = 1,
|
||||
};
|
||||
struct apfl_expr_body body = init_body();
|
||||
|
||||
for (;;) {
|
||||
struct apfl_expr expr;
|
||||
|
|
@ -1838,9 +1822,9 @@ parse_braces(
|
|||
if (!apfl_resizable_append(
|
||||
p->allocator,
|
||||
sizeof(struct apfl_expr),
|
||||
(void **)&body->items,
|
||||
&body->len,
|
||||
&body->cap,
|
||||
(void **)&body.items,
|
||||
&body.len,
|
||||
&body.cap,
|
||||
&expr,
|
||||
1
|
||||
)) {
|
||||
|
|
@ -1883,7 +1867,7 @@ parse_braces(
|
|||
|
||||
params = (struct apfl_expr_params) { .params = NULL, .len = 0, .cap = 0 };
|
||||
|
||||
body = NULL;
|
||||
body = init_body();
|
||||
}
|
||||
|
||||
out->type = FRAG_EXPR;
|
||||
|
|
@ -1903,7 +1887,7 @@ parse_braces(
|
|||
|
||||
return true;
|
||||
case APFL_TOK_MAPSTO:
|
||||
if (body->len > 0 && !has_params) {
|
||||
if (body.len > 0 && !has_params) {
|
||||
p->error = (struct apfl_error) {
|
||||
.type = APFL_ERR_STATEMENTS_BEFORE_PARAMETERS,
|
||||
.position = p->token.position,
|
||||
|
|
@ -1930,9 +1914,7 @@ parse_braces(
|
|||
}
|
||||
|
||||
params = (struct apfl_expr_params) { .params = NULL, .len = 0, .cap = 0 };
|
||||
if (!init_body(p, &body)) {
|
||||
goto error;
|
||||
}
|
||||
body = init_body();
|
||||
}
|
||||
|
||||
if (!fragments_to_params(p, fragment_list_move(&fragments), ¶ms)) {
|
||||
|
|
@ -1951,7 +1933,7 @@ parse_braces(
|
|||
}
|
||||
|
||||
error:
|
||||
apfl_expr_body_unref(p->allocator, body);
|
||||
apfl_expr_body_deinit(p->allocator, &body);
|
||||
apfl_expr_params_deinit(p->allocator, ¶ms);
|
||||
fragment_list_deinit(p->allocator, &fragments);
|
||||
apfl_expr_complex_func_deinit(p->allocator, &complex_func);
|
||||
|
|
|
|||
|
|
@ -159,22 +159,6 @@ params_item(bool expand, struct apfl_expr_param param)
|
|||
};
|
||||
}
|
||||
|
||||
struct test_pre_body {
|
||||
struct apfl_expr *items;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static struct apfl_expr_body *
|
||||
create_body(struct parser_test *pt, struct test_pre_body pre_body)
|
||||
{
|
||||
struct apfl_expr_body *body = ALLOC_OBJ(pt->allocator, struct apfl_expr_body);
|
||||
body->items = pre_body.items;
|
||||
body->len = pre_body.len;
|
||||
body->cap = pre_body.len;
|
||||
body->refcount = 1;
|
||||
return body;
|
||||
}
|
||||
|
||||
// Fugly macros to make it a bit easier to create a heap allocated struct value
|
||||
#define BEGIN_NEW(pt, T) ((T *)new_helper(pt, sizeof(T), &((T)
|
||||
#define END_NEW )))
|
||||
|
|
@ -244,7 +228,7 @@ enum listbuilder_cmd {
|
|||
#define LIST_ADD }, {.has_item = true, .item =
|
||||
|
||||
MKLISTBUILDER(list, struct apfl_expr_list, struct apfl_expr_list_item, items)
|
||||
MKLISTBUILDER(body, struct test_pre_body, struct apfl_expr, items)
|
||||
MKCAPLISTBUILDER(body, struct apfl_expr_body, struct apfl_expr, items)
|
||||
MKCAPLISTBUILDER(dict, struct apfl_expr_dict, struct apfl_expr_dict_pair, items)
|
||||
MKCAPLISTBUILDER(complex_func, struct apfl_expr_complex_func, struct apfl_expr_subfunc, subfuncs)
|
||||
MKCAPLISTBUILDER(params, struct apfl_expr_params, struct apfl_expr_params_item, params)
|
||||
|
|
@ -382,8 +366,8 @@ TEST(empty_function, t) {
|
|||
expect_expr(pt, (struct apfl_expr) {
|
||||
.type = APFL_EXPR_SIMPLE_FUNC,
|
||||
.position = POS(1, 1),
|
||||
.simple_func = create_body(pt, LIST_BEGIN(pt, body)
|
||||
LIST_END),
|
||||
.simple_func = LIST_BEGIN(pt, body)
|
||||
LIST_END,
|
||||
});
|
||||
expect_eof(pt);
|
||||
destroy_parser_test(pt);
|
||||
|
|
@ -591,9 +575,9 @@ TEST(factorial, t) {
|
|||
.constant = num_const(0),
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD const_expr(2, 10, num_const(1)),
|
||||
LIST_END)
|
||||
LIST_END
|
||||
},
|
||||
LIST_ADD (struct apfl_expr_subfunc) {
|
||||
.params = LIST_BEGIN(pt, params)
|
||||
|
|
@ -602,7 +586,7 @@ TEST(factorial, t) {
|
|||
.var = new_string(pt, "n"),
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD (struct apfl_expr) {
|
||||
.type = APFL_EXPR_CALL,
|
||||
.position = POS(3, 10),
|
||||
|
|
@ -634,7 +618,7 @@ TEST(factorial, t) {
|
|||
LIST_END,
|
||||
},
|
||||
},
|
||||
LIST_END)
|
||||
LIST_END
|
||||
},
|
||||
LIST_END
|
||||
} END_NEW
|
||||
|
|
@ -686,14 +670,14 @@ TEST(map, t) {
|
|||
LIST_END,
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD (struct apfl_expr) {
|
||||
.type = APFL_EXPR_LIST,
|
||||
.position = POS(2, 9),
|
||||
.list = LIST_BEGIN(pt, list)
|
||||
LIST_END,
|
||||
},
|
||||
LIST_END),
|
||||
LIST_END,
|
||||
},
|
||||
LIST_ADD (struct apfl_expr_subfunc) {
|
||||
.params = LIST_BEGIN(pt, params)
|
||||
|
|
@ -715,7 +699,7 @@ TEST(map, t) {
|
|||
LIST_END,
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD (struct apfl_expr) {
|
||||
.type = APFL_EXPR_LIST,
|
||||
.position = POS(4, 5),
|
||||
|
|
@ -743,7 +727,7 @@ TEST(map, t) {
|
|||
} END_NEW),
|
||||
LIST_END,
|
||||
},
|
||||
LIST_END)
|
||||
LIST_END
|
||||
},
|
||||
LIST_END,
|
||||
} END_NEW,
|
||||
|
|
@ -1020,12 +1004,12 @@ TEST(simple_function, t) {
|
|||
expect_expr(pt, (struct apfl_expr) {
|
||||
.type = APFL_EXPR_SIMPLE_FUNC,
|
||||
.position = POS(1, 1),
|
||||
.simple_func = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.simple_func = LIST_BEGIN(pt, body)
|
||||
LIST_ADD (struct apfl_expr) {
|
||||
.type = APFL_EXPR_SIMPLE_FUNC,
|
||||
.position = POS(1, 2),
|
||||
.simple_func = create_body(pt, LIST_BEGIN(pt, body)
|
||||
LIST_END),
|
||||
.simple_func = LIST_BEGIN(pt, body)
|
||||
LIST_END,
|
||||
},
|
||||
LIST_ADD (struct apfl_expr) {
|
||||
.type = APFL_EXPR_CALL,
|
||||
|
|
@ -1037,7 +1021,7 @@ TEST(simple_function, t) {
|
|||
LIST_ADD list_item(false, BEGIN_NEW(pt, struct apfl_expr) {
|
||||
.type = APFL_EXPR_SIMPLE_FUNC,
|
||||
.position = POS(3, 5),
|
||||
.simple_func = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.simple_func = LIST_BEGIN(pt, body)
|
||||
LIST_ADD (struct apfl_expr) {
|
||||
.type = APFL_EXPR_ASSIGNMENT,
|
||||
.position = POS(4, 9),
|
||||
|
|
@ -1049,13 +1033,13 @@ TEST(simple_function, t) {
|
|||
},
|
||||
LIST_ADD var(pt, 5, 5, "a"),
|
||||
LIST_ADD var(pt, 6, 5, "b"),
|
||||
LIST_END),
|
||||
LIST_END,
|
||||
} END_NEW),
|
||||
LIST_END,
|
||||
},
|
||||
},
|
||||
LIST_ADD var(pt, 7, 4, "c"),
|
||||
LIST_END),
|
||||
LIST_END,
|
||||
});
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
|
@ -1113,11 +1097,11 @@ TEST(complex_function, t) {
|
|||
},
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD var(pt, 1, 21, "foo"),
|
||||
LIST_ADD var(pt, 1, 26, "bar"),
|
||||
LIST_ADD var(pt, 2, 5, "baz"),
|
||||
LIST_END),
|
||||
LIST_END,
|
||||
},
|
||||
LIST_ADD {
|
||||
.params = LIST_BEGIN(pt, params)
|
||||
|
|
@ -1131,8 +1115,8 @@ TEST(complex_function, t) {
|
|||
LIST_END,
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
LIST_END),
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_END,
|
||||
},
|
||||
LIST_ADD {
|
||||
.params = LIST_BEGIN(pt, params)
|
||||
|
|
@ -1160,7 +1144,7 @@ TEST(complex_function, t) {
|
|||
LIST_END
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD var(pt, 4, 5, "a"),
|
||||
LIST_ADD var(pt, 5, 5, "b"),
|
||||
LIST_ADD {
|
||||
|
|
@ -1180,16 +1164,16 @@ TEST(complex_function, t) {
|
|||
.var = new_string(pt, "x"),
|
||||
}),
|
||||
LIST_END,
|
||||
.body = create_body(pt, LIST_BEGIN(pt, body)
|
||||
.body = LIST_BEGIN(pt, body)
|
||||
LIST_ADD var(pt, 6, 14, "y"),
|
||||
LIST_END),
|
||||
LIST_END,
|
||||
}
|
||||
LIST_END
|
||||
} END_NEW),
|
||||
LIST_END,
|
||||
},
|
||||
}
|
||||
LIST_END),
|
||||
LIST_END,
|
||||
},
|
||||
LIST_END,
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue