index atoms with operators against the same atom with no operator (#387)

This commit is contained in:
Mark Thom
2020-04-30 15:09:05 -06:00
parent a821daadd3
commit d3f1cd7411

View File

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