From: Mark Thom Date: Sat, 17 Feb 2018 05:18:17 +0000 (-0700) Subject: fix compile_seq, variable printing on standalone inlines. X-Git-Tag: v0.8.110~562 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=61bc5a2a2954f954a2233181fd9a3d36e5078978;p=scryer-prolog.git fix compile_seq, variable printing on standalone inlines. --- diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index a6624592..6be24510 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -874,6 +874,8 @@ pub enum ArithmeticInstruction { pub enum BuiltInInstruction { CleanUpBlock, + CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm), + DynamicCompareNumber(CompareNumberQT), EraseBall, Fail, GetArgCall, @@ -884,6 +886,14 @@ pub enum BuiltInInstruction { InstallCleaner, InstallNewBlock, InternalCallN, + IsAtomic(RegType), + IsCompound(RegType), + IsFloat(RegType), + IsInteger(RegType), + IsNonVar(RegType), + IsRational(RegType), + IsString(RegType), + IsVar(RegType), ResetBlock, RestoreCutPolicy, SetBall, @@ -902,16 +912,14 @@ pub enum ControlInstruction { CallN(usize), // arity. CatchCall, CatchExecute, - CheckCpExecute, - CompareNumber(CompareNumberQT, ArithmeticTerm, ArithmeticTerm), + CheckCpExecute, CompareTermCall(CompareTermQT), CompareTermExecute(CompareTermQT), DisplayCall, DisplayExecute, Deallocate, DuplicateTermCall, - DuplicateTermExecute, - DynamicCompareNumber(CompareNumberQT), + DuplicateTermExecute, DynamicIs, EqCall, EqExecute, @@ -926,15 +934,7 @@ pub enum ControlInstruction { GroundExecute, JmpByCall(usize, usize), // arity, global_offset. JmpByExecute(usize, usize), - IsCall(RegType, ArithmeticTerm), - IsAtomic(RegType), - IsCompound(RegType), - IsFloat(RegType), - IsInteger(RegType), - IsNonVar(RegType), - IsRational(RegType), - IsString(RegType), - IsVar(RegType), + IsCall(RegType, ArithmeticTerm), IsExecute(RegType, ArithmeticTerm), NotEqCall, NotEqExecute, @@ -950,15 +950,13 @@ impl ControlInstruction { &ControlInstruction::ArgExecute => true, &ControlInstruction::Call(_, _, _) => true, &ControlInstruction::CatchCall => true, - &ControlInstruction::CatchExecute => true, - &ControlInstruction::CompareNumber(..) => true, + &ControlInstruction::CatchExecute => true, &ControlInstruction::CompareTermCall(..) => true, &ControlInstruction::CompareTermExecute(..) => true, &ControlInstruction::DisplayCall => true, &ControlInstruction::DisplayExecute => true, &ControlInstruction::DuplicateTermCall => true, &ControlInstruction::DuplicateTermExecute => true, - &ControlInstruction::DynamicCompareNumber(_) => true, &ControlInstruction::DynamicIs => true, &ControlInstruction::EqCall => true, &ControlInstruction::EqExecute => true, @@ -976,14 +974,6 @@ impl ControlInstruction { &ControlInstruction::GotoExecute(..) => true, &ControlInstruction::GroundCall => true, &ControlInstruction::GroundExecute => true, - &ControlInstruction::IsAtomic(_) => true, - &ControlInstruction::IsCompound(_) => true, - &ControlInstruction::IsFloat(_) => true, - &ControlInstruction::IsInteger(_) => true, - &ControlInstruction::IsNonVar(_) => true, - &ControlInstruction::IsRational(_) => true, - &ControlInstruction::IsString(_) => true, - &ControlInstruction::IsVar(_) => true, &ControlInstruction::IsCall(..) => true, &ControlInstruction::IsExecute(..) => true, &ControlInstruction::JmpByCall(..) => true, diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index a6c6b673..3e365d86 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -483,13 +483,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> }; match *term { - &QueryTerm::Cut => { + &QueryTerm::Cut => code.push(if chunk_num == 0 { Line::Cut(CutInstruction::NeckCut) } else { Line::Cut(CutInstruction::Cut(perm_v!(1))) - }); - }, + }), &QueryTerm::Is(ref terms) => { let (mut acode, at) = self.call_arith_eval(terms[1].as_ref(), 1)?; code.append(&mut acode); @@ -520,7 +519,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> } }, &QueryTerm::Inlined(ref term) => - self.compile_inlined(term, term_loc, code)?, + try!(self.compile_inlined(term, term_loc, code)), _ => { let num_perm_vars = if chunk_num == 0 { conjunct_info.perm_vars() @@ -530,10 +529,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> self.compile_query_line(term, term_loc, code, num_perm_vars, is_exposed); }, - }; - - self.marker.reset_contents(); + }; } + + self.marker.reset_contents(); } Ok(()) diff --git a/src/prolog/io.rs b/src/prolog/io.rs index 43dbf582..741397b2 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -168,25 +168,9 @@ impl fmt::Display for ControlInstruction { &ControlInstruction::IsCall(r, ref at) => write!(f, "is_call {}, {}", r, at), &ControlInstruction::IsExecute(r, ref at) => - write!(f, "is_execute {}, {}", r, at), - &ControlInstruction::IsAtomic(r) => - write!(f, "is_atomic {}", r), - &ControlInstruction::IsCompound(r) => - write!(f, "is_compound {}", r), - &ControlInstruction::IsFloat(r) => - write!(f, "is_float {}", r), - &ControlInstruction::IsRational(r) => - write!(f, "is_rational {}", r), - &ControlInstruction::IsNonVar(r) => - write!(f, "is_non_var {}", r), - &ControlInstruction::IsString(r) => - write!(f, "is_string {}", r), - &ControlInstruction::IsInteger(r) => - write!(f, "is_integer {}", r), + write!(f, "is_execute {}, {}", r, at), &ControlInstruction::DynamicIs => - write!(f, "call_is"), - &ControlInstruction::IsVar(r) => - write!(f, "is_var {}", r), + write!(f, "call_is"), &ControlInstruction::JmpByCall(arity, offset) => write!(f, "jmp_by_call {}/{}", offset, arity), &ControlInstruction::JmpByExecute(arity, offset) => @@ -200,11 +184,7 @@ impl fmt::Display for ControlInstruction { &ControlInstruction::ThrowCall => write!(f, "call_throw"), &ControlInstruction::ThrowExecute => - write!(f, "execute_throw"), - &ControlInstruction::CompareNumber(cmp, ref at_1, ref at_2) => - write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2), - &ControlInstruction::DynamicCompareNumber(cmp) => - write!(f, "dynamic_number_test {}", cmp), + write!(f, "execute_throw"), } } } @@ -226,7 +206,7 @@ impl fmt::Display for BuiltInInstruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &BuiltInInstruction::CleanUpBlock => - write!(f, "clean_up_block"), + write!(f, "clean_up_block"), &BuiltInInstruction::EraseBall => write!(f, "erase_ball"), &BuiltInInstruction::Fail => @@ -246,7 +226,7 @@ impl fmt::Display for BuiltInInstruction { &BuiltInInstruction::InstallNewBlock => write!(f, "install_new_block"), &BuiltInInstruction::InternalCallN => - write!(f, "internal_call_N"), + write!(f, "internal_call_N"), &BuiltInInstruction::ResetBlock => write!(f, "reset_block"), &BuiltInInstruction::RestoreCutPolicy => @@ -261,6 +241,26 @@ impl fmt::Display for BuiltInInstruction { write!(f, "unwind_stack"), &BuiltInInstruction::Unify => write!(f, "unify"), + &BuiltInInstruction::IsAtomic(r) => + write!(f, "is_atomic {}", r), + &BuiltInInstruction::IsCompound(r) => + write!(f, "is_compound {}", r), + &BuiltInInstruction::IsFloat(r) => + write!(f, "is_float {}", r), + &BuiltInInstruction::IsRational(r) => + write!(f, "is_rational {}", r), + &BuiltInInstruction::IsNonVar(r) => + write!(f, "is_non_var {}", r), + &BuiltInInstruction::IsString(r) => + write!(f, "is_string {}", r), + &BuiltInInstruction::IsInteger(r) => + write!(f, "is_integer {}", r), + &BuiltInInstruction::IsVar(r) => + write!(f, "is_var {}", r), + &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => + write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2), + &BuiltInInstruction::DynamicCompareNumber(cmp) => + write!(f, "dynamic_number_test {}", cmp), } } } diff --git a/src/prolog/lib/lists.rs b/src/prolog/lib/lists.rs index a584848a..0e0df5f0 100644 --- a/src/prolog/lib/lists.rs +++ b/src/prolog/lib/lists.rs @@ -9,7 +9,8 @@ pub static LISTS: &str = "member(X, [X|_]). memberchk(X, Xs) :- member(X, Xs), !. - reverse(Xs, Ys) :- reverse(Xs, [], Ys). + reverse(Xs, Ys) :- var(Ys), !, reverse(Xs, [], Ys). + reverse(Ys, Xs) :- var(Ys), reverse(Xs, [], Ys). reverse([], Ys, Ys). reverse([H|T], Ps, Rs) :- diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 0e797f4c..d1985494 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1270,6 +1270,18 @@ impl MachineState { instr: &BuiltInInstruction) { match instr { + &BuiltInInstruction::CompareNumber(cmp, ref at_1, ref at_2) => { + let n1 = try_or_fail!(self, self.get_number(at_1)); + let n2 = try_or_fail!(self, self.get_number(at_2)); + + self.compare_numbers(cmp, n1, n2); + }, + &BuiltInInstruction::DynamicCompareNumber(cmp) => { + let n1 = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(1))); + let n2 = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(2))); + + self.compare_numbers(cmp, n1, n2); + }, &BuiltInInstruction::GetArgCall => try_or_fail!(self, { let val = self.try_get_arg(); @@ -1339,6 +1351,70 @@ SetupCallCleanupCutPolicy.") self.p += 1; }, + &BuiltInInstruction::IsAtomic(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::Con(_) => self.p += 1, + _ => self.fail = true + }; + }, + &BuiltInInstruction::IsInteger(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::Con(Constant::Number(Number::Integer(_))) => self.p += 1, + _ => self.fail = true + }; + }, + &BuiltInInstruction::IsCompound(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::Str(_) => self.p += 1, + _ => self.fail = true + }; + }, + &BuiltInInstruction::IsFloat(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::Con(Constant::Number(Number::Float(_))) => self.p += 1, + _ => self.fail = true + }; + }, + &BuiltInInstruction::IsRational(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::Con(Constant::Number(Number::Rational(_))) => self.p += 1, + _ => self.fail = true + }; + }, + &BuiltInInstruction::IsString(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::Con(Constant::String(_)) => self.p += 1, + _ => self.fail = true + }; + }, + &BuiltInInstruction::IsNonVar(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true, + _ => self.p += 1 + }; + }, + &BuiltInInstruction::IsVar(r) => { + let d = self.store(self.deref(self[r].clone())); + + match d { + Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1, + _ => self.fail = true + }; + }, &BuiltInInstruction::RestoreCutPolicy => { let restore_default = if let Ok(cut_policy) = cut_policy.downcast_ref::() { @@ -1737,19 +1813,7 @@ SetupCallCleanupCutPolicy.") &ControlInstruction::DuplicateTermExecute => { self.duplicate_term(); self.p = self.cp; - }, - &ControlInstruction::CompareNumber(cmp, ref at_1, ref at_2) => { - let n1 = try_or_fail!(self, self.get_number(at_1)); - let n2 = try_or_fail!(self, self.get_number(at_2)); - - self.compare_numbers(cmp, n1, n2); - }, - &ControlInstruction::DynamicCompareNumber(cmp) => { - let n1 = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(1))); - let n2 = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(2))); - - self.compare_numbers(cmp, n1, n2); - }, + }, &ControlInstruction::DynamicIs => { let a = self[temp_v!(1)].clone(); let result = try_or_fail!(self, self.arith_eval_by_metacall(temp_v!(2))); @@ -1757,70 +1821,6 @@ SetupCallCleanupCutPolicy.") self.unify(a, Addr::Con(Constant::Number(result))); self.p += 1; }, - &ControlInstruction::IsAtomic(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::Con(_) => self.p += 1, - _ => self.fail = true - }; - }, - &ControlInstruction::IsInteger(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::Con(Constant::Number(Number::Integer(_))) => self.p += 1, - _ => self.fail = true - }; - }, - &ControlInstruction::IsCompound(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::Str(_) => self.p += 1, - _ => self.fail = true - }; - }, - &ControlInstruction::IsFloat(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::Con(Constant::Number(Number::Float(_))) => self.p += 1, - _ => self.fail = true - }; - }, - &ControlInstruction::IsRational(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::Con(Constant::Number(Number::Rational(_))) => self.p += 1, - _ => self.fail = true - }; - }, - &ControlInstruction::IsString(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::Con(Constant::String(_)) => self.p += 1, - _ => self.fail = true - }; - }, - &ControlInstruction::IsNonVar(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true, - _ => self.p += 1 - }; - }, - &ControlInstruction::IsVar(r) => { - let d = self.store(self.deref(self[r].clone())); - - match d { - Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1, - _ => self.fail = true - }; - }, &ControlInstruction::EqCall => { self.fail = self.eq_test(); self.p += 1; diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index e3a44b80..9ac9d915 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -46,8 +46,8 @@ impl Machine { pub fn new() -> Self { let atom_tbl = Rc::new(RefCell::new(HashSet::new())); let (code, code_dir, op_dir) = build_code_dir(atom_tbl.clone()); - - + + Machine { ms: MachineState::new(atom_tbl), cut_policy: Box::new(DefaultCutPolicy {}), @@ -121,7 +121,7 @@ impl Machine { self.ms.execute_fact_instr(&fact_instr); } - + self.ms.p += 1; }, &Line::Indexing(ref indexing_instr) => @@ -194,9 +194,11 @@ impl Machine { }, &VarData::Temp(cn, _, _) if cn == chunk_num => { let r = var_data.as_reg_type(); - let addr = self.ms[r].clone(); - - heap_locs.insert(var, addr); + + if r.reg_num() != 0 { + let addr = self.ms[r].clone(); + heap_locs.insert(var, addr); + } }, _ => {} } @@ -205,8 +207,8 @@ impl Machine { fn run_query<'a>(&mut self, alloc_locs: &AllocVarDict<'a>, heap_locs: &mut HeapVarDict<'a>) { - let end_ptr = CodePtr::TopLevel(0, self.cached_query_size()); - + let end_ptr = CodePtr::TopLevel(0, self.cached_query_size()); + while self.ms.p < end_ptr { if let CodePtr::TopLevel(mut cn, p) = self.ms.p { match &self[CodePtr::TopLevel(cn, p)] { @@ -224,7 +226,13 @@ impl Machine { match self.ms.p { CodePtr::TopLevel(_, p) if p > 0 => {}, - _ => break + _ => { + if heap_locs.is_empty() { + self.record_var_places(0, alloc_locs, heap_locs); + } + + break; + } }; } } diff --git a/src/prolog/macros.rs b/src/prolog/macros.rs index 2d892915..d4291667 100644 --- a/src/prolog/macros.rs +++ b/src/prolog/macros.rs @@ -30,7 +30,7 @@ macro_rules! deallocate { macro_rules! compare_number_instr { ($cmp: expr, $at_1: expr, $at_2: expr) => ( - Line::Control(ControlInstruction::CompareNumber($cmp, $at_1, $at_2)) + Line::BuiltIn(BuiltInInstruction::CompareNumber($cmp, $at_1, $at_2)) ) } @@ -158,50 +158,50 @@ macro_rules! retry_me_else { macro_rules! is_atomic { ($reg:expr) => ( - Line::Control(ControlInstruction::IsAtomic($reg)) + Line::BuiltIn(BuiltInInstruction::IsAtomic($reg)) ) } macro_rules! is_integer { ($reg:expr) => ( - Line::Control(ControlInstruction::IsInteger($reg)) + Line::BuiltIn(BuiltInInstruction::IsInteger($reg)) ) } macro_rules! is_compound { ($r:expr) => ( - Line::Control(ControlInstruction::IsCompound($r)) + Line::BuiltIn(BuiltInInstruction::IsCompound($r)) ) } macro_rules! is_float { ($r:expr) => ( - Line::Control(ControlInstruction::IsFloat($r)) + Line::BuiltIn(BuiltInInstruction::IsFloat($r)) ) } macro_rules! is_rational { ($r:expr) => ( - Line::Control(ControlInstruction::IsRational($r)) + Line::BuiltIn(BuiltInInstruction::IsRational($r)) ) } macro_rules! is_nonvar { ($r:expr) => ( - Line::Control(ControlInstruction::IsNonVar($r)) + Line::BuiltIn(BuiltInInstruction::IsNonVar($r)) ) } macro_rules! is_string { ($r:expr) => ( - Line::Control(ControlInstruction::IsString($r)) + Line::BuiltIn(BuiltInInstruction::IsString($r)) ) } macro_rules! is_var { ($reg:expr) => ( - Line::Control(ControlInstruction::IsVar($reg)) + Line::BuiltIn(BuiltInInstruction::IsVar($reg)) ) } @@ -475,7 +475,7 @@ macro_rules! dynamic_is { macro_rules! dynamic_num_test { ($cmp:expr) => ( - Line::Control(ControlInstruction::DynamicCompareNumber($cmp)) + Line::BuiltIn(BuiltInInstruction::DynamicCompareNumber($cmp)) ) } diff --git a/src/tests.rs b/src/tests.rs index 9c1898c4..76a90ddd 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1302,6 +1302,7 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "?- X is 3 rdiv 4, rational(X)."); assert_prolog_failure!(&mut wam, "?- rational(3)."); + assert_prolog_failure!(&mut wam, "?- rational(f(X))."); assert_prolog_failure!(&mut wam, "?- rational(\"sdfsa\")."); assert_prolog_failure!(&mut wam, "?- rational(atom)."); assert_prolog_failure!(&mut wam, "?- rational(structure(functor))."); @@ -1309,6 +1310,7 @@ fn test_queries_on_builtins() assert_prolog_failure!(&mut wam, "?- rational([1,2,X])."); assert_prolog_success!(&mut wam, "?- compound(functor(compound))."); + assert_prolog_success!(&mut wam, "?- compound(f(X))."); assert_prolog_failure!(&mut wam, "?- compound(3.14159269)."); assert_prolog_failure!(&mut wam, "?- compound(3)."); assert_prolog_failure!(&mut wam, "?- compound(\"sdfsa\")."); @@ -1319,6 +1321,7 @@ fn test_queries_on_builtins() assert_prolog_failure!(&mut wam, "?- string(functor(string))."); assert_prolog_failure!(&mut wam, "?- string(3.14159269)."); assert_prolog_failure!(&mut wam, "?- string(3)."); + assert_prolog_failure!(&mut wam, "?- string(f(X))."); assert_prolog_success!(&mut wam, "?- string(\"sdfsa\")."); assert_prolog_failure!(&mut wam, "?- string(atom)."); assert_prolog_failure!(&mut wam, "?- string([1,2,3])."); @@ -1326,6 +1329,7 @@ fn test_queries_on_builtins() assert_prolog_success!(&mut wam, "?- X = nonvar, nonvar(X)."); assert_prolog_failure!(&mut wam, "?- nonvar(X)."); + assert_prolog_success!(&mut wam, "?- nonvar(f(X))."); assert_prolog_success!(&mut wam, "?- nonvar(functor(nonvar))."); assert_prolog_success!(&mut wam, "?- nonvar(3.14159269)."); assert_prolog_success!(&mut wam, "?- nonvar(3).");