add missing cases to retract_clause (#1214)
This commit is contained in:
@@ -235,19 +235,20 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
|
|||||||
index = index_loc;
|
index = index_loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DynamicElse(_, _, next_or_fail) => match next_or_fail
|
&Instruction::DynamicElse(_, _, next_or_fail) => {
|
||||||
{
|
match next_or_fail {
|
||||||
NextOrFail::Next(i) => {
|
NextOrFail::Next(i) => {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
index = index_loc;
|
||||||
|
} else {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NextOrFail::Fail(_) => {
|
||||||
index = index_loc;
|
index = index_loc;
|
||||||
} else {
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NextOrFail::Fail(_) => {
|
}
|
||||||
index = index_loc;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
&Instruction::DynamicInternalElse(_, _, next_or_fail) => {
|
&Instruction::DynamicInternalElse(_, _, next_or_fail) => {
|
||||||
match next_or_fail {
|
match next_or_fail {
|
||||||
NextOrFail::Next(i) => {
|
NextOrFail::Next(i) => {
|
||||||
@@ -1173,7 +1174,6 @@ fn append_compiled_clause(
|
|||||||
{
|
{
|
||||||
Some(index_loc) if lower_bound_arg_num == target_arg_num => {
|
Some(index_loc) if lower_bound_arg_num == target_arg_num => {
|
||||||
code.push(settings.internal_trust_me());
|
code.push(settings.internal_trust_me());
|
||||||
|
|
||||||
code.extend(clause_code.drain(3..)); // skip the indexing code
|
code.extend(clause_code.drain(3..)); // skip the indexing code
|
||||||
|
|
||||||
// set skeleton[target_pos].opt_arg_index_key to
|
// set skeleton[target_pos].opt_arg_index_key to
|
||||||
@@ -1796,24 +1796,19 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let payload_compilation_target = self.payload.compilation_target;
|
let payload_compilation_target = self.payload.compilation_target;
|
||||||
let code_index = self.get_or_insert_code_index(key, payload_compilation_target);
|
let code_index = self.get_or_insert_code_index(key, payload_compilation_target);
|
||||||
|
|
||||||
let skeleton = match self
|
let skeleton = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&payload_compilation_target, &key)
|
.get_predicate_skeleton_mut(&payload_compilation_target, &key)
|
||||||
{
|
.unwrap();
|
||||||
Some(skeleton) => skeleton,
|
|
||||||
None => {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let code = &mut self.wam_prelude.code;
|
let code = &mut self.wam_prelude.code;
|
||||||
let lower_bound = lower_bound_of_target_clause(skeleton, target_pos);
|
let lower_bound = lower_bound_of_target_clause(skeleton, target_pos);
|
||||||
let lower_bound_is_unindexed = !skeleton.clauses[lower_bound].opt_arg_index_key.is_some();
|
let lower_bound_is_unindexed = !skeleton.clauses[lower_bound].opt_arg_index_key.is_some();
|
||||||
|
|
||||||
if target_pos == 0 || (lower_bound + 1 == target_pos && lower_bound_is_unindexed) {
|
if target_pos == 0 || (lower_bound + 1 == target_pos && lower_bound_is_unindexed) {
|
||||||
// the clause preceding target_pos, if there is one, is of key type
|
// the clause preceding target_pos, if there is one, is of
|
||||||
// OptArgIndexKey::None.
|
// key type OptArgIndexKey::None.
|
||||||
match skeleton.clauses[target_pos]
|
match skeleton.clauses[target_pos]
|
||||||
.opt_arg_index_key
|
.opt_arg_index_key
|
||||||
.switch_on_term_loc()
|
.switch_on_term_loc()
|
||||||
@@ -2024,29 +2019,91 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
.switch_on_term_loc()
|
.switch_on_term_loc()
|
||||||
{
|
{
|
||||||
Some(index_loc) => {
|
Some(index_loc) => {
|
||||||
let preceding_choice_instr_loc = find_inner_choice_instr(
|
let clause_start = find_inner_choice_instr(
|
||||||
code,
|
code,
|
||||||
skeleton.clauses[target_pos - 1].clause_start,
|
skeleton.clauses[target_pos].clause_start,
|
||||||
index_loc,
|
index_loc,
|
||||||
);
|
);
|
||||||
|
|
||||||
remove_non_leading_clause(
|
let lower_bound_clause_start = skeleton.clauses[lower_bound].clause_start;
|
||||||
code,
|
let preceding_choice_instr_loc;
|
||||||
preceding_choice_instr_loc,
|
|
||||||
skeleton.clauses[target_pos].clause_start,
|
|
||||||
&mut self.payload.retraction_info,
|
|
||||||
);
|
|
||||||
|
|
||||||
match &mut code[preceding_choice_instr_loc] {
|
match &mut code[clause_start] {
|
||||||
Instruction::TryMeElse(0) => {
|
Instruction::TryMeElse(0) => {
|
||||||
set_switch_var_offset(
|
preceding_choice_instr_loc = if skeleton.clauses[lower_bound]
|
||||||
|
.opt_arg_index_key
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
lower_bound_clause_start - 2
|
||||||
|
} else {
|
||||||
|
lower_bound_clause_start
|
||||||
|
};
|
||||||
|
|
||||||
|
remove_non_leading_clause(
|
||||||
code,
|
code,
|
||||||
index_loc,
|
preceding_choice_instr_loc,
|
||||||
preceding_choice_instr_loc + 1 - index_loc,
|
skeleton.clauses[target_pos].clause_start - 2,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {}
|
Instruction::TryMeElse(_) => {
|
||||||
|
let new_target_loc = blunt_leading_choice_instr(
|
||||||
|
code,
|
||||||
|
clause_start,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
|
|
||||||
|
derelictize_try_me_else(
|
||||||
|
code,
|
||||||
|
clause_start,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
|
|
||||||
|
set_switch_var_offset(
|
||||||
|
code,
|
||||||
|
index_loc,
|
||||||
|
new_target_loc - index_loc,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.payload.retraction_info.push_record(
|
||||||
|
RetractionRecord::SkeletonClauseStartReplaced(
|
||||||
|
payload_compilation_target,
|
||||||
|
key,
|
||||||
|
target_pos + 1,
|
||||||
|
skeleton.clauses[target_pos + 1].clause_start,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
skeleton.clauses[target_pos + 1].clause_start =
|
||||||
|
skeleton.clauses[target_pos].clause_start;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
preceding_choice_instr_loc = find_inner_choice_instr(
|
||||||
|
code,
|
||||||
|
skeleton.clauses[target_pos - 1].clause_start,
|
||||||
|
index_loc,
|
||||||
|
);
|
||||||
|
|
||||||
|
remove_non_leading_clause(
|
||||||
|
code,
|
||||||
|
preceding_choice_instr_loc,
|
||||||
|
skeleton.clauses[target_pos].clause_start,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
|
|
||||||
|
match &mut code[preceding_choice_instr_loc] {
|
||||||
|
Instruction::TryMeElse(0) => {
|
||||||
|
set_switch_var_offset(
|
||||||
|
code,
|
||||||
|
index_loc,
|
||||||
|
preceding_choice_instr_loc + 1 - index_loc,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
|||||||
Reference in New Issue
Block a user