]> Repositorios git - scryer-prolog.git/commitdiff
correct assertz/1 bugs (#922)
authorMark Thom <[email protected]>
Tue, 4 May 2021 23:53:02 +0000 (17:53 -0600)
committerMark Thom <[email protected]>
Tue, 4 May 2021 23:53:02 +0000 (17:53 -0600)
src/machine/compile.rs

index bb09fcda4a3e1f275865bc178675e72ace25e2b4..e88dc605e1161e688ea6ec6fd541856fc3627cd6 100644 (file)
@@ -224,8 +224,20 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
                     index = index_loc;
                 }
             }
-            &Line::Choice(ChoiceInstruction::DynamicElse(_, _, next_or_fail))
-            | &Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, next_or_fail)) => {
+            &Line::Choice(ChoiceInstruction::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;
+                }
+            },
+            &Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, next_or_fail)) => {
                 match next_or_fail {
                     NextOrFail::Next(i) => {
                         if i == 0 {
@@ -656,16 +668,12 @@ fn thread_choice_instr_at_to(
                 *o = target_loc - instr_loc;
                 return;
             }
-            Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)))
-            | Line::Choice(ChoiceInstruction::DynamicInternalElse(
-                _,
-                _,
-                NextOrFail::Next(ref mut o),
-            )) => {
+            Line::Choice(ChoiceInstruction::DynamicElse(_, _, NextOrFail::Next(o)))
+            | Line::Choice(ChoiceInstruction::DynamicInternalElse(_, _, NextOrFail::Next(o))) => {
                 instr_loc += *o;
             }
-            Line::Choice(ChoiceInstruction::TryMeElse(ref mut o))
-            | Line::Choice(ChoiceInstruction::RetryMeElse(ref mut o)) => {
+            Line::Choice(ChoiceInstruction::TryMeElse(o))
+            | Line::Choice(ChoiceInstruction::RetryMeElse(o)) => {
                 instr_loc += *o;
             }
             Line::Control(ControlInstruction::RevJmpBy(ref mut o)) if instr_loc >= target_loc => {
@@ -725,6 +733,12 @@ fn thread_choice_instr_at_to(
                 instr_loc += *o;
             }
             _ => {
+                println!("failing code: \n");
+
+                for index in instr_loc - 40..instr_loc + 40 {
+                    println!("{:07} | {}", index, code[index]);
+                }
+
                 unreachable!()
             }
         }
@@ -1224,6 +1238,23 @@ fn append_compiled_clause(
             skeleton.clauses[target_pos].opt_arg_index_key += clause_loc;
             code.extend(clause_code.drain(1..));
 
+            match skeleton.clauses[target_pos]
+                .opt_arg_index_key
+                .switch_on_term_loc()
+            {
+                Some(index_loc) => {
+                    // point to the inner-threaded TryMeElse(0) if target_pos is
+                    // indexed, and make switch_on_term point one line after it in
+                    // its variable offset.
+                    skeleton.clauses[target_pos].clause_start += 2;
+
+                    if !skeleton.core.is_dynamic {
+                        set_switch_var_offset(code, index_loc, 2, retraction_info);
+                    }
+                }
+                None => {}
+            }
+
             match skeleton.clauses[lower_bound]
                 .opt_arg_index_key
                 .switch_on_term_loc()
@@ -1240,23 +1271,6 @@ fn append_compiled_clause(
                         code_ptr_opt = Some(skeleton.clauses[lower_bound].clause_start);
                     }
 
-                    match skeleton.clauses[target_pos]
-                        .opt_arg_index_key
-                        .switch_on_term_loc()
-                    {
-                        Some(index_loc) => {
-                            // point to the inner-threaded TryMeElse(0) if target_pos is
-                            // indexed, and make switch_on_term point one line after it in
-                            // its variable offset.
-                            skeleton.clauses[target_pos].clause_start += 2;
-
-                            if !skeleton.core.is_dynamic {
-                                set_switch_var_offset(code, index_loc, 2, retraction_info);
-                            }
-                        }
-                        None => {}
-                    }
-
                     find_outer_choice_instr(code, skeleton.clauses[lower_bound].clause_start)
                 }
             }