]> Repositorios git - scryer-prolog.git/commitdiff
index atoms with operators against the same atom with no operator (#387)
authorMark Thom <[email protected]>
Thu, 30 Apr 2020 21:09:05 +0000 (15:09 -0600)
committerMark Thom <[email protected]>
Thu, 30 Apr 2020 21:09:05 +0000 (15:09 -0600)
src/prolog/indexing.rs

index f02565eb1527000df6fe0b27f22fce6cec417365..4873fc03251824a7c2714dca2a008b93574ee22a 100644 (file)
@@ -1,4 +1,5 @@
 use prolog_parser::ast::*;
+use prolog_parser::tabled_rc::*;
 
 use crate::prolog::instructions::*;
 use crate::prolog::rug::Integer;
@@ -18,6 +19,7 @@ enum IntIndex {
 }
 
 pub struct CodeOffsets {
+    atom_tbl: TabledData<Atom>,
     pub constants: IndexMap<Constant, ThirdLevelIndex>,
     pub lists: ThirdLevelIndex,
     pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
@@ -26,6 +28,7 @@ pub struct CodeOffsets {
 impl CodeOffsets {
     pub fn new() -> Self {
         CodeOffsets {
+            atom_tbl: TabledData::new(Rc::new("_index".to_string())),
             constants: IndexMap::new(),
             lists: Vec::new(),
             structures: IndexMap::new(),
@@ -53,13 +56,37 @@ impl CodeOffsets {
 
     fn intercept_constant(&mut self, constant: &Constant, index: usize) {
         match constant {
-            &Constant::Atom(ref name, _) if name.is_char() => {
+            &Constant::Atom(ref name, ref op) if name.is_char() => {
                 let c = name.as_str().chars().next().unwrap();
                 let code = self.constants
                     .entry(Constant::Char(c))
                     .or_insert(vec![]);
 
                 code.push(Self::add_index(code.is_empty(), index));
+
+                if op.is_some() {
+                    let code = self.constants
+                        .entry(Constant::Atom(name.clone(), None))
+                        .or_insert(vec![]);
+
+                    code.push(Self::add_index(false, index));
+                }
+            }
+            &Constant::Atom(ref name, Some(_)) => {
+                let code = self.constants
+                    .entry(Constant::Atom(name.clone(), None))
+                    .or_insert(vec![]);
+
+                code.push(Self::add_index(code.is_empty(), index));
+            }
+            &Constant::Char(c) => {
+                let atom = clause_name!(c.to_string(), self.atom_tbl.clone());
+
+                let code = self.constants
+                    .entry(Constant::Atom(atom, None))
+                    .or_insert(vec![]);
+
+                code.push(Self::add_index(code.is_empty(), index));
             }
             &Constant::Fixnum(n) => {
                 let code = self.constants