From f0c8056334147cb456b52fd93df7a6be00480689 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Fri, 17 Jul 2020 11:02:58 -0600 Subject: [PATCH] look up operator precedence when arity does not match what the atom records, don't print brackets around outermost '+' (#629) --- src/forms.rs | 24 +++++++++++++------ src/heap_print.rs | 2 +- src/machine/machine_state_impl.rs | 39 +++++++++++++++++++++++-------- src/machine/system_calls.rs | 8 +++++-- src/toplevel.pl | 9 ++++--- 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/forms.rs b/src/forms.rs index 5e2681b0..499ee875 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -505,11 +505,11 @@ pub fn fetch_atom_op_spec( spec: Option, op_dir: &OpDir, ) -> Option { - fetch_op_spec(name.clone(), 1, spec.clone(), op_dir) - .or_else(|| fetch_op_spec(name, 2, spec, op_dir)) + fetch_op_spec_from_existing(name.clone(), 1, spec.clone(), op_dir) + .or_else(|| fetch_op_spec_from_existing(name, 2, spec, op_dir)) } -pub fn fetch_op_spec( +pub fn fetch_op_spec_from_existing( name: ClauseName, arity: usize, spec: Option, @@ -524,7 +524,15 @@ pub fn fetch_op_spec( } } - spec.or_else(|| match arity { + spec.or_else(|| fetch_op_spec(name, arity, op_dir)) +} + +pub fn fetch_op_spec( + name: ClauseName, + arity: usize, + op_dir: &OpDir, +) -> Option { + match arity { 2 => op_dir .get(&(name, Fixity::In)) .and_then(|OpDirValue(spec, _)| { @@ -542,7 +550,7 @@ pub fn fetch_op_spec( } op_dir - .get(&(name.clone(), Fixity::Post)) + .get(&(name, Fixity::Post)) .and_then(|OpDirValue(spec, _)| { if spec.prec() > 0 { Some(spec.clone()) @@ -551,8 +559,10 @@ pub fn fetch_op_spec( } }) } - _ => None, - }) + _ => { + None + } + } } pub type ModuleDir = IndexMap; diff --git a/src/heap_print.rs b/src/heap_print.rs index 53fd481a..4a7b3e76 100644 --- a/src/heap_print.rs +++ b/src/heap_print.rs @@ -1408,7 +1408,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { match self.machine_st.heap.index_addr(&addr).as_ref() { &HeapCellValue::NamedStr(arity, ref name, ref spec) => { - let spec = fetch_op_spec(name.clone(), arity, spec.clone(), self.op_dir); + let spec = fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir); if let Some(spec) = spec { self.handle_op_as_struct( diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 582aa5bf..ed5deb81 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -2461,22 +2461,29 @@ impl MachineState { fn try_functor_fabricate_struct( &mut self, name: ClauseName, - arity: isize, + arity: usize, spec: Option, op_dir: &OpDir, r: Ref, ) { - let spec = fetch_atom_op_spec(name.clone(), spec, op_dir); + let spec = spec.and_then(|spec| { + if spec.arity() != arity { + fetch_op_spec(name.clone(), arity, op_dir) + } else { + Some(spec) + } + }); let f_a = if name.as_str() == "." && arity == 2 { Addr::Lis(self.heap.h()) } else { - self.heap.to_unifiable(HeapCellValue::NamedStr(arity as usize, name, spec)) + self.heap.to_unifiable(HeapCellValue::NamedStr(arity, name, spec)) }; - for _ in 0..arity { - let h = self.heap.h(); - self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); + let h = self.heap.h(); + + for i in 0 .. arity { + self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + i))); } self.bind(r, f_a); @@ -2497,7 +2504,13 @@ impl MachineState { } Addr::Str(o) => match self.heap.clone(o) { HeapCellValue::NamedStr(arity, name, spec) => { - let spec = fetch_op_spec(name.clone(), arity, spec, &indices.op_dir); + let spec = fetch_op_spec_from_existing( + name.clone(), + arity, + spec, + &indices.op_dir, + ); + self.try_functor_compound_case(name, arity, spec) } _ => { @@ -2505,7 +2518,13 @@ impl MachineState { } }, Addr::Lis(_) | Addr::PStrLocation(..) => { - let spec = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir); + let spec = fetch_op_spec_from_existing( + clause_name!("."), + 2, + None, + &indices.op_dir, + ); + self.try_functor_compound_case(clause_name!("."), 2, spec) } Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => { @@ -2576,7 +2595,7 @@ impl MachineState { if let HeapCellValue::Atom(name, spec) = self.heap.clone(h) { self.try_functor_fabricate_struct( name, - arity, + arity as usize, spec, &indices.op_dir, a1.as_var().unwrap(), @@ -2596,7 +2615,7 @@ impl MachineState { Addr::Char(c) => { self.try_functor_fabricate_struct( clause_name!(c.to_string(), indices.atom_tbl), - arity, + arity as usize, None, &indices.op_dir, a1.as_var().unwrap(), diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 9e969c7b..7763e963 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -3895,9 +3895,13 @@ impl MachineState { } }, Addr::Con(h) if self.heap.atom_at(h) => { - if let &HeapCellValue::Atom(ref name, ref spec) = &self.heap[h] { + if let &HeapCellValue::Atom(ref name, ref spec) = &self.heap[h] { let module = name.owning_module(); - let spec = fetch_atom_op_spec(name.clone(), spec.clone(), &indices.op_dir); + let spec = fetch_atom_op_spec( + name.clone(), + spec.clone(), + &indices.op_dir, + ); indices.predicate_exists(name.clone(), module, 0, spec) } else { diff --git a/src/toplevel.pl b/src/toplevel.pl index 23e7decd..dfe53d26 100644 --- a/src/toplevel.pl +++ b/src/toplevel.pl @@ -157,9 +157,12 @@ needs_bracketing(Value, Op) :- current_op(FPrec, _, F)), _, false), - ( EqPrec < FPrec -> true - ; '$quoted_token'(F) -> true - ; atom_length(F, 1), graphic_token_char(F) -> true + ( EqPrec < FPrec -> + true + ; '$quoted_token'(F) -> + true + ; FPrec > 0, F == Value, graphic_token_char(F) -> + true ; EqPrec == FPrec, memberchk(EqSpec, [fx,xfx,yfx]) ). -- 2.54.0