]> Repositorios git - scryer-prolog.git/commitdiff
look up operator precedence when arity does not match what the atom records, don...
authorMark Thom <[email protected]>
Fri, 17 Jul 2020 17:02:58 +0000 (11:02 -0600)
committerMark Thom <[email protected]>
Fri, 17 Jul 2020 17:02:58 +0000 (11:02 -0600)
src/forms.rs
src/heap_print.rs
src/machine/machine_state_impl.rs
src/machine/system_calls.rs
src/toplevel.pl

index 5e2681b00a3290a1a1b74f5062578ed62aebd1f1..499ee87513c9c47ca32d41334f2aacc8d1b4086c 100644 (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>;
index 53fd481a7d9baca87a0153ee71bce867ccebc2a3..4a7b3e76d5bcc4ddb685577be07f3c32da528fc5 100644 (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(
index 582aa5bfa59cb6f4963603080fbdc0623ed12ffc..ed5deb81894f315152fa68837da8fda330e12153 100644 (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(),
index 9e969c7b89f5af9bbb29ceaef838c2f91cf2c9fb..7763e9632103ff4e7b9600c91062f4a75b30c9b2 100644 (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 {
index 23e7decd95b7a4b8a92c2e86a8ce97dd44cf0904..dfe53d26358f3f66c544d1c5b908b33d2e9d4ffa 100644 (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])
     ).