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>,
op_dir: &OpDir,
) -> Option<SharedOpDesc> {
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<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
.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<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() {
&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(

View File

@@ -2461,22 +2461,29 @@ impl MachineState {
fn try_functor_fabricate_struct(
&mut self,
name: ClauseName,
arity: isize,
arity: usize,
spec: Option<SharedOpDesc>,
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(),

View File

@@ -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 {

View File

@@ -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])
).