compile: Move milist into compile_assignable_ilists

This makes the function signatures a bit smaller.
This commit is contained in:
Laria 2022-08-04 22:25:04 +02:00
parent 9b84a52f77
commit a160dea021

View file

@ -303,10 +303,28 @@ tmp_ilist(struct compiler *compiler, int line)
return ilist;
}
static struct matcher_instruction_list *
tmp_milist(struct compiler *compiler)
{
struct matcher_instruction_list *milist;
if (
(milist = apfl_matcher_instructions_new(compiler->gc)) == NULL
|| !apfl_gc_tmproot_add(
compiler->gc,
GC_OBJECT_FROM(milist, GC_TYPE_MATCHER_INSTRUCTIONS)
)
) {
return NULL;
}
return milist;
}
struct compile_assignable_ilists {
struct instruction_list *prelude;
struct instruction_list *newvars;
struct instruction_list *setvars;
struct matcher_instruction_list *matcher;
};
static bool
@ -315,7 +333,6 @@ compile_assignable(
bool local,
struct apfl_position position,
struct apfl_expr_assignable *assignable,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists
);
@ -324,10 +341,9 @@ compile_assignable_var_or_member(
struct compiler *compiler,
bool local,
struct apfl_expr_assignable_var_or_member *var_or_member,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists
) {
size_t index = milist->capture_count++;
size_t index = ilists.matcher->capture_count++;
if (var_or_member->type != APFL_EXPR_ASSIGNABLE_VAR_OR_MEMBER_VAR) {
compiler->error = apfl_error_simple(APFL_ERR_NOT_IMPLEMENTED); // TODO: Implement me
@ -346,9 +362,9 @@ compile_assignable_var_or_member(
* }
*/
TRY(milist_ensure_cap(compiler, milist, 2));
milist_put_insn(milist, MATCHER_CAPTURE);
milist_put_index(milist, index);
TRY(milist_ensure_cap(compiler, ilists.matcher, 2));
milist_put_insn(ilists.matcher, MATCHER_CAPTURE);
milist_put_index(ilists.matcher, index);
TRY(ilist_ensure_cap(compiler, ilists.newvars, 2));
@ -370,20 +386,19 @@ static bool
compile_assignable_constant(
struct compiler *compiler,
struct apfl_expr_const *constant,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists
) {
size_t index = milist->value_count++;
size_t index = ilists.matcher->value_count++;
TRY(compile_constant(compiler, constant, ilists.prelude));
TRY(ilist_ensure_cap(compiler, ilists.prelude, 2));
ilist_put_insn(ilists.prelude, INSN_MATCHER_SET_VAL);
ilist_put_index(ilists.prelude, index);
TRY(milist_ensure_cap(compiler, milist, 3));
milist_put_insn(milist, MATCHER_CHECK_CONST);
milist_put_index(milist, index);
milist_put_insn(milist, MATCHER_IGNORE);
TRY(milist_ensure_cap(compiler, ilists.matcher, 3));
milist_put_insn(ilists.matcher, MATCHER_CHECK_CONST);
milist_put_index(ilists.matcher, index);
milist_put_insn(ilists.matcher, MATCHER_IGNORE);
return true;
}
@ -394,21 +409,20 @@ compile_assignable_predicate(
bool local,
struct apfl_position position,
struct apfl_expr_assignable_predicate *predicate,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists
) {
size_t index = milist->value_count++;
size_t index = ilists.matcher->value_count++;
TRY(compile_expr(compiler, predicate->rhs, ilists.prelude));
TRY(ilist_ensure_cap(compiler, ilists.prelude, 2));
ilist_put_insn(ilists.prelude, INSN_MATCHER_SET_VAL);
ilist_put_index(ilists.prelude, index);
TRY(milist_ensure_cap(compiler, milist, 2));
milist_put_insn(milist, MATCHER_CHECK_PRED);
milist_put_index(milist, index);
TRY(milist_ensure_cap(compiler, ilists.matcher, 2));
milist_put_insn(ilists.matcher, MATCHER_CHECK_PRED);
milist_put_index(ilists.matcher, index);
return compile_assignable(compiler, local, position, predicate->lhs, milist, ilists);
return compile_assignable(compiler, local, position, predicate->lhs, ilists);
}
static bool
@ -417,7 +431,6 @@ compile_assignable_list_expand(
bool local,
struct apfl_position position,
struct apfl_expr_assignable_list *list,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists,
size_t expand_at
) {
@ -425,8 +438,8 @@ compile_assignable_list_expand(
struct apfl_expr_assignable_list_item *expand_item = &list->items[expand_at];
assert(expand_item->expand);
TRY(milist_ensure_cap(compiler, milist, 1));
milist_put_insn(milist, MATCHER_CONTINUE_FROM_END);
TRY(milist_ensure_cap(compiler, ilists.matcher, 1));
milist_put_insn(ilists.matcher, MATCHER_CONTINUE_FROM_END);
for (size_t i = list->len; i-- > expand_at+1; ) {
struct apfl_expr_assignable_list_item *item = &list->items[i];
@ -439,13 +452,13 @@ compile_assignable_list_expand(
return false;
}
TRY(compile_assignable(compiler, local, position, &item->assignable, milist, ilists));
TRY(compile_assignable(compiler, local, position, &item->assignable, ilists));
}
TRY(milist_ensure_cap(compiler, milist, 1));
milist_put_insn(milist, MATCHER_REMAINDING);
TRY(milist_ensure_cap(compiler, ilists.matcher, 1));
milist_put_insn(ilists.matcher, MATCHER_REMAINDING);
TRY(compile_assignable(compiler, local, position, &expand_item->assignable, milist, ilists));
TRY(compile_assignable(compiler, local, position, &expand_item->assignable, ilists));
return true;
}
@ -456,11 +469,10 @@ compile_assignable_list(
bool local,
struct apfl_position position,
struct apfl_expr_assignable_list *list,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists
) {
TRY(milist_ensure_cap(compiler, milist, 1));
milist_put_insn(milist, MATCHER_ENTER_LIST);
TRY(milist_ensure_cap(compiler, ilists.matcher, 1));
milist_put_insn(ilists.matcher, MATCHER_ENTER_LIST);
for (size_t i = 0; i < list->len; i++) {
struct apfl_expr_assignable_list_item *item = &list->items[i];
@ -471,17 +483,16 @@ compile_assignable_list(
local,
position,
list,
milist,
ilists,
i
);
}
TRY(compile_assignable(compiler, local, position, &item->assignable, milist, ilists));
TRY(compile_assignable(compiler, local, position, &item->assignable, ilists));
}
TRY(milist_ensure_cap(compiler, milist, 1));
milist_put_insn(milist, MATCHER_LEAVE_LIST);
TRY(milist_ensure_cap(compiler, ilists.matcher, 1));
milist_put_insn(ilists.matcher, MATCHER_LEAVE_LIST);
return true;
}
@ -491,21 +502,20 @@ compile_assignable(
bool local,
struct apfl_position position,
struct apfl_expr_assignable *assignable,
struct matcher_instruction_list *milist,
struct compile_assignable_ilists ilists
) {
switch (assignable->type) {
case APFL_EXPR_ASSIGNABLE_VAR_OR_MEMBER:
return compile_assignable_var_or_member(compiler, local, &assignable->var_or_member, milist, ilists);
return compile_assignable_var_or_member(compiler, local, &assignable->var_or_member, ilists);
case APFL_EXPR_ASSIGNABLE_CONSTANT:
return compile_assignable_constant(compiler, &assignable->constant, milist, ilists);
return compile_assignable_constant(compiler, &assignable->constant, ilists);
case APFL_EXPR_ASSIGNABLE_PREDICATE:
return compile_assignable_predicate(compiler, local, position, &assignable->predicate, milist, ilists);
return compile_assignable_predicate(compiler, local, position, &assignable->predicate, ilists);
case APFL_EXPR_ASSIGNABLE_LIST:
return compile_assignable_list(compiler, local, position, &assignable->list, milist, ilists);
return compile_assignable_list(compiler, local, position, &assignable->list, ilists);
case APFL_EXPR_ASSIGNABLE_BLANK:
TRY(milist_ensure_cap(compiler, milist, 1));
milist_put_insn(milist, MATCHER_IGNORE);
TRY(milist_ensure_cap(compiler, ilists.matcher, 1));
milist_put_insn(ilists.matcher, MATCHER_IGNORE);
return true;
}
@ -547,23 +557,18 @@ compile_complex_assignment(
TRY(ilist_ensure_cap(compiler, ilist, 2));
struct matcher_instruction_list *milist;
if ((milist = apfl_matcher_instructions_new(compiler->gc)) == NULL) {
compiler->error = apfl_error_simple(APFL_ERR_MALLOC_FAILED);
return false;
}
ilist_put_insn(ilist, INSN_MATCHER_LOAD);
ilist_put_matcher(ilist, milist);
struct compile_assignable_ilists ilists = {
.prelude = ilist,
};
MALLOC_FAIL_IF_NULL(compiler, (ilists.matcher = tmp_milist(compiler)));
MALLOC_FAIL_IF_NULL(compiler, (ilists.newvars = tmp_ilist(compiler, position.line)));
MALLOC_FAIL_IF_NULL(compiler, (ilists.setvars = tmp_ilist(compiler, position.line)));
TRY(compile_assignable(compiler, assignment->local, position, &assignment->lhs, milist, ilists));
ilist_put_insn(ilist, INSN_MATCHER_LOAD);
ilist_put_matcher(ilist, ilists.matcher);
TRY(compile_assignable(compiler, assignment->local, position, &assignment->lhs, ilists));
TRY(concat_ilists(compiler, ilist, ilists.newvars));