From 1d964ef9218f702a33d54e36f3e5f07392eed9f4 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sat, 18 Apr 2020 14:37:14 -0600 Subject: [PATCH] add domain and type errors for compare/3 (#296) --- src/prolog/machine/machine_errors.rs | 2 ++ src/prolog/machine/machine_state.rs | 30 +++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index 3e366322..c5173afc 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -505,6 +505,7 @@ impl ValidType { #[derive(Clone, Copy)] pub enum DomainErrorType { NotLessThanZero, + Order, Stream, StreamOrAlias, } @@ -513,6 +514,7 @@ impl DomainErrorType { pub fn as_str(self) -> &'static str { match self { DomainErrorType::NotLessThanZero => "not_less_than_zero", + DomainErrorType::Order => "order", DomainErrorType::Stream => "stream", DomainErrorType::StreamOrAlias => "stream_or_alias", } diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 9f50f530..cc9a74c2 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -1076,10 +1076,38 @@ pub(crate) trait CallPolicy: Any { return_from_clause!(machine_st.last_call, machine_st) } &BuiltInClauseType::Compare => { - let a1 = machine_st[temp_v!(1)]; + let a1 = machine_st.store(machine_st.deref(machine_st[temp_v!(1)])); let a2 = machine_st[temp_v!(2)]; let a3 = machine_st[temp_v!(3)]; + match a1 { + Addr::Con(h) if machine_st.heap.atom_at(h) => { + if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] { + match atom.as_str() { + ">" | "<" | "=" => { + } + _ => { + let stub = + MachineError::functor_stub(clause_name!("compare"), 3); + + let err = MachineError::domain_error(DomainErrorType::Order, a1); + return Err(machine_st.error_form(err, stub)); + } + } + } else { + unreachable!() + } + } + addr if !addr.is_ref() => { + let h = machine_st.heap.h(); + let stub = MachineError::functor_stub(clause_name!("compare"), 3); + let err = MachineError::type_error(h, ValidType::Atom, a1); + return Err(machine_st.error_form(err, stub)); + } + _ => { + } + } + let atom = match machine_st.compare_term_test(&a2, &a3) { Some(Ordering::Greater) => { let spec = fetch_atom_op_spec(clause_name!(">"), None, &indices.op_dir); -- 2.54.0