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:
24
src/forms.rs
24
src/forms.rs
@@ -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>;
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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])
|
||||||
).
|
).
|
||||||
|
|||||||
Reference in New Issue
Block a user