From: Mark Thom Date: Sat, 18 Apr 2020 20:37:14 +0000 (-0600) Subject: add domain and type errors for compare/3 (#296) X-Git-Tag: v0.8.123~131 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=1d964ef9218f702a33d54e36f3e5f07392eed9f4;p=scryer-prolog.git add domain and type errors for compare/3 (#296) --- 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);