look up operator precedence when arity does not match what the atom records, don't print brackets around outermost '+' (#629)

This commit is contained in:
Mark Thom
2020-07-17 11:02:58 -06:00
parent 6c691d9223
commit f0c8056334
5 changed files with 59 additions and 23 deletions

View File

@@ -505,11 +505,11 @@ pub fn fetch_atom_op_spec(
spec: Option<SharedOpDesc>, spec: Option<SharedOpDesc>,
op_dir: &OpDir, op_dir: &OpDir,
) -> Option<SharedOpDesc> { ) -> Option<SharedOpDesc> {
fetch_op_spec(name.clone(), 1, spec.clone(), op_dir) fetch_op_spec_from_existing(name.clone(), 1, spec.clone(), op_dir)
.or_else(|| fetch_op_spec(name, 2, spec, 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, name: ClauseName,
arity: usize, arity: usize,
spec: Option<SharedOpDesc>, spec: Option<SharedOpDesc>,
@@ -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<SharedOpDesc> {
match arity {
2 => op_dir 2 => op_dir
.get(&(name, Fixity::In)) .get(&(name, Fixity::In))
.and_then(|OpDirValue(spec, _)| { .and_then(|OpDirValue(spec, _)| {
@@ -542,7 +550,7 @@ pub fn fetch_op_spec(
} }
op_dir op_dir
.get(&(name.clone(), Fixity::Post)) .get(&(name, Fixity::Post))
.and_then(|OpDirValue(spec, _)| { .and_then(|OpDirValue(spec, _)| {
if spec.prec() > 0 { if spec.prec() > 0 {
Some(spec.clone()) Some(spec.clone())
@@ -551,8 +559,10 @@ pub fn fetch_op_spec(
} }
}) })
} }
_ => None, _ => {
}) None
}
}
} }
pub type ModuleDir = IndexMap<ClauseName, Module>; pub type ModuleDir = IndexMap<ClauseName, Module>;

View File

@@ -1408,7 +1408,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
match self.machine_st.heap.index_addr(&addr).as_ref() { match self.machine_st.heap.index_addr(&addr).as_ref() {
&HeapCellValue::NamedStr(arity, ref name, ref spec) => { &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 { if let Some(spec) = spec {
self.handle_op_as_struct( self.handle_op_as_struct(

View File

@@ -2461,22 +2461,29 @@ impl MachineState {
fn try_functor_fabricate_struct( fn try_functor_fabricate_struct(
&mut self, &mut self,
name: ClauseName, name: ClauseName,
arity: isize, arity: usize,
spec: Option<SharedOpDesc>, spec: Option<SharedOpDesc>,
op_dir: &OpDir, op_dir: &OpDir,
r: Ref, 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 { let f_a = if name.as_str() == "." && arity == 2 {
Addr::Lis(self.heap.h()) Addr::Lis(self.heap.h())
} else { } 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();
let h = self.heap.h();
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); for i in 0 .. arity {
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + i)));
} }
self.bind(r, f_a); self.bind(r, f_a);
@@ -2497,7 +2504,13 @@ impl MachineState {
} }
Addr::Str(o) => match self.heap.clone(o) { Addr::Str(o) => match self.heap.clone(o) {
HeapCellValue::NamedStr(arity, name, spec) => { 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) self.try_functor_compound_case(name, arity, spec)
} }
_ => { _ => {
@@ -2505,7 +2518,13 @@ impl MachineState {
} }
}, },
Addr::Lis(_) | Addr::PStrLocation(..) => { 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) self.try_functor_compound_case(clause_name!("."), 2, spec)
} }
Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => { Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(..) => {
@@ -2576,7 +2595,7 @@ impl MachineState {
if let HeapCellValue::Atom(name, spec) = self.heap.clone(h) { if let HeapCellValue::Atom(name, spec) = self.heap.clone(h) {
self.try_functor_fabricate_struct( self.try_functor_fabricate_struct(
name, name,
arity, arity as usize,
spec, spec,
&indices.op_dir, &indices.op_dir,
a1.as_var().unwrap(), a1.as_var().unwrap(),
@@ -2596,7 +2615,7 @@ impl MachineState {
Addr::Char(c) => { Addr::Char(c) => {
self.try_functor_fabricate_struct( self.try_functor_fabricate_struct(
clause_name!(c.to_string(), indices.atom_tbl), clause_name!(c.to_string(), indices.atom_tbl),
arity, arity as usize,
None, None,
&indices.op_dir, &indices.op_dir,
a1.as_var().unwrap(), a1.as_var().unwrap(),

View File

@@ -3895,9 +3895,13 @@ impl MachineState {
} }
}, },
Addr::Con(h) if self.heap.atom_at(h) => { 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 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) indices.predicate_exists(name.clone(), module, 0, spec)
} else { } else {

View File

@@ -157,9 +157,12 @@ needs_bracketing(Value, Op) :-
current_op(FPrec, _, F)), current_op(FPrec, _, F)),
_, _,
false), false),
( EqPrec < FPrec -> true ( EqPrec < FPrec ->
; '$quoted_token'(F) -> true true
; atom_length(F, 1), graphic_token_char(F) -> true ; '$quoted_token'(F) ->
true
; FPrec > 0, F == Value, graphic_token_char(F) ->
true
; EqPrec == FPrec, ; EqPrec == FPrec,
memberchk(EqSpec, [fx,xfx,yfx]) memberchk(EqSpec, [fx,xfx,yfx])
). ).