compile: Move milist into compile_assignable_ilists
This makes the function signatures a bit smaller.
This commit is contained in:
parent
9b84a52f77
commit
a160dea021
1 changed files with 54 additions and 49 deletions
103
src/compile.c
103
src/compile.c
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue