]> Repositorios git - scryer-prolog.git/commitdiff
add missing cases to retract_clause (#1214)
authorMark Thom <[email protected]>
Sat, 15 Jan 2022 07:51:38 +0000 (00:51 -0700)
committerMark Thom <[email protected]>
Sat, 15 Jan 2022 07:51:38 +0000 (00:51 -0700)
src/machine/compile.rs

index 180a2b9db776bde2fe594f0f77490331563d2fd5..b8ffdcf220ed20c175ee13caed6a81c65ee0fb05 100644 (file)
@@ -235,19 +235,20 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
                     index = index_loc;
                 }
             }
-            &Instruction::DynamicElse(_, _, next_or_fail) => match next_or_fail
-            {
-                NextOrFail::Next(i) => {
-                    if i == 0 {
+            &Instruction::DynamicElse(_, _, next_or_fail) => {
+                match next_or_fail {
+                    NextOrFail::Next(i) => {
+                        if i == 0 {
+                            index = index_loc;
+                        } else {
+                            return index;
+                        }
+                    }
+                    NextOrFail::Fail(_) => {
                         index = index_loc;
-                    } else {
-                        return index;
                     }
                 }
-                NextOrFail::Fail(_) => {
-                    index = index_loc;
-                }
-            },
+            }
             &Instruction::DynamicInternalElse(_, _, next_or_fail) => {
                 match next_or_fail {
                     NextOrFail::Next(i) => {
@@ -1173,7 +1174,6 @@ fn append_compiled_clause(
     {
         Some(index_loc) if lower_bound_arg_num == target_arg_num => {
             code.push(settings.internal_trust_me());
-
             code.extend(clause_code.drain(3..)); // skip the indexing code
 
             // 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 code_index = self.get_or_insert_code_index(key, payload_compilation_target);
 
-        let skeleton = match self
+        let skeleton = self
             .wam_prelude
             .indices
             .get_predicate_skeleton_mut(&payload_compilation_target, &key)
-        {
-            Some(skeleton) => skeleton,
-            None => {
-                unreachable!();
-            }
-        };
+            .unwrap();
 
         let code = &mut self.wam_prelude.code;
         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();
 
         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
-            // OptArgIndexKey::None.
+            // the clause preceding target_pos, if there is one, is of
+            // key type OptArgIndexKey::None.
             match skeleton.clauses[target_pos]
                 .opt_arg_index_key
                 .switch_on_term_loc()
@@ -2024,29 +2019,91 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
                         .switch_on_term_loc()
                     {
                         Some(index_loc) => {
-                            let preceding_choice_instr_loc = find_inner_choice_instr(
+                            let clause_start = find_inner_choice_instr(
                                 code,
-                                skeleton.clauses[target_pos - 1].clause_start,
+                                skeleton.clauses[target_pos].clause_start,
                                 index_loc,
                             );
 
-                            remove_non_leading_clause(
-                                code,
-                                preceding_choice_instr_loc,
-                                skeleton.clauses[target_pos].clause_start,
-                                &mut self.payload.retraction_info,
-                            );
+                            let lower_bound_clause_start = skeleton.clauses[lower_bound].clause_start;
+                            let preceding_choice_instr_loc;
 
-                            match &mut code[preceding_choice_instr_loc] {
+                            match &mut code[clause_start] {
                                 Instruction::TryMeElse(0) => {
+                                    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,
+                                        preceding_choice_instr_loc,
+                                        skeleton.clauses[target_pos].clause_start - 2,
+                                        &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,
-                                        preceding_choice_instr_loc + 1 - 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