Merge branch 'Skgland-clean_up' into rebis-dev

This commit is contained in:
Mark Thom
2021-02-07 00:34:57 -07:00
43 changed files with 6895 additions and 8659 deletions

4
Cargo.lock generated
View File

@@ -878,7 +878,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "prolog_parser_rebis" name = "prolog_parser"
version = "0.8.68" version = "0.8.68"
dependencies = [ dependencies = [
"lexical", "lexical",
@@ -1221,7 +1221,7 @@ dependencies = [
"num-rug-adapter", "num-rug-adapter",
"openssl", "openssl",
"ordered-float", "ordered-float",
"prolog_parser_rebis", "prolog_parser",
"ref_thread_local", "ref_thread_local",
"ring", "ring",
"ripemd160", "ripemd160",

View File

@@ -18,8 +18,8 @@ members = ["crates/prolog_parser"]
indexmap = "1.0.2" indexmap = "1.0.2"
[features] [features]
default = ["rug", "prolog_parser_rebis/rug"] default = ["rug", "prolog_parser/rug"]
num = ["num-rug-adapter", "prolog_parser_rebis/num"] num = ["num-rug-adapter", "prolog_parser/num"]
[dependencies] [dependencies]
cpu-time = "1.0.0" cpu-time = "1.0.0"
@@ -35,7 +35,7 @@ libc = "0.2.62"
nix = "0.15.0" nix = "0.15.0"
num-rug-adapter = { optional = true, version = "0.1.4" } num-rug-adapter = { optional = true, version = "0.1.4" }
ordered-float = "0.5.0" ordered-float = "0.5.0"
prolog_parser_rebis = { path = "./crates/prolog_parser", default-features = false } prolog_parser = { path = "./crates/prolog_parser", default-features = false }
ref_thread_local = "0.0.0" ref_thread_local = "0.0.0"
rug = { version = "1.4.0", optional = true } rug = { version = "1.4.0", optional = true }
rustyline = "7.0.0" rustyline = "7.0.0"

View File

@@ -1,5 +1,3 @@
extern crate indexmap;
use std::env; use std::env;
use std::fs; use std::fs;
use std::fs::File; use std::fs::File;
@@ -15,15 +13,13 @@ fn find_prolog_files(libraries: &mut File, prefix: &str, current_dir: &Path) {
for entry in entries.filter_map(Result::ok).map(|e| e.path()) { for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
if entry.is_dir() { if entry.is_dir() {
if let Some(file_name) = entry.file_name() { if let Some(file_name) = entry.file_name() {
let new_prefix = let new_prefix = prefix.to_owned() + file_name.to_str().unwrap() + "/";
prefix.to_owned() + file_name.to_str().unwrap() + "/";
find_prolog_files(libraries, &new_prefix, &entry); find_prolog_files(libraries, &new_prefix, &entry);
} }
} else if entry.is_file() { } else if entry.is_file() {
let ext = std::ffi::OsStr::new("pl"); let ext = std::ffi::OsStr::new("pl");
if entry.extension() == Some(ext) { if entry.extension() == Some(ext) {
let contain = let contain = String::from_utf8(fs::read(&entry).unwrap()).unwrap();
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
let name = entry.file_stem().unwrap().to_str().unwrap(); let name = entry.file_stem().unwrap().to_str().unwrap();
let line = format!( let line = format!(
@@ -47,7 +43,7 @@ fn main() {
libraries libraries
.write_all( .write_all(
b"ref_thread_local! { b"ref_thread_local::ref_thread_local! {
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = { pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
let mut m = IndexMap::new();\n", let mut m = IndexMap::new();\n",
) )

View File

@@ -148,7 +148,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "prolog_parser_rebis" name = "prolog_parser"
version = "0.8.68" version = "0.8.68"
dependencies = [ dependencies = [
"lexical", "lexical",

View File

@@ -1,8 +1,9 @@
[package] [package]
name = "prolog_parser_rebis" name = "prolog_parser"
version = "0.8.68" version = "0.8.68"
authors = ["Mark Thom <markjordanthom@gmail.com>"] authors = ["Mark Thom <markjordanthom@gmail.com>"]
repository = "https://github.com/mthom/prolog_parser" edition = "2018"
repository = "https://github.com/mthom/scryer-prolog"
description = " An operator precedence parser for the Rebis development version of Scryer Prolog, an up and coming ISO Prolog implementation." description = " An operator precedence parser for the Rebis development version of Scryer Prolog, an up and coming ISO Prolog implementation."
license = "BSD-3-Clause" license = "BSD-3-Clause"

View File

@@ -1,8 +1,8 @@
use rug::{Integer, Rational}; use crate::rug::{Integer, Rational};
use crate::tabled_rc::*;
use ordered_float::*; use ordered_float::*;
use tabled_rc::*;
use put_back_n::*; use crate::put_back_n::*;
use std::cell::Cell; use std::cell::Cell;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -27,112 +27,150 @@ pub const MAX_ARITY: usize = 1023;
pub const XFX: u32 = 0x0001; pub const XFX: u32 = 0x0001;
pub const XFY: u32 = 0x0002; pub const XFY: u32 = 0x0002;
pub const YFX: u32 = 0x0004; pub const YFX: u32 = 0x0004;
pub const XF: u32 = 0x0010; pub const XF: u32 = 0x0010;
pub const YF: u32 = 0x0020; pub const YF: u32 = 0x0020;
pub const FX: u32 = 0x0040; pub const FX: u32 = 0x0040;
pub const FY: u32 = 0x0080; pub const FY: u32 = 0x0080;
pub const DELIMITER: u32 = 0x0100; pub const DELIMITER: u32 = 0x0100;
pub const TERM: u32 = 0x1000; pub const TERM: u32 = 0x1000;
pub const LTERM: u32 = 0x3000; pub const LTERM: u32 = 0x3000;
pub const NEGATIVE_SIGN: u32 = 0x0200; pub const NEGATIVE_SIGN: u32 = 0x0200;
#[macro_export] #[macro_export]
macro_rules! clause_name { macro_rules! clause_name {
($name: expr, $tbl: expr) => ( ($name: expr, $tbl: expr) => {
ClauseName::User(TabledRc::new($name, $tbl.clone())) $crate::ast::ClauseName::User($crate::tabled_rc::TabledRc::new($name, $tbl.clone()))
) ; };
($name: expr) => ( ($name: expr) => {
ClauseName::BuiltIn($name) $crate::ast::ClauseName::BuiltIn($name)
) };
} }
#[macro_export] #[macro_export]
macro_rules! atom { macro_rules! atom {
($e:expr, $tbl:expr) => ( ($e:expr, $tbl:expr) => {
Constant::Atom(ClauseName::User(tabled_rc!($e, $tbl)), None) $crate::ast::Constant::Atom(
); $crate::ast::ClauseName::User($crate::tabled_rc!($e, $tbl)),
($e:expr) => ( None,
Constant::Atom(clause_name!($e), None) )
) };
($e:expr) => {
$crate::ast::Constant::Atom($crate::clause_name!($e), None)
};
} }
#[macro_export] #[macro_export]
macro_rules! rc_atom { macro_rules! rc_atom {
($e:expr) => ( ($e:expr) => {
Rc::new(String::from($e)) Rc::new(String::from($e))
) };
} }
macro_rules! is_term { macro_rules! is_term {
($x:expr) => ( ($x & TERM) != 0 ) ($x:expr) => {
($x & $crate::ast::TERM) != 0
};
} }
macro_rules! is_lterm { macro_rules! is_lterm {
($x:expr) => ( ($x & LTERM) != 0 ) ($x:expr) => {
($x & $crate::ast::LTERM) != 0
};
} }
macro_rules! is_op { macro_rules! is_op {
($x:expr) => ( $x & (XF | YF | FX | FY | XFX | XFY | YFX) != 0 ) ($x:expr) => {
$x & ($crate::ast::XF
| $crate::ast::YF
| $crate::ast::FX
| $crate::ast::FY
| $crate::ast::XFX
| $crate::ast::XFY
| $crate::ast::YFX)
!= 0
};
} }
macro_rules! is_negate { macro_rules! is_negate {
($x:expr) => ( ($x & NEGATIVE_SIGN) != 0 ) ($x:expr) => {
($x & $crate::ast::NEGATIVE_SIGN) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_prefix { macro_rules! is_prefix {
($x:expr) => ( $x & (FX | FY) != 0 ) ($x:expr) => {
$x & ($crate::ast::FX | $crate::ast::FY) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_postfix { macro_rules! is_postfix {
($x:expr) => ( $x & (XF | YF) != 0 ) ($x:expr) => {
$x & ($crate::ast::XF | $crate::ast::YF) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_infix { macro_rules! is_infix {
($x:expr) => ( ($x & (XFX | XFY | YFX)) != 0 ) ($x:expr) => {
($x & ($crate::ast::XFX | $crate::ast::XFY | $crate::ast::YFX)) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_xfx { macro_rules! is_xfx {
($x:expr) => ( ($x & XFX) != 0 ) ($x:expr) => {
($x & $crate::ast::XFX) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_xfy { macro_rules! is_xfy {
($x:expr) => ( ($x & XFY) != 0 ) ($x:expr) => {
($x & $crate::ast::XFY) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_yfx { macro_rules! is_yfx {
($x:expr) => ( ($x & YFX) != 0 ) ($x:expr) => {
($x & $crate::ast::YFX) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_yf { macro_rules! is_yf {
($x:expr) => ( ($x & YF) != 0 ) ($x:expr) => {
($x & $crate::ast::YF) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_xf { macro_rules! is_xf {
($x:expr) => ( ($x & XF) != 0 ) ($x:expr) => {
($x & $crate::ast::XF) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_fx { macro_rules! is_fx {
($x:expr) => ( ($x & FX) != 0 ) ($x:expr) => {
($x & $crate::ast::FX) != 0
};
} }
#[macro_export] #[macro_export]
macro_rules! is_fy { macro_rules! is_fy {
($x:expr) => ( ($x & FY) != 0 ) ($x:expr) => {
($x & $crate::ast::FY) != 0
};
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum RegType { pub enum RegType {
Perm(usize), Perm(usize),
Temp(usize) Temp(usize),
} }
impl Default for RegType { impl Default for RegType {
@@ -144,23 +182,20 @@ impl Default for RegType {
impl RegType { impl RegType {
pub fn reg_num(self) -> usize { pub fn reg_num(self) -> usize {
match self { match self {
RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num,
} }
} }
pub fn is_perm(self) -> bool { pub fn is_perm(self) -> bool {
match self { matches!(self, RegType::Perm(_))
RegType::Perm(_) => true,
_ => false
}
} }
} }
impl fmt::Display for RegType { impl fmt::Display for RegType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&RegType::Perm(val) => write!(f, "Y{}", val), RegType::Perm(val) => write!(f, "Y{}", val),
&RegType::Temp(val) => write!(f, "X{}", val) RegType::Temp(val) => write!(f, "X{}", val),
} }
} }
} }
@@ -168,13 +203,13 @@ impl fmt::Display for RegType {
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum VarReg { pub enum VarReg {
ArgAndNorm(RegType, usize), ArgAndNorm(RegType, usize),
Norm(RegType) Norm(RegType),
} }
impl VarReg { impl VarReg {
pub fn norm(self) -> RegType { pub fn norm(self) -> RegType {
match self { match self {
VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg,
} }
} }
} }
@@ -182,12 +217,10 @@ impl VarReg {
impl fmt::Display for VarReg { impl fmt::Display for VarReg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg), VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
&VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg), VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
&VarReg::ArgAndNorm(RegType::Perm(reg), arg) => VarReg::ArgAndNorm(RegType::Perm(reg), arg) => write!(f, "Y{} A{}", reg, arg),
write!(f, "Y{} A{}", reg, arg), VarReg::ArgAndNorm(RegType::Temp(reg), arg) => write!(f, "X{} A{}", reg, arg),
&VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
write!(f, "X{} A{}", reg, arg)
} }
} }
} }
@@ -200,28 +233,30 @@ impl Default for VarReg {
#[macro_export] #[macro_export]
macro_rules! temp_v { macro_rules! temp_v {
($x:expr) => ( ($x:expr) => {
RegType::Temp($x) $crate::ast::RegType::Temp($x)
) };
} }
#[macro_export] #[macro_export]
macro_rules! perm_v { macro_rules! perm_v {
($x:expr) => ( ($x:expr) => {
RegType::Perm($x) $crate::ast::RegType::Perm($x)
) };
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum GenContext { pub enum GenContext {
Head, Mid(usize), Last(usize) // Mid & Last: chunk_num Head,
Mid(usize),
Last(usize), // Mid & Last: chunk_num
} }
impl GenContext { impl GenContext {
pub fn chunk_num(self) -> usize { pub fn chunk_num(self) -> usize {
match self { match self {
GenContext::Head => 0, GenContext::Head => 0,
GenContext::Mid(cn) | GenContext::Last(cn) => cn GenContext::Mid(cn) | GenContext::Last(cn) => cn,
} }
} }
} }
@@ -247,43 +282,35 @@ pub type OpDir = HashMap<OpDirKey, OpDirValue>;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct MachineFlags { pub struct MachineFlags {
pub double_quotes: DoubleQuotes pub double_quotes: DoubleQuotes,
} }
impl Default for MachineFlags { impl Default for MachineFlags {
fn default() -> Self { fn default() -> Self {
MachineFlags { double_quotes: DoubleQuotes::default() } MachineFlags {
double_quotes: DoubleQuotes::default(),
}
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum DoubleQuotes { pub enum DoubleQuotes {
Atom, Chars, Codes Atom,
Chars,
Codes,
} }
impl DoubleQuotes { impl DoubleQuotes {
pub fn is_chars(self) -> bool { pub fn is_chars(self) -> bool {
if let DoubleQuotes::Chars = self { matches!(self, DoubleQuotes::Chars)
true
} else {
false
}
} }
pub fn is_atom(self) -> bool { pub fn is_atom(self) -> bool {
if let DoubleQuotes::Atom = self { matches!(self, DoubleQuotes::Atom)
true
} else {
false
}
} }
pub fn is_codes(self) -> bool { pub fn is_codes(self) -> bool {
if let DoubleQuotes::Codes = self { matches!(self, DoubleQuotes::Codes)
true
} else {
false
}
} }
} }
@@ -296,10 +323,10 @@ impl Default for DoubleQuotes {
pub fn default_op_dir() -> OpDir { pub fn default_op_dir() -> OpDir {
let mut op_dir = OpDir::new(); let mut op_dir = OpDir::new();
op_dir.insert((clause_name!(":-"), Fixity::In), OpDirValue::new(XFX, 1200)); op_dir.insert((clause_name!(":-"), Fixity::In), OpDirValue::new(XFX, 1200));
op_dir.insert((clause_name!(":-"), Fixity::Pre), OpDirValue::new(FX, 1200)); op_dir.insert((clause_name!(":-"), Fixity::Pre), OpDirValue::new(FX, 1200));
op_dir.insert((clause_name!("?-"), Fixity::Pre), OpDirValue::new(FX, 1200)); op_dir.insert((clause_name!("?-"), Fixity::Pre), OpDirValue::new(FX, 1200));
op_dir.insert((clause_name!(","), Fixity::In), OpDirValue::new(XFY, 1000)); op_dir.insert((clause_name!(","), Fixity::In), OpDirValue::new(XFY, 1000));
op_dir op_dir
} }
@@ -307,7 +334,7 @@ pub fn default_op_dir() -> OpDir {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ArithmeticError { pub enum ArithmeticError {
NonEvaluableFunctor(Constant, usize), NonEvaluableFunctor(Constant, usize),
UninstantiatedVar UninstantiatedVar,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -321,47 +348,35 @@ pub enum ParserError {
MissingQuote(usize, usize), MissingQuote(usize, usize),
NonPrologChar(usize, usize), NonPrologChar(usize, usize),
ParseBigInt(usize, usize), ParseBigInt(usize, usize),
Utf8Error(usize, usize) Utf8Error(usize, usize),
} }
impl ParserError { impl ParserError {
pub fn line_and_col_num(&self) -> Option<(usize, usize)> { pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
match self { match self {
&ParserError::BackQuotedString(line_num, col_num) &ParserError::BackQuotedString(line_num, col_num)
| &ParserError::UnexpectedChar(_, line_num, col_num) | &ParserError::UnexpectedChar(_, line_num, col_num)
| &ParserError::IncompleteReduction(line_num, col_num) | &ParserError::IncompleteReduction(line_num, col_num)
| &ParserError::MissingQuote(line_num, col_num) | &ParserError::MissingQuote(line_num, col_num)
| &ParserError::NonPrologChar(line_num, col_num) | &ParserError::NonPrologChar(line_num, col_num)
| &ParserError::ParseBigInt(line_num, col_num) | &ParserError::ParseBigInt(line_num, col_num)
| &ParserError::Utf8Error(line_num, col_num) => | &ParserError::Utf8Error(line_num, col_num) => Some((line_num, col_num)),
Some((line_num, col_num)), _ => None,
_ =>
None
} }
} }
pub fn as_str(&self) -> &'static str { pub fn as_str(&self) -> &'static str {
match self { match self {
&ParserError::BackQuotedString(..) => ParserError::BackQuotedString(..) => "back_quoted_string",
"back_quoted_string", ParserError::UnexpectedChar(..) => "unexpected_char",
&ParserError::UnexpectedChar(..) => ParserError::UnexpectedEOF => "unexpected_end_of_file",
"unexpected_char", ParserError::IncompleteReduction(..) => "incomplete_reduction",
&ParserError::UnexpectedEOF => ParserError::InvalidSingleQuotedCharacter(..) => "invalid_single_quoted_character",
"unexpected_end_of_file", ParserError::IO(_) => "input_output_error",
&ParserError::IncompleteReduction(..) => ParserError::MissingQuote(..) => "missing_quote",
"incomplete_reduction", ParserError::NonPrologChar(..) => "non_prolog_character",
&ParserError::InvalidSingleQuotedCharacter(..) => ParserError::ParseBigInt(..) => "cannot_parse_big_int",
"invalid_single_quoted_character", ParserError::Utf8Error(..) => "utf8_conversion_error",
&ParserError::IO(_) =>
"input_output_error",
&ParserError::MissingQuote(..) =>
"missing_quote",
&ParserError::NonPrologChar(..) =>
"non_prolog_character",
&ParserError::ParseBigInt(..) =>
"cannot_parse_big_int",
&ParserError::Utf8Error(..) =>
"utf8_conversion_error",
} }
} }
} }
@@ -382,39 +397,38 @@ impl From<&IOError> for ParserError {
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct CompositeOpDir<'a, 'b> { pub struct CompositeOpDir<'a, 'b> {
pub primary_op_dir: Option<&'b OpDir>, pub primary_op_dir: Option<&'b OpDir>,
pub secondary_op_dir: &'a OpDir, pub secondary_op_dir: &'a OpDir,
} }
impl<'a, 'b> CompositeOpDir<'a, 'b> impl<'a, 'b> CompositeOpDir<'a, 'b> {
{
#[inline] #[inline]
pub fn new(secondary_op_dir: &'a OpDir, primary_op_dir: Option<&'b OpDir>) -> Self { pub fn new(secondary_op_dir: &'a OpDir, primary_op_dir: Option<&'b OpDir>) -> Self {
CompositeOpDir { primary_op_dir, secondary_op_dir } CompositeOpDir {
primary_op_dir,
secondary_op_dir,
}
} }
#[inline] #[inline]
pub(crate) pub(crate) fn get(&self, name: ClauseName, fixity: Fixity) -> Option<&OpDirValue> {
fn get(&self, name: ClauseName, fixity: Fixity) -> Option<&OpDirValue> let entry = if let Some(ref primary_op_dir) = &self.primary_op_dir {
{ primary_op_dir.get(&(name.clone(), fixity))
let entry = } else {
if let Some(ref primary_op_dir) = &self.primary_op_dir { None
primary_op_dir.get(&(name.clone(), fixity)) };
} else {
None
};
entry.or_else(move || self.secondary_op_dir.get(&(name, fixity))) entry.or_else(move || self.secondary_op_dir.get(&(name, fixity)))
} }
} }
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub enum Fixity { pub enum Fixity {
In, Post, Pre In,
Post,
Pre,
} }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
@@ -496,28 +510,21 @@ pub enum Constant {
impl fmt::Display for Constant { impl fmt::Display for Constant {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&Constant::Atom(ref atom, _) => Constant::Atom(ref atom, _) => {
if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) { if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) {
write!(f, "'{}'", atom.as_str()) write!(f, "'{}'", atom.as_str())
} else { } else {
write!(f, "{}", atom.as_str()) write!(f, "{}", atom.as_str())
}, }
&Constant::Char(c) => }
write!(f, "'{}'", c as u32), Constant::Char(c) => write!(f, "'{}'", *c as u32),
&Constant::EmptyList => Constant::EmptyList => write!(f, "[]"),
write!(f, "[]"), Constant::Fixnum(n) => write!(f, "{}", n),
&Constant::Fixnum(n) => Constant::Integer(ref n) => write!(f, "{}", n),
write!(f, "{}", n), Constant::Rational(ref n) => write!(f, "{}", n),
&Constant::Integer(ref n) => Constant::Float(ref n) => write!(f, "{}", n),
write!(f, "{}", n), Constant::String(ref s) => write!(f, "\"{}\"", &s),
&Constant::Rational(ref n) => Constant::Usize(integer) => write!(f, "u{}", integer),
write!(f, "{}", n),
&Constant::Float(ref n) =>
write!(f, "{}", n),
&Constant::String(ref s) =>
write!(f, "\"{}\"", &s),
&Constant::Usize(integer) =>
write!(f, "u{}", integer),
} }
} }
} }
@@ -526,37 +533,27 @@ impl PartialEq for Constant {
fn eq(&self, other: &Constant) -> bool { fn eq(&self, other: &Constant) -> bool {
match (self, other) { match (self, other) {
(&Constant::Atom(ref atom, _), &Constant::Char(c)) (&Constant::Atom(ref atom, _), &Constant::Char(c))
| (&Constant::Char(c), &Constant::Atom(ref atom, _)) => { | (&Constant::Char(c), &Constant::Atom(ref atom, _)) => {
atom.is_char() && Some(c) == atom.as_str().chars().next() atom.is_char() && atom.as_str().starts_with(c)
}, }
(&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) => (&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) => a1.as_str() == a2.as_str(),
a1.as_str() == a2.as_str(), (&Constant::Char(c1), &Constant::Char(c2)) => c1 == c2,
(&Constant::Char(c1), &Constant::Char(c2)) => (&Constant::Fixnum(n1), &Constant::Fixnum(n2)) => n1 == n2,
c1 == c2, (&Constant::Fixnum(n1), &Constant::Integer(ref n2))
(&Constant::Fixnum(n1), &Constant::Fixnum(n2)) => | (&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => {
n1 == n2,
(&Constant::Fixnum(n1), &Constant::Integer(ref n2)) |
(&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => {
if let Some(n2) = n2.to_isize() { if let Some(n2) = n2.to_isize() {
n1 == n2 n1 == n2
} else { } else {
false false
} }
} }
(&Constant::Integer(ref n1), &Constant::Integer(ref n2)) => (&Constant::Integer(ref n1), &Constant::Integer(ref n2)) => n1 == n2,
n1 == n2, (&Constant::Rational(ref n1), &Constant::Rational(ref n2)) => n1 == n2,
(&Constant::Rational(ref n1), &Constant::Rational(ref n2)) => (&Constant::Float(ref n1), &Constant::Float(ref n2)) => n1 == n2,
n1 == n2, (&Constant::String(ref s1), &Constant::String(ref s2)) => s1 == s2,
(&Constant::Float(ref n1), &Constant::Float(ref n2)) => (&Constant::EmptyList, &Constant::EmptyList) => true,
n1 == n2, (&Constant::Usize(u1), &Constant::Usize(u2)) => u1 == u2,
(&Constant::String(ref s1), &Constant::String(ref s2)) => { _ => false,
&s1 == &s2
}
(&Constant::EmptyList, &Constant::EmptyList) =>
true,
(&Constant::Usize(u1), &Constant::Usize(u2)) =>
u1 == u2,
_ => false
} }
} }
} }
@@ -564,10 +561,10 @@ impl PartialEq for Constant {
impl Eq for Constant {} impl Eq for Constant {}
impl Constant { impl Constant {
pub fn to_atom(self) -> Option<ClauseName> { pub fn to_atom(&self) -> Option<ClauseName> {
match self { match self {
Constant::Atom(a, _) => Some(a.defrock_brackets()), Constant::Atom(a, _) => Some(a.defrock_brackets()),
_ => None _ => None,
} }
} }
} }
@@ -575,7 +572,7 @@ impl Constant {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ClauseName { pub enum ClauseName {
BuiltIn(&'static str), BuiltIn(&'static str),
User(TabledRc<Atom>) User(TabledRc<Atom>),
} }
impl fmt::Display for ClauseName { impl fmt::Display for ClauseName {
@@ -620,20 +617,22 @@ impl ClauseName {
#[inline] #[inline]
pub fn owning_module(&self) -> Self { pub fn owning_module(&self) -> Self {
match self { match self {
&ClauseName::User(ref name) => { ClauseName::User(ref name) => {
let module = name.owning_module(); let module = name.owning_module();
ClauseName::User(TabledRc { atom: module.clone(), ClauseName::User(TabledRc {
table: TabledData::new(module) }) atom: module.clone(),
}, table: TabledData::new(module),
_ => clause_name!("user") })
}
_ => clause_name!("user"),
} }
} }
#[inline] #[inline]
pub fn to_rc(&self) -> Rc<String> { pub fn to_rc(&self) -> Rc<String> {
match self { match self {
&ClauseName::BuiltIn(s) => Rc::new(s.to_string()), ClauseName::BuiltIn(s) => Rc::new(s.to_string()),
&ClauseName::User(ref rc) => rc.inner() ClauseName::User(ref rc) => rc.inner(),
} }
} }
@@ -660,52 +659,46 @@ impl ClauseName {
pub fn has_table_of(&self, other: &ClauseName) -> bool { pub fn has_table_of(&self, other: &ClauseName) -> bool {
match self { match self {
ClauseName::BuiltIn(_) => { ClauseName::BuiltIn(_) => {
if let ClauseName::BuiltIn(_) = other { matches!(other, ClauseName::BuiltIn(_))
true
} else {
false
}
}
ClauseName::User(ref name) => {
other.has_table(&name.table)
} }
ClauseName::User(ref name) => other.has_table(&name.table),
} }
} }
#[inline] #[inline]
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
match self { match self {
&ClauseName::BuiltIn(s) => s, ClauseName::BuiltIn(s) => s,
&ClauseName::User(ref name) => name.as_ref() ClauseName::User(ref name) => name.as_ref(),
} }
} }
#[inline] #[inline]
pub fn is_char(&self) -> bool { pub fn is_char(&self) -> bool {
!self.as_str().is_empty() && self.as_str().chars().skip(1).next().is_none() !self.as_str().is_empty() && self.as_str().chars().nth(1).is_none()
} }
pub fn defrock_brackets(self) -> Self { pub fn defrock_brackets(&self) -> Self {
fn defrock_brackets(s: &str) -> &str { fn defrock_brackets(s: &str) -> &str {
if s.starts_with('(') && s.ends_with(')') { if s.starts_with('(') && s.ends_with(')') {
&s[1 .. s.len() - 1] &s[1..s.len() - 1]
} else { } else {
s s
} }
} }
match self { match self {
ClauseName::BuiltIn(s) => ClauseName::BuiltIn(s) => ClauseName::BuiltIn(defrock_brackets(s)),
ClauseName::BuiltIn(defrock_brackets(s)), ClauseName::User(s) => {
ClauseName::User(s) =>
ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table)) ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table))
}
} }
} }
} }
impl AsRef<str> for ClauseName { impl AsRef<str> for ClauseName {
#[inline] #[inline]
fn as_ref(self: &Self) -> &str { fn as_ref(&self) -> &str {
self.as_str() self.as_str()
} }
} }
@@ -713,41 +706,45 @@ impl AsRef<str> for ClauseName {
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum Term { pub enum Term {
AnonVar, AnonVar,
Clause(Cell<RegType>, ClauseName, Vec<Box<Term>>, Option<SharedOpDesc>), Clause(
Cell<RegType>,
ClauseName,
Vec<Box<Term>>,
Option<SharedOpDesc>,
),
Cons(Cell<RegType>, Box<Term>, Box<Term>), Cons(Cell<RegType>, Box<Term>, Box<Term>),
Constant(Cell<RegType>, Constant), Constant(Cell<RegType>, Constant),
Var(Cell<VarReg>, Rc<Var>) Var(Cell<VarReg>, Rc<Var>),
} }
impl Term { impl Term {
pub fn shared_op_desc(&self) -> Option<SharedOpDesc> { pub fn shared_op_desc(&self) -> Option<SharedOpDesc> {
match self { match self {
&Term::Clause(_, _, _, ref spec) => spec.clone(), Term::Clause(_, _, _, ref spec) => spec.clone(),
&Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(), Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(),
_ => None _ => None,
} }
} }
pub fn to_constant(self) -> Option<Constant> { pub fn into_constant(self) -> Option<Constant> {
match self { match self {
Term::Constant(_, c) => Some(c), Term::Constant(_, c) => Some(c),
_ => None _ => None,
} }
} }
pub fn first_arg(&self) -> Option<&Term> { pub fn first_arg(&self) -> Option<&Term> {
match self { match self {
&Term::Clause(_, _, ref terms, _) => Term::Clause(_, _, ref terms, _) => terms.first().map(|bt| bt.as_ref()),
terms.first().map(|bt| bt.as_ref()), _ => None,
_ => None
} }
} }
pub fn set_name(&mut self, new_name: ClauseName) { pub fn set_name(&mut self, new_name: ClauseName) {
match self { match self {
Term::Constant(_, Constant::Atom(ref mut atom, _)) Term::Constant(_, Constant::Atom(ref mut atom, _))
| Term::Clause(_, ref mut atom, ..) => { | Term::Clause(_, ref mut atom, ..) => {
*atom = new_name; *atom = new_name;
} }
_ => {} _ => {}
} }
@@ -755,22 +752,23 @@ impl Term {
pub fn name(&self) -> Option<ClauseName> { pub fn name(&self) -> Option<ClauseName> {
match self { match self {
&Term::Constant(_, Constant::Atom(ref atom, _)) &Term::Constant(_, Constant::Atom(ref atom, _)) | &Term::Clause(_, ref atom, ..) => {
| &Term::Clause(_, ref atom, ..) => Some(atom.clone()), Some(atom.clone())
_ => None }
_ => None,
} }
} }
pub fn arity(&self) -> usize { pub fn arity(&self) -> usize {
match self { match self {
&Term::Clause(_, _, ref child_terms, ..) => child_terms.len(), Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
_ => 0 _ => 0,
} }
} }
} }
fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> { fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> {
if let &mut Term::Clause(_, ref name, ref mut subterms, _) = term { if let Term::Clause(_, ref name, ref mut subterms, _) = term {
if name.as_str() == s && subterms.len() == 2 { if name.as_str() == s && subterms.len() == 2 {
let snd = *subterms.pop().unwrap(); let snd = *subterms.pop().unwrap();
let fst = *subterms.pop().unwrap(); let fst = *subterms.pop().unwrap();

View File

@@ -1,9 +1,9 @@
use crate::lexical::parse_lossy;
use crate::ordered_float::*;
use crate::rug::Integer; use crate::rug::Integer;
use lexical::parse_lossy;
use ordered_float::*;
use ast::*; use crate::ast::*;
use tabled_rc::*; use crate::tabled_rc::*;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
@@ -11,13 +11,13 @@ use std::io::Read;
use std::rc::Rc; use std::rc::Rc;
macro_rules! is_not_eof { macro_rules! is_not_eof {
($c:expr) => ( ($c:expr) => {
match $c { match $c {
Ok(c) => c, Ok(c) => c,
Err(ParserError::UnexpectedEOF) => return Ok(true), Err($crate::ast::ParserError::UnexpectedEOF) => return Ok(true),
Err(e) => return Err(e) Err(e) => return Err(e),
} }
) };
} }
macro_rules! consume_chars_with { macro_rules! consume_chars_with {
@@ -26,27 +26,27 @@ macro_rules! consume_chars_with {
match $e { match $e {
Ok(Some(c)) => $token.push(c), Ok(Some(c)) => $token.push(c),
Ok(None) => continue, Ok(None) => continue,
Err(ParserError::UnexpectedChar(..)) => break, Err($crate::ast::ParserError::UnexpectedChar(..)) => break,
Err(e) => return Err(e) Err(e) => return Err(e),
} }
} }
} };
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum Token { pub enum Token {
Constant(Constant), Constant(Constant),
Var(Rc<Atom>), Var(Rc<Atom>),
Open, // '(' Open, // '('
OpenCT, // '(' OpenCT, // '('
Close, // ')' Close, // ')'
OpenList, // '[' OpenList, // '['
CloseList, // ']' CloseList, // ']'
OpenCurly, // '{' OpenCurly, // '{'
CloseCurly, // '}' CloseCurly, // '}'
HeadTailSeparator, // '|' HeadTailSeparator, // '|'
Comma, // ',' Comma, // ','
End End,
} }
pub struct Lexer<'a, R: Read> { pub struct Lexer<'a, R: Read> {
@@ -54,17 +54,17 @@ pub struct Lexer<'a, R: Read> {
pub(crate) reader: &'a mut ParsingStream<R>, pub(crate) reader: &'a mut ParsingStream<R>,
pub(crate) flags: MachineFlags, pub(crate) flags: MachineFlags,
pub(crate) line_num: usize, pub(crate) line_num: usize,
pub(crate) col_num: usize pub(crate) col_num: usize,
} }
impl<'a, R: Read + fmt::Debug> fmt::Debug for Lexer<'a, R> { impl<'a, R: Read + fmt::Debug> fmt::Debug for Lexer<'a, R> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Lexer") f.debug_struct("Lexer")
.field("atom_tbl", &self.atom_tbl) .field("atom_tbl", &self.atom_tbl)
.field("reader", &"&'a mut ParsingStream<R>") // Hacky solution. .field("reader", &"&'a mut ParsingStream<R>") // Hacky solution.
.field("line_num", &self.line_num) .field("line_num", &self.line_num)
.field("col_num", &self.col_num) .field("col_num", &self.col_num)
.finish() .finish()
} }
} }
@@ -74,7 +74,13 @@ impl<'a, R: Read> Lexer<'a, R> {
flags: MachineFlags, flags: MachineFlags,
src: &'a mut ParsingStream<R>, src: &'a mut ParsingStream<R>,
) -> Self { ) -> Self {
Lexer { atom_tbl, flags, reader: src, line_num: 0, col_num: 0 } Lexer {
atom_tbl,
flags,
reader: src,
line_num: 0,
col_num: 0,
}
} }
fn return_char(&mut self, c: char) { fn return_char(&mut self, c: char) {
@@ -128,8 +134,7 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
} }
fn single_line_comment(&mut self) -> Result<(), ParserError> fn single_line_comment(&mut self) -> Result<(), ParserError> {
{
loop { loop {
if self.reader.peek().is_none() || new_line_char!(self.skip_char()?) { if self.reader.peek().is_none() || new_line_char!(self.skip_char()?) {
break; break;
@@ -229,8 +234,7 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
} }
fn get_single_quoted_item(&mut self) -> Result<Option<char>, ParserError> fn get_single_quoted_item(&mut self) -> Result<Option<char>, ParserError> {
{
if backslash_char!(self.lookahead_char()?) { if backslash_char!(self.lookahead_char()?) {
let c = self.skip_char()?; let c = self.skip_char()?;
@@ -264,14 +268,13 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
} }
fn get_double_quoted_item(&mut self) -> Result<Option<char>, ParserError> fn get_double_quoted_item(&mut self) -> Result<Option<char>, ParserError> {
{
if backslash_char!(self.lookahead_char()?) { if backslash_char!(self.lookahead_char()?) {
let c = self.skip_char()?; let c = self.skip_char()?;
if new_line_char!(self.lookahead_char()?) { if new_line_char!(self.lookahead_char()?) {
self.skip_char()?; self.skip_char()?;
return Ok(None) return Ok(None);
} else { } else {
self.return_char(c); self.return_char(c);
} }
@@ -299,8 +302,7 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
} }
fn get_control_escape_sequence(&mut self) -> Result<char, ParserError> fn get_control_escape_sequence(&mut self) -> Result<char, ParserError> {
{
let escaped = match self.lookahead_char()? { let escaped = match self.lookahead_char()? {
'a' => '\u{07}', // UTF-8 alert 'a' => '\u{07}', // UTF-8 alert
'b' => '\u{08}', // UTF-8 backspace 'b' => '\u{08}', // UTF-8 backspace
@@ -309,20 +311,18 @@ impl<'a, R: Read> Lexer<'a, R> {
't' => '\t', 't' => '\t',
'n' => '\n', 'n' => '\n',
'r' => '\r', 'r' => '\r',
c => return Err(ParserError::UnexpectedChar(c, self.line_num, self.col_num)) c => return Err(ParserError::UnexpectedChar(c, self.line_num, self.col_num)),
}; };
self.skip_char()?; self.skip_char()?;
return Ok(escaped); return Ok(escaped);
} }
fn get_octal_escape_sequence(&mut self) -> Result<char, ParserError> fn get_octal_escape_sequence(&mut self) -> Result<char, ParserError> {
{
self.escape_sequence_to_char(|c| octal_digit_char!(c), 8) self.escape_sequence_to_char(|c| octal_digit_char!(c), 8)
} }
fn get_hexadecimal_escape_sequence(&mut self) -> Result<char, ParserError> fn get_hexadecimal_escape_sequence(&mut self) -> Result<char, ParserError> {
{
self.skip_char()?; self.skip_char()?;
let c = self.lookahead_char()?; let c = self.lookahead_char()?;
@@ -354,12 +354,13 @@ impl<'a, R: Read> Lexer<'a, R> {
if backslash_char!(c) { if backslash_char!(c) {
self.skip_char()?; self.skip_char()?;
u32::from_str_radix(&token, radix) u32::from_str_radix(&token, radix).map_or_else(
.map_or_else( |_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)),
|_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)), |n| {
|n| char::try_from(n) char::try_from(n)
.map_err(|_| ParserError::Utf8Error(self.line_num, self.col_num)) .map_err(|_| ParserError::Utf8Error(self.line_num, self.col_num))
) },
)
} else { } else {
// on failure, restore the token characters and backslash. // on failure, restore the token characters and backslash.
self.reader.put_back_all(token.chars().map(Ok)); self.reader.put_back_all(token.chars().map(Ok));
@@ -423,11 +424,8 @@ impl<'a, R: Read> Lexer<'a, R> {
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
Integer::from_str_radix(&token, 16) Integer::from_str_radix(&token, 16)
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
.map_err(|_| ParserError::ParseBigInt( .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.line_num,
self.col_num,
))
}) })
} else { } else {
self.return_char('x'); self.return_char('x');
@@ -449,11 +447,8 @@ impl<'a, R: Read> Lexer<'a, R> {
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
Integer::from_str_radix(&token, 8) Integer::from_str_radix(&token, 8)
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
.map_err(|_| ParserError::ParseBigInt( .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.line_num,
self.col_num,
))
}) })
} else { } else {
self.return_char('o'); self.return_char('o');
@@ -475,11 +470,8 @@ impl<'a, R: Read> Lexer<'a, R> {
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
Integer::from_str_radix(&token, 2) Integer::from_str_radix(&token, 2)
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
.map_err(|_| ParserError::ParseBigInt( .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.line_num,
self.col_num,
))
}) })
} else { } else {
self.return_char('b'); self.return_char('b');
@@ -525,18 +517,20 @@ impl<'a, R: Read> Lexer<'a, R> {
if single_quote_char!(self.lookahead_char()?) { if single_quote_char!(self.lookahead_char()?) {
self.skip_char()?; self.skip_char()?;
if !token.is_empty() && token.chars().skip(1).next().is_none() { if !token.is_empty() && token.chars().nth(1).is_none() {
if let Some(c) = token.chars().next() { if let Some(c) = token.chars().next() {
return Ok(Token::Constant(Constant::Char(c))); return Ok(Token::Constant(Constant::Char(c)));
} }
} }
} else { } else {
return Err(ParserError::InvalidSingleQuotedCharacter(self.lookahead_char()?)) return Err(ParserError::InvalidSingleQuotedCharacter(
self.lookahead_char()?,
));
} }
} else { } else {
match self.get_back_quoted_string() { match self.get_back_quoted_string() {
Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)), Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)),
Err(e) => return Err(e) Err(e) => return Err(e),
} }
} }
@@ -575,12 +569,10 @@ impl<'a, R: Read> Lexer<'a, R> {
isize::from_str_radix(&token, 10) isize::from_str_radix(&token, 10)
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
token.parse::<Integer>() token
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .parse::<Integer>()
.map_err(|_| ParserError::ParseBigInt( .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
self.line_num, .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.col_num,
))
}) })
} else if decimal_digit_char!(self.lookahead_char()?) { } else if decimal_digit_char!(self.lookahead_char()?) {
token.push('.'); token.push('.');
@@ -599,7 +591,7 @@ impl<'a, R: Read> Lexer<'a, R> {
let c = match self.lookahead_char() { let c = match self.lookahead_char() {
Err(_) => return Ok(self.vacate_with_float(token)), Err(_) => return Ok(self.vacate_with_float(token)),
Ok(c) => c Ok(c) => c,
}; };
if !sign_char!(c) && !decimal_digit_char!(c) { if !sign_char!(c) && !decimal_digit_char!(c) {
@@ -613,8 +605,8 @@ impl<'a, R: Read> Lexer<'a, R> {
Err(_) => { Err(_) => {
self.return_char(token.pop().unwrap()); self.return_char(token.pop().unwrap());
return Ok(self.vacate_with_float(token)); return Ok(self.vacate_with_float(token));
}, }
Ok(c) => c Ok(c) => c,
}; };
if !decimal_digit_char!(c) { if !decimal_digit_char!(c) {
@@ -645,70 +637,65 @@ impl<'a, R: Read> Lexer<'a, R> {
isize::from_str_radix(&token, 10) isize::from_str_radix(&token, 10)
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
token.parse::<Integer>() token
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .parse::<Integer>()
.map_err(|_| ParserError::ParseBigInt( .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
self.line_num, .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.col_num,
))
}) })
} }
} else { } else {
if token.starts_with('0') && token.len() == 1 { if token.starts_with('0') && token.len() == 1 {
if c == 'x' { if c == 'x' {
self.hexadecimal_constant() self.hexadecimal_constant().or_else(|e| {
.or_else(|e| { if let ParserError::ParseBigInt(..) = e {
if let ParserError::ParseBigInt(..) = e { isize::from_str_radix(&token, 10)
isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n)))
.map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| {
.or_else(|_| { token
token.parse::<Integer>() .parse::<Integer>()
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
.map_err(|_| ParserError::ParseBigInt( .map_err(|_| {
self.line_num, ParserError::ParseBigInt(self.line_num, self.col_num)
self.col_num, })
)) })
}) } else {
} else { Err(e)
Err(e) }
} })
})
} else if c == 'o' { } else if c == 'o' {
self.octal_constant() self.octal_constant().or_else(|e| {
.or_else(|e| { if let ParserError::ParseBigInt(..) = e {
if let ParserError::ParseBigInt(..) = e { isize::from_str_radix(&token, 10)
isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n)))
.map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| {
.or_else(|_| { token
token.parse::<Integer>() .parse::<Integer>()
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
.map_err(|_| ParserError::ParseBigInt( .map_err(|_| {
self.line_num, ParserError::ParseBigInt(self.line_num, self.col_num)
self.col_num, })
)) })
}) } else {
} else { Err(e)
Err(e) }
} })
})
} else if c == 'b' { } else if c == 'b' {
self.binary_constant() self.binary_constant().or_else(|e| {
.or_else(|e| { if let ParserError::ParseBigInt(..) = e {
if let ParserError::ParseBigInt(..) = e { isize::from_str_radix(&token, 10)
isize::from_str_radix(&token, 10) .map(|n| Token::Constant(Constant::Fixnum(n)))
.map(|n| Token::Constant(Constant::Fixnum(n))) .or_else(|_| {
.or_else(|_| { token
token.parse::<Integer>() .parse::<Integer>()
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
.map_err(|_| ParserError::ParseBigInt( .map_err(|_| {
self.line_num, ParserError::ParseBigInt(self.line_num, self.col_num)
self.col_num, })
)) })
}) } else {
} else { Err(e)
Err(e) }
} })
})
} else if single_quote_char!(c) { } else if single_quote_char!(c) {
self.skip_char()?; self.skip_char()?;
@@ -726,45 +713,39 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
self.get_single_quoted_char() self.get_single_quoted_char()
.and_then(|c| { .map(|c| Token::Constant(Constant::Fixnum(c as isize)))
Ok(Token::Constant(Constant::Fixnum(c as isize)))
})
.or_else(|_| { .or_else(|_| {
self.return_char(c); self.return_char(c);
isize::from_str_radix(&token, 10) isize::from_str_radix(&token, 10)
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
token.parse::<Integer>() token
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .parse::<Integer>()
.map_err(|_| ParserError::ParseBigInt( .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
self.line_num, .map_err(|_| {
self.col_num, ParserError::ParseBigInt(self.line_num, self.col_num)
)) })
}) })
}) })
} else { } else {
isize::from_str_radix(&token, 10) isize::from_str_radix(&token, 10)
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
token.parse::<Integer>() token
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .parse::<Integer>()
.map_err(|_| ParserError::ParseBigInt( .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
self.line_num, .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.col_num,
))
}) })
} }
} else { } else {
isize::from_str_radix(&token, 10) isize::from_str_radix(&token, 10)
.map(|n| Token::Constant(Constant::Fixnum(n))) .map(|n| Token::Constant(Constant::Fixnum(n)))
.or_else(|_| { .or_else(|_| {
token.parse::<Integer>() token
.map(|n| Token::Constant(Constant::Integer(Rc::new(n)))) .parse::<Integer>()
.map_err(|_| ParserError::ParseBigInt( .map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
self.line_num, .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
self.col_num,
))
}) })
} }
} }
@@ -781,18 +762,19 @@ impl<'a, R: Read> Lexer<'a, R> {
Ok(c) if layout_char!(c) || new_line_char!(c) => { Ok(c) if layout_char!(c) || new_line_char!(c) => {
self.skip_char()?; self.skip_char()?;
layout_inserted = true; layout_inserted = true;
}, }
Ok(c) if end_line_comment_char!(c) => { Ok(c) if end_line_comment_char!(c) => {
self.single_line_comment()?; self.single_line_comment()?;
layout_inserted = true; layout_inserted = true;
}, }
Ok(c) if comment_1_char!(c) => Ok(c) if comment_1_char!(c) => {
if self.bracketed_comment()? { if self.bracketed_comment()? {
layout_inserted = true; layout_inserted = true;
} else { } else {
more_layout = false; more_layout = false;
}, }
_ => more_layout = false }
_ => more_layout = false,
}; };
if !more_layout { if !more_layout {
@@ -825,8 +807,11 @@ impl<'a, R: Read> Lexer<'a, R> {
if c == '(' { if c == '(' {
self.skip_char()?; self.skip_char()?;
return Ok(if layout_inserted { Token::Open } return Ok(if layout_inserted {
else { Token::OpenCT }); Token::Open
} else {
Token::OpenCT
});
} }
if c == '.' { if c == '.' {
@@ -839,7 +824,7 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
return Ok(Token::End); return Ok(Token::End);
}, }
Err(ParserError::UnexpectedEOF) => { Err(ParserError::UnexpectedEOF) => {
return Ok(Token::End); return Ok(Token::End);
} }
@@ -891,8 +876,8 @@ impl<'a, R: Read> Lexer<'a, R> {
} }
self.name_token(c) self.name_token(c)
}, }
Err(e) => Err(e) Err(e) => Err(e),
} }
} }
} }

View File

@@ -1,14 +1,14 @@
extern crate lexical;
extern crate ordered_float;
#[cfg(feature = "rug")]
extern crate rug;
#[cfg(feature = "num-rug-adapter")] #[cfg(feature = "num-rug-adapter")]
extern crate num_rug_adapter as rug; use num_rug_adapter as rug;
extern crate unicode_reader; #[cfg(feature = "rug")]
use rug;
#[macro_use] pub mod tabled_rc; #[macro_use]
#[macro_use] pub mod ast; pub mod tabled_rc;
#[macro_use] pub mod macros; #[macro_use]
pub mod ast;
#[macro_use]
pub mod macros;
pub mod parser; pub mod parser;
pub mod put_back_n; pub mod put_back_n;

View File

@@ -1,187 +1,246 @@
#[macro_export] #[macro_export]
macro_rules! char_class { macro_rules! char_class {
($c: expr, [$head:expr]) => ($c == $head); ($c: expr, [$head:expr]) => ($c == $head);
($c: expr, [$head:expr $(, $cs:expr)+]) => ($c == $head || char_class!($c, [$($cs),*])); ($c: expr, [$head:expr $(, $cs:expr)+]) => ($c == $head || $crate::char_class!($c, [$($cs),*]));
} }
#[macro_export] #[macro_export]
macro_rules! symbolic_control_char { macro_rules! symbolic_control_char {
($c: expr) => (char_class!($c, ['a', 'b', 'f', 'n', 'r', 't', 'v', '0'])) ($c: expr) => {
$crate::char_class!($c, ['a', 'b', 'f', 'n', 'r', 't', 'v', '0'])
};
} }
#[macro_export] #[macro_export]
macro_rules! space_char { macro_rules! space_char {
($c: expr) => ($c == ' ') ($c: expr) => {
$c == ' '
};
} }
#[macro_export] #[macro_export]
macro_rules! layout_char { macro_rules! layout_char {
($c: expr) => (char_class!($c, [' ', '\n', '\t', '\u{0B}', '\u{0C}'])) ($c: expr) => {
$crate::char_class!($c, [' ', '\n', '\t', '\u{0B}', '\u{0C}'])
};
} }
#[macro_export] #[macro_export]
macro_rules! symbolic_hexadecimal_char { macro_rules! symbolic_hexadecimal_char {
($c: expr) => ($c == 'x') ($c: expr) => {
$c == 'x'
};
} }
#[macro_export] #[macro_export]
macro_rules! octal_digit_char { macro_rules! octal_digit_char {
($c: expr) => ($c >= '0' && $c <= '7') ($c: expr) => {
('0'..='7').contains(&$c)
};
} }
#[macro_export] #[macro_export]
macro_rules! binary_digit_char { macro_rules! binary_digit_char {
($c: expr) => ($c >= '0' && $c <= '1') ($c: expr) => {
$c >= '0' && $c <= '1'
};
} }
#[macro_export] #[macro_export]
macro_rules! hexadecimal_digit_char { macro_rules! hexadecimal_digit_char {
($c: expr) => ($c >= '0' && $c <= '9' || ($c: expr) => {
$c >= 'A' && $c <= 'F' || ('0'..='9').contains(&$c) || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c)
$c >= 'a' && $c <= 'f') };
} }
#[macro_export] #[macro_export]
macro_rules! exponent_char { macro_rules! exponent_char {
($c: expr) => ($c == 'e' || $c == 'E') ($c: expr) => {
$c == 'e' || $c == 'E'
};
} }
#[macro_export] #[macro_export]
macro_rules! sign_char { macro_rules! sign_char {
($c: expr) => ($c == '-' || $c == '+') ($c: expr) => {
$c == '-' || $c == '+'
};
} }
#[macro_export] #[macro_export]
macro_rules! new_line_char { macro_rules! new_line_char {
($c: expr) => ($c == '\n') ($c: expr) => {
$c == '\n'
};
} }
#[macro_export] #[macro_export]
macro_rules! end_line_comment_char { macro_rules! end_line_comment_char {
($c: expr) => ($c == '%') ($c: expr) => {
$c == '%'
};
} }
#[macro_export] #[macro_export]
macro_rules! comment_1_char { macro_rules! comment_1_char {
($c: expr) => ($c == '/') ($c: expr) => {
$c == '/'
};
} }
#[macro_export] #[macro_export]
macro_rules! comment_2_char { macro_rules! comment_2_char {
($c: expr) => ($c == '*') ($c: expr) => {
$c == '*'
};
} }
#[macro_export] #[macro_export]
macro_rules! capital_letter_char { macro_rules! capital_letter_char {
($c: expr) => ($c >= 'A' && $c <= 'Z') ($c: expr) => {
('A'..='Z').contains(&$c)
};
} }
#[macro_export] #[macro_export]
macro_rules! small_letter_char { macro_rules! small_letter_char {
($c: expr) => ($c >= 'a' && $c <= 'z') ($c: expr) => {
('a'..='z').contains(&$c)
};
} }
#[macro_export] #[macro_export]
macro_rules! variable_indicator_char { macro_rules! variable_indicator_char {
($c: expr) => ($c == '_') ($c: expr) => {
$c == '_'
};
} }
#[macro_export] #[macro_export]
macro_rules! graphic_char { macro_rules! graphic_char {
($c: expr) => (char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':', ($c: expr) => ($crate::char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':',
'<', '=', '>', '?', '@', '^', '~'])) '<', '=', '>', '?', '@', '^', '~']))
} }
#[macro_export] #[macro_export]
macro_rules! graphic_token_char { macro_rules! graphic_token_char {
($c: expr) => (graphic_char!($c) || backslash_char!($c)) ($c: expr) => {
$crate::graphic_char!($c) || $crate::backslash_char!($c)
};
} }
#[macro_export] #[macro_export]
macro_rules! alpha_char { macro_rules! alpha_char {
($c: expr) => ($c: expr) => {
(match $c { match $c {
'a' ..= 'z' => true, 'a'..='z' => true,
'A' ..= 'Z' => true, 'A'..='Z' => true,
'_' => true, '_' => true,
'\u{00A0}' ..= '\u{00BF}' => true, '\u{00A0}'..='\u{00BF}' => true,
'\u{00C0}' ..= '\u{00D6}' => true, '\u{00C0}'..='\u{00D6}' => true,
'\u{00D8}' ..= '\u{00F6}' => true, '\u{00D8}'..='\u{00F6}' => true,
'\u{00F8}' ..= '\u{00FF}' => true, '\u{00F8}'..='\u{00FF}' => true,
'\u{0100}' ..= '\u{017F}' => true, // Latin Extended-A '\u{0100}'..='\u{017F}' => true, // Latin Extended-A
'\u{0180}' ..= '\u{024F}' => true, // Latin Extended-B '\u{0180}'..='\u{024F}' => true, // Latin Extended-B
'\u{0250}' ..= '\u{02AF}' => true, // IPA Extensions '\u{0250}'..='\u{02AF}' => true, // IPA Extensions
'\u{02B0}' ..= '\u{02FF}' => true, // Spacing Modifier Letters '\u{02B0}'..='\u{02FF}' => true, // Spacing Modifier Letters
'\u{0300}' ..= '\u{036F}' => true, // Combining Diacritical Marks '\u{0300}'..='\u{036F}' => true, // Combining Diacritical Marks
'\u{0370}' ..= '\u{03FF}' => true, // Greek/Coptic '\u{0370}'..='\u{03FF}' => true, // Greek/Coptic
'\u{0400}' ..= '\u{04FF}' => true, // Cyrillic '\u{0400}'..='\u{04FF}' => true, // Cyrillic
'\u{0500}' ..= '\u{052F}' => true, // Cyrillic Supplement '\u{0500}'..='\u{052F}' => true, // Cyrillic Supplement
'\u{0530}' ..= '\u{058F}' => true, // Armenian '\u{0530}'..='\u{058F}' => true, // Armenian
'\u{0590}' ..= '\u{05FF}' => true, // Hebrew '\u{0590}'..='\u{05FF}' => true, // Hebrew
'\u{0600}' ..= '\u{06FF}' => true, // Arabic '\u{0600}'..='\u{06FF}' => true, // Arabic
'\u{0700}' ..= '\u{074F}' => true, // Syriac '\u{0700}'..='\u{074F}' => true, // Syriac
_ => false _ => false,
}) }
};
} }
#[macro_export] #[macro_export]
macro_rules! decimal_digit_char { macro_rules! decimal_digit_char {
($c: expr) => ($c >= '0' && $c <= '9') ($c: expr) => {
('0'..='9').contains(&$c)
};
} }
#[macro_export] #[macro_export]
macro_rules! decimal_point_char { macro_rules! decimal_point_char {
($c: expr) => ($c == '.') ($c: expr) => {
$c == '.'
};
} }
#[macro_export] #[macro_export]
macro_rules! alpha_numeric_char { macro_rules! alpha_numeric_char {
($c: expr) => (alpha_char!($c) || decimal_digit_char!($c)) ($c: expr) => {
$crate::alpha_char!($c) || $crate::decimal_digit_char!($c)
};
} }
#[macro_export] #[macro_export]
macro_rules! cut_char { macro_rules! cut_char {
($c: expr) => ($c == '!') ($c: expr) => {
$c == '!'
};
} }
#[macro_export] #[macro_export]
macro_rules! semicolon_char { macro_rules! semicolon_char {
($c: expr) => ($c == ';') ($c: expr) => {
$c == ';'
};
} }
#[macro_export] #[macro_export]
macro_rules! backslash_char { macro_rules! backslash_char {
($c: expr) => ($c == '\\') ($c: expr) => {
$c == '\\'
};
} }
#[macro_export] #[macro_export]
macro_rules! single_quote_char { macro_rules! single_quote_char {
($c: expr) => ($c == '\'') ($c: expr) => {
$c == '\''
};
} }
#[macro_export] #[macro_export]
macro_rules! double_quote_char { macro_rules! double_quote_char {
($c: expr) => ($c == '"') ($c: expr) => {
$c == '"'
};
} }
#[macro_export] #[macro_export]
macro_rules! back_quote_char { macro_rules! back_quote_char {
($c: expr) => ($c == '`') ($c: expr) => {
$c == '`'
};
} }
#[macro_export] #[macro_export]
macro_rules! meta_char { macro_rules! meta_char {
($c: expr) => ( char_class!($c, ['\\', '\'', '"', '`']) ) ($c: expr) => {
$crate::char_class!($c, ['\\', '\'', '"', '`'])
};
} }
#[macro_export] #[macro_export]
macro_rules! solo_char { macro_rules! solo_char {
($c: expr) => ( char_class!($c, ['!', '(', ')', ',', ';', '[', ']', ($c: expr) => {
'{', '}', '|', '%']) ) $crate::char_class!($c, ['!', '(', ')', ',', ';', '[', ']', '{', '}', '|', '%'])
};
} }
#[macro_export] #[macro_export]
macro_rules! prolog_char { macro_rules! prolog_char {
($c: expr) => (graphic_char!($c) || alpha_numeric_char!($c) || solo_char!($c) || ($c: expr) => {
layout_char!($c) || meta_char!($c)) $crate::graphic_char!($c)
|| $crate::alpha_numeric_char!($c)
|| $crate::solo_char!($c)
|| $crate::layout_char!($c)
|| $crate::meta_char!($c)
};
} }

View File

@@ -1,10 +1,10 @@
use ast::*; use crate::ast::*;
use lexer::*; use crate::lexer::*;
use tabled_rc::*; use crate::tabled_rc::*;
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use rug::ops::NegAssign; use crate::rug::ops::NegAssign;
use std::cell::Cell; use std::cell::Cell;
use std::io::Read; use std::io::Read;
@@ -16,25 +16,30 @@ enum TokenType {
Term, Term,
Open, Open,
OpenCT, OpenCT,
OpenList, // '[' OpenList, // '['
OpenCurly, // '{' OpenCurly, // '{'
HeadTailSeparator, // '|' HeadTailSeparator, // '|'
Comma, // ',' Comma, // ','
Close, Close,
CloseList, // ']' CloseList, // ']'
CloseCurly, // '}' CloseCurly, // '}'
End End,
} }
impl TokenType { impl TokenType {
fn is_sep(self) -> bool { fn is_sep(self) -> bool {
match self { matches!(
TokenType::HeadTailSeparator | TokenType::OpenCT | TokenType::Open | self,
TokenType::Close | TokenType::OpenList | TokenType::CloseList | TokenType::HeadTailSeparator
TokenType::OpenCurly | TokenType::CloseCurly | TokenType::Comma | TokenType::OpenCT
=> true, | TokenType::Open
_ => false | TokenType::Close
} | TokenType::OpenList
| TokenType::CloseList
| TokenType::OpenCurly
| TokenType::CloseCurly
| TokenType::Comma
)
} }
} }
@@ -42,12 +47,14 @@ impl TokenType {
struct TokenDesc { struct TokenDesc {
tt: TokenType, tt: TokenType,
priority: usize, priority: usize,
spec: u32 spec: u32,
} }
pub pub fn get_clause_spec(
fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> Option<SharedOpDesc> name: ClauseName,
{ arity: usize,
op_dir: &CompositeOpDir,
) -> Option<SharedOpDesc> {
match arity { match arity {
1 => { 1 => {
/* This is a clause with an operator principal functor. Prefix operators /* This is a clause with an operator principal functor. Prefix operators
@@ -60,20 +67,25 @@ fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> O
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::Post) { if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::Post) {
return Some(cell.clone()); return Some(cell.clone());
} }
}, }
2 => 2 => {
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::In) { if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::In) {
return Some(cell.clone()); return Some(cell.clone());
}, }
}
_ => {} _ => {}
}; };
None None
} }
pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc> pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc> {
{ let mut op_desc = OpDesc {
let mut op_desc = OpDesc { pre: 0, inf: 0, post: 0, spec: 0 }; pre: 0,
inf: 0,
post: 0,
spec: 0,
};
if let Some(OpDirValue(cell)) = op_dir.get(name.clone(), Fixity::Pre) { if let Some(OpDirValue(cell)) = op_dir.get(name.clone(), Fixity::Pre) {
let (pri, spec) = cell.get(); let (pri, spec) = cell.get();
@@ -111,8 +123,7 @@ pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc>
} }
} }
fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool {
{
d2.priority <= priority d2.priority <= priority
&& is_term!(d3.spec) && is_term!(d3.spec)
&& is_term!(d1.spec) && is_term!(d1.spec)
@@ -120,18 +131,15 @@ fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b
&& d1.priority < d2.priority && d1.priority < d2.priority
} }
fn affirm_yfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool fn affirm_yfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool {
{
d2.priority <= priority d2.priority <= priority
&& ((is_term!(d3.spec) && d3.priority < d2.priority) && ((is_term!(d3.spec) && d3.priority < d2.priority)
|| (is_lterm!(d3.spec) && d3.priority == d2.priority)) || (is_lterm!(d3.spec) && d3.priority == d2.priority))
&& is_term!(d1.spec) && is_term!(d1.spec)
&& d1.priority < d2.priority && d1.priority < d2.priority
} }
fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool {
fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool
{
d2.priority < priority d2.priority < priority
&& is_term!(d3.spec) && is_term!(d3.spec)
&& d3.priority < d2.priority && d3.priority < d2.priority
@@ -139,49 +147,35 @@ fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b
&& d1.priority <= d2.priority && d1.priority <= d2.priority
} }
fn affirm_yf(d1: TokenDesc, d2: TokenDesc) -> bool fn affirm_yf(d1: TokenDesc, d2: TokenDesc) -> bool {
{
let is_valid_lterm = is_lterm!(d2.spec) && d2.priority == d1.priority; let is_valid_lterm = is_lterm!(d2.spec) && d2.priority == d1.priority;
(is_term!(d2.spec) && d2.priority < d1.priority) || is_valid_lterm (is_term!(d2.spec) && d2.priority < d1.priority) || is_valid_lterm
} }
fn affirm_xf(d1: TokenDesc, d2: TokenDesc) -> bool fn affirm_xf(d1: TokenDesc, d2: TokenDesc) -> bool {
{
is_term!(d2.spec) && d2.priority < d1.priority is_term!(d2.spec) && d2.priority < d1.priority
} }
fn affirm_fy(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool fn affirm_fy(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool {
{
d2.priority < priority && is_term!(d1.spec) && d1.priority <= d2.priority d2.priority < priority && is_term!(d1.spec) && d1.priority <= d2.priority
} }
fn affirm_fx(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool fn affirm_fx(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool {
{
d2.priority <= priority && is_term!(d1.spec) && d1.priority < d2.priority d2.priority <= priority && is_term!(d1.spec) && d1.priority < d2.priority
} }
fn sep_to_atom(tt: TokenType) -> Option<ClauseName> fn sep_to_atom(tt: TokenType) -> Option<ClauseName> {
{
match tt { match tt {
TokenType::Open | TokenType::OpenCT => TokenType::Open | TokenType::OpenCT => Some(clause_name!("(")),
Some(clause_name!("(")), TokenType::Close => Some(clause_name!(")")),
TokenType::Close => TokenType::OpenList => Some(clause_name!("[")),
Some(clause_name!(")")), TokenType::CloseList => Some(clause_name!("]")),
TokenType::OpenList => TokenType::OpenCurly => Some(clause_name!("{")),
Some(clause_name!("[")), TokenType::CloseCurly => Some(clause_name!("}")),
TokenType::CloseList => TokenType::HeadTailSeparator => Some(clause_name!("|")),
Some(clause_name!("]")), TokenType::Comma => Some(clause_name!(",")),
TokenType::OpenCurly => TokenType::End => Some(clause_name!(".")),
Some(clause_name!("{")), _ => None,
TokenType::CloseCurly =>
Some(clause_name!("}")),
TokenType::HeadTailSeparator =>
Some(clause_name!("|")),
TokenType::Comma =>
Some(clause_name!(",")),
TokenType::End =>
Some(clause_name!(".")),
_ => None
} }
} }
@@ -190,7 +184,7 @@ pub struct OpDesc {
pub pre: usize, pub pre: usize,
pub inf: usize, pub inf: usize,
pub post: usize, pub post: usize,
pub spec: Specifier pub spec: Specifier,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -201,8 +195,7 @@ pub struct Parser<'a, R: Read> {
terms: Vec<Term>, terms: Vec<Term>,
} }
fn read_tokens<'a, R: Read>(lexer: &mut Lexer<'a, R>) -> Result<Vec<Token>, ParserError> fn read_tokens<R: Read>(lexer: &mut Lexer<R>) -> Result<Vec<Token>, ParserError> {
{
let mut tokens = vec![]; let mut tokens = vec![];
loop { loop {
@@ -227,10 +220,12 @@ impl<'a, R: Read> Parser<'a, R> {
atom_tbl: TabledData<Atom>, atom_tbl: TabledData<Atom>,
flags: MachineFlags, flags: MachineFlags,
) -> Self { ) -> Self {
Parser { lexer: Lexer::new(atom_tbl, flags, stream), Parser {
tokens: vec![], lexer: Lexer::new(atom_tbl, flags, stream),
stack: Vec::new(), tokens: vec![],
terms: Vec::new() } stack: Vec::new(),
terms: Vec::new(),
}
} }
#[inline] #[inline]
@@ -255,50 +250,46 @@ impl<'a, R: Read> Parser<'a, R> {
fn get_term_name(&mut self, td: TokenDesc) -> Option<(ClauseName, Option<SharedOpDesc>)> { fn get_term_name(&mut self, td: TokenDesc) -> Option<(ClauseName, Option<SharedOpDesc>)> {
match td.tt { match td.tt {
TokenType::HeadTailSeparator => { TokenType::HeadTailSeparator => Some((
Some((clause_name!("|"), Some(SharedOpDesc::new(td.priority, td.spec)))) clause_name!("|"),
} Some(SharedOpDesc::new(td.priority, td.spec)),
TokenType::Comma => { )),
Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY)))) TokenType::Comma => Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY)))),
} TokenType::Term => match self.terms.pop() {
TokenType::Term => { Some(Term::Constant(_, Constant::Atom(atom, spec))) => Some((atom, spec)),
match self.terms.pop() { Some(term) => {
Some(Term::Constant(_, Constant::Atom(atom, spec))) => self.terms.push(term);
Some((atom, spec)), None
Some(term) => {
self.terms.push(term);
None
},
_ => None
} }
} _ => None,
_ => { },
None _ => None,
}
} }
} }
fn push_binary_op(&mut self, td: TokenDesc, spec: Specifier) fn push_binary_op(&mut self, td: TokenDesc, spec: Specifier) {
{
if let Some(arg2) = self.terms.pop() { if let Some(arg2) = self.terms.pop() {
if let Some((name, shared_op_desc)) = self.get_term_name(td) { if let Some((name, shared_op_desc)) = self.get_term_name(td) {
if let Some(arg1) = self.terms.pop() { if let Some(arg1) = self.terms.pop() {
let term = Term::Clause(Cell::default(), let term = Term::Clause(
name, Cell::default(),
vec![Box::new(arg1), Box::new(arg2)], name,
shared_op_desc); vec![Box::new(arg1), Box::new(arg2)],
shared_op_desc,
);
self.terms.push(term); self.terms.push(term);
self.stack.push(TokenDesc { tt: TokenType::Term, self.stack.push(TokenDesc {
priority: td.priority, tt: TokenType::Term,
spec }); priority: td.priority,
spec,
});
} }
} }
} }
} }
fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32) fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32) {
{
if let Some(mut arg1) = self.terms.pop() { if let Some(mut arg1) = self.terms.pop() {
if let Some(mut name) = self.terms.pop() { if let Some(mut name) = self.terms.pop() {
if is_postfix!(assoc) { if is_postfix!(assoc) {
@@ -306,52 +297,61 @@ impl<'a, R: Read> Parser<'a, R> {
} }
if let Term::Constant(_, Constant::Atom(name, shared_op_desc)) = name { if let Term::Constant(_, Constant::Atom(name, shared_op_desc)) = name {
let term = Term::Clause(Cell::default(), name, vec![Box::new(arg1)], let term =
shared_op_desc); Term::Clause(Cell::default(), name, vec![Box::new(arg1)], shared_op_desc);
self.terms.push(term); self.terms.push(term);
self.stack.push(TokenDesc { tt: TokenType::Term, self.stack.push(TokenDesc {
priority: td.priority, tt: TokenType::Term,
spec }); priority: td.priority,
spec,
});
} }
} }
} }
} }
fn promote_atom_op(&mut self, atom: ClauseName, priority: usize, assoc: u32, fn promote_atom_op(
op_dir_val: Option<&OpDirValue>) &mut self,
{ atom: ClauseName,
priority: usize,
assoc: u32,
op_dir_val: Option<&OpDirValue>,
) {
let spec = op_dir_val.map(|op_dir_val| op_dir_val.shared_op_desc()); let spec = op_dir_val.map(|op_dir_val| op_dir_val.shared_op_desc());
self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, spec))); self.terms
self.stack.push(TokenDesc { tt: TokenType::Term, priority, spec: assoc }); .push(Term::Constant(Cell::default(), Constant::Atom(atom, spec)));
self.stack.push(TokenDesc {
tt: TokenType::Term,
priority,
spec: assoc,
});
} }
fn shift(&mut self, token: Token, priority: usize, spec: Specifier) fn shift(&mut self, token: Token, priority: usize, spec: Specifier) {
{
let tt = match token { let tt = match token {
Token::Constant(Constant::String(s)) Token::Constant(Constant::String(s)) if self.lexer.flags.double_quotes.is_codes() => {
if self.lexer.flags.double_quotes.is_codes() => { let mut list = Term::Constant(Cell::default(), Constant::EmptyList);
let mut list = Term::Constant(Cell::default(), Constant::EmptyList);
for c in s.chars().rev() { for c in s.chars().rev() {
list = Term::Cons( list = Term::Cons(
Cell::default(),
Box::new(Term::Constant(
Cell::default(), Cell::default(),
Box::new(Term::Constant( Constant::Fixnum(c as isize),
Cell::default(), )),
Constant::Fixnum(c as isize), Box::new(list),
)), );
Box::new(list),
);
}
self.terms.push(list);
TokenType::Term
} }
self.terms.push(list);
TokenType::Term
}
Token::Constant(c) => { Token::Constant(c) => {
self.terms.push(Term::Constant(Cell::default(), c)); self.terms.push(Term::Constant(Cell::default(), c));
TokenType::Term TokenType::Term
}, }
Token::Var(v) => { Token::Var(v) => {
if v.trim() == "_" { if v.trim() == "_" {
self.terms.push(Term::AnonVar); self.terms.push(Term::AnonVar);
@@ -360,7 +360,7 @@ impl<'a, R: Read> Parser<'a, R> {
} }
TokenType::Term TokenType::Term
}, }
Token::Comma => TokenType::Comma, Token::Comma => TokenType::Comma,
Token::Open => TokenType::Open, Token::Open => TokenType::Open,
Token::Close => TokenType::Close, Token::Close => TokenType::Close,
@@ -381,18 +381,13 @@ impl<'a, R: Read> Parser<'a, R> {
if let Some(desc1) = self.stack.pop() { if let Some(desc1) = self.stack.pop() {
if let Some(desc2) = self.stack.pop() { if let Some(desc2) = self.stack.pop() {
if let Some(desc3) = self.stack.pop() { if let Some(desc3) = self.stack.pop() {
if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1) if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1) {
{
self.push_binary_op(desc2, LTERM); self.push_binary_op(desc2, LTERM);
continue; continue;
} } else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1) {
else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1)
{
self.push_binary_op(desc2, LTERM); self.push_binary_op(desc2, LTERM);
continue; continue;
} } else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1) {
else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1)
{
self.push_binary_op(desc2, TERM); self.push_binary_op(desc2, TERM);
continue; continue;
} else { } else {
@@ -425,12 +420,12 @@ impl<'a, R: Read> Parser<'a, R> {
} }
} }
fn compute_arity_in_brackets(&self) -> Option<usize> fn compute_arity_in_brackets(&self) -> Option<usize> {
{
let mut arity = 0; let mut arity = 0;
for (i, desc) in self.stack.iter().rev().enumerate() { for (i, desc) in self.stack.iter().rev().enumerate() {
if i % 2 == 0 { // expect a term or non-comma operator. if i % 2 == 0 {
// expect a term or non-comma operator.
if let TokenType::Comma = desc.tt { if let TokenType::Comma = desc.tt {
return None; return None;
} else if is_term!(desc.spec) || is_op!(desc.spec) || is_negate!(desc.spec) { } else if is_term!(desc.spec) || is_op!(desc.spec) || is_negate!(desc.spec) {
@@ -454,8 +449,7 @@ impl<'a, R: Read> Parser<'a, R> {
None None
} }
fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool {
{
if self.stack.is_empty() { if self.stack.is_empty() {
return false; return false;
} }
@@ -464,7 +458,7 @@ impl<'a, R: Read> Parser<'a, R> {
let arity = match self.compute_arity_in_brackets() { let arity = match self.compute_arity_in_brackets() {
Some(arity) => arity, Some(arity) => arity,
None => return false None => return false,
}; };
if self.stack.len() > 2 * arity { if self.stack.len() > 2 * arity {
@@ -490,9 +484,7 @@ impl<'a, R: Read> Parser<'a, R> {
if self.atomize_term(&self.terms[idx - 1]).is_some() { if self.atomize_term(&self.terms[idx - 1]).is_some() {
self.stack.truncate(stack_len + 1); self.stack.truncate(stack_len + 1);
let mut subterms: Vec<_> = self.terms.drain(idx ..) let mut subterms: Vec<_> = self.terms.drain(idx..).map(Box::new).collect();
.map(|t| Box::new(t))
.collect();
if let Some(name) = self.terms.pop().and_then(|t| self.atomize_term(&t)) { if let Some(name) = self.terms.pop().and_then(|t| self.atomize_term(&t)) {
// reduce the '.' functor to a cons cell if it applies. // reduce the '.' functor to a cons cell if it applies.
@@ -503,11 +495,15 @@ impl<'a, R: Read> Parser<'a, R> {
self.terms.push(Term::Cons(Cell::default(), head, tail)); self.terms.push(Term::Cons(Cell::default(), head, tail));
} else { } else {
let spec = get_clause_spec(name.clone(), subterms.len(), op_dir); let spec = get_clause_spec(name.clone(), subterms.len(), op_dir);
self.terms.push(Term::Clause(Cell::default(), name, subterms, spec)); self.terms
.push(Term::Clause(Cell::default(), name, subterms, spec));
} }
if let Some(&mut TokenDesc { ref mut priority, ref mut spec, if let Some(&mut TokenDesc {
ref mut tt }) = self.stack.last_mut() ref mut priority,
ref mut spec,
ref mut tt,
}) = self.stack.last_mut()
{ {
*tt = TokenType::Term; *tt = TokenType::Term;
*priority = 0; *priority = 0;
@@ -523,7 +519,7 @@ impl<'a, R: Read> Parser<'a, R> {
} }
pub fn devour_whitespace(&mut self) -> Result<(), ParserError> { pub fn devour_whitespace(&mut self) -> Result<(), ParserError> {
self.lexer.scan_for_layout()?; self.lexer.scan_for_layout()?;
Ok(()) Ok(())
} }
@@ -531,8 +527,7 @@ impl<'a, R: Read> Parser<'a, R> {
self.stack.clear() self.stack.clear()
} }
fn expand_comma_compacted_terms(&mut self, index: usize) -> usize fn expand_comma_compacted_terms(&mut self, index: usize) -> usize {
{
if let Some(term) = self.terms.pop() { if let Some(term) = self.terms.pop() {
let op_desc = self.stack[index - 1]; let op_desc = self.stack[index - 1];
@@ -548,8 +543,7 @@ impl<'a, R: Read> Parser<'a, R> {
self.terms.extend(terms.into_iter()); self.terms.extend(terms.into_iter());
return arity; return arity;
} }
_ => { _ => {}
}
} }
} }
@@ -559,12 +553,12 @@ impl<'a, R: Read> Parser<'a, R> {
0 0
} }
fn compute_arity_in_list(&self) -> Option<usize> fn compute_arity_in_list(&self) -> Option<usize> {
{
let mut arity = 0; let mut arity = 0;
for (i, desc) in self.stack.iter().rev().enumerate() { for (i, desc) in self.stack.iter().rev().enumerate() {
if i % 2 == 0 { // expect a term or non-comma operator. if i % 2 == 0 {
// expect a term or non-comma operator.
if let TokenType::Comma = desc.tt { if let TokenType::Comma = desc.tt {
return None; return None;
} else if is_term!(desc.spec) || is_op!(desc.spec) { } else if is_term!(desc.spec) || is_op!(desc.spec) {
@@ -590,8 +584,7 @@ impl<'a, R: Read> Parser<'a, R> {
None None
} }
fn reduce_list(&mut self) -> Result<bool, ParserError> fn reduce_list(&mut self) -> Result<bool, ParserError> {
{
if self.stack.is_empty() { if self.stack.is_empty() {
return Ok(false); return Ok(false);
} }
@@ -602,7 +595,8 @@ impl<'a, R: Read> Parser<'a, R> {
td.tt = TokenType::Term; td.tt = TokenType::Term;
td.priority = 0; td.priority = 0;
self.terms.push(Term::Constant(Cell::default(), Constant::EmptyList)); self.terms
.push(Term::Constant(Cell::default(), Constant::EmptyList));
return Ok(true); return Ok(true);
} }
} }
@@ -611,7 +605,7 @@ impl<'a, R: Read> Parser<'a, R> {
let mut arity = match self.compute_arity_in_list() { let mut arity = match self.compute_arity_in_list() {
Some(arity) => arity, Some(arity) => arity,
None => return Ok(false) None => return Ok(false),
}; };
// we know that self.stack.len() >= 2 by this point. // we know that self.stack.len() >= 2 by this point.
@@ -621,12 +615,15 @@ impl<'a, R: Read> Parser<'a, R> {
let end_term = if self.stack[idx].tt != TokenType::HeadTailSeparator { let end_term = if self.stack[idx].tt != TokenType::HeadTailSeparator {
Term::Constant(Cell::default(), Constant::EmptyList) Term::Constant(Cell::default(), Constant::EmptyList)
} else { } else {
let term = let term = match self.terms.pop() {
match self.terms.pop() { Some(term) => term,
Some(term) => term, _ => {
_ => return Err(ParserError::IncompleteReduction(self.lexer.line_num, return Err(ParserError::IncompleteReduction(
self.lexer.col_num)) self.lexer.line_num,
}; self.lexer.col_num,
))
}
};
if self.stack[idx].priority > 1000 { if self.stack[idx].priority > 1000 {
arity += self.expand_comma_compacted_terms(idx); arity += self.expand_comma_compacted_terms(idx);
@@ -639,15 +636,17 @@ impl<'a, R: Read> Parser<'a, R> {
let idx = self.terms.len() - arity; let idx = self.terms.len() - arity;
let list = self.terms.drain(idx ..) let list = self.terms.drain(idx..).rev().fold(end_term, |acc, t| {
.rev() Term::Cons(Cell::default(), Box::new(t), Box::new(acc))
.fold(end_term, |acc, t| Term::Cons(Cell::default(), });
Box::new(t),
Box::new(acc)));
self.stack.truncate(list_len); self.stack.truncate(list_len);
self.stack.push(TokenDesc { tt: TokenType::Term, priority: 0, spec: TERM }); self.stack.push(TokenDesc {
tt: TokenType::Term,
priority: 0,
spec: TERM,
});
self.terms.push(list); self.terms.push(list);
Ok(true) Ok(true)
@@ -664,8 +663,7 @@ impl<'a, R: Read> Parser<'a, R> {
td.priority = 0; td.priority = 0;
td.spec = TERM; td.spec = TERM;
let term = Term::Constant(Cell::default(), let term = Term::Constant(Cell::default(), atom!("{}", self.lexer.atom_tbl));
atom!("{}", self.lexer.atom_tbl));
self.terms.push(term); self.terms.push(term);
return Ok(true); return Ok(true);
} }
@@ -687,17 +685,19 @@ impl<'a, R: Read> Parser<'a, R> {
let term = match self.terms.pop() { let term = match self.terms.pop() {
Some(term) => term, Some(term) => term,
_ => return Err(ParserError::IncompleteReduction( _ => {
self.lexer.line_num, return Err(ParserError::IncompleteReduction(
self.lexer.col_num, self.lexer.line_num,
)) self.lexer.col_num,
))
}
}; };
self.terms.push(Term::Clause( self.terms.push(Term::Clause(
Cell::default(), Cell::default(),
clause_name!("{}"), clause_name!("{}"),
vec![Box::new(term)], vec![Box::new(term)],
None None,
)); ));
return Ok(true); return Ok(true);
@@ -722,35 +722,40 @@ impl<'a, R: Read> Parser<'a, R> {
let idx = self.stack.len() - 2; let idx = self.stack.len() - 2;
match self.stack.remove(idx) { let td = self.stack.remove(idx);
td => match td.tt {
match td.tt { TokenType::Open | TokenType::OpenCT => {
TokenType::Open | TokenType::OpenCT => { if self.stack[idx].tt == TokenType::Comma {
if self.stack[idx].tt == TokenType::Comma { return false;
return false;
}
if let Some(atom) = sep_to_atom(self.stack[idx].tt) {
self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, None)));
}
self.stack[idx].spec = TERM;
self.stack[idx].tt = TokenType::Term;
self.stack[idx].priority = 0;
true
},
_ => false
} }
if let Some(atom) = sep_to_atom(self.stack[idx].tt) {
self.terms
.push(Term::Constant(Cell::default(), Constant::Atom(atom, None)));
}
self.stack[idx].spec = TERM;
self.stack[idx].tt = TokenType::Term;
self.stack[idx].priority = 0;
true
}
_ => false,
} }
} }
fn shift_op(&mut self, name: ClauseName, op_dir: &CompositeOpDir) -> Result<bool, ParserError> { fn shift_op(&mut self, name: ClauseName, op_dir: &CompositeOpDir) -> Result<bool, ParserError> {
if let Some(OpDesc { pre, inf, post, spec }) = get_op_desc(name.clone(), op_dir) { if let Some(OpDesc {
pre,
inf,
post,
spec,
}) = get_op_desc(name.clone(), op_dir)
{
if (pre > 0 && inf + post > 0) || is_negate!(spec) { if (pre > 0 && inf + post > 0) || is_negate!(spec) {
match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? { match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? {
// do this when layout hasn't been inserted, // do this when layout hasn't been inserted,
// ie. why we don't match on Token::Open. // ie. why we don't match on Token::Open.
&Token::OpenCT => { Token::OpenCT => {
// can't be prefix, so either inf == 0 // can't be prefix, so either inf == 0
// or post == 0. // or post == 0.
self.reduce_op(inf + post); self.reduce_op(inf + post);
@@ -764,7 +769,7 @@ impl<'a, R: Read> Parser<'a, R> {
spec & (XFX | XFY | YFX | YF | XF), spec & (XFX | XFY | YFX | YF | XF),
op_dir_val, op_dir_val,
); );
}, }
_ => { _ => {
self.reduce_op(inf + post); self.reduce_op(inf + post);
@@ -782,11 +787,21 @@ impl<'a, R: Read> Parser<'a, R> {
); );
} else { } else {
let op_dir_val = op_dir.get(name.clone(), Fixity::Pre); let op_dir_val = op_dir.get(name.clone(), Fixity::Pre);
self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN), op_dir_val); self.promote_atom_op(
name,
pre,
spec & (FX | FY | NEGATIVE_SIGN),
op_dir_val,
);
} }
} else { } else {
let op_dir_val = op_dir.get(name.clone(), Fixity::Pre); let op_dir_val = op_dir.get(name.clone(), Fixity::Pre);
self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN), op_dir_val); self.promote_atom_op(
name,
pre,
spec & (FX | FY | NEGATIVE_SIGN),
op_dir_val,
);
} }
} }
} }
@@ -807,49 +822,46 @@ impl<'a, R: Read> Parser<'a, R> {
} }
Ok(true) Ok(true)
} else { // not an operator. } else {
// not an operator.
Ok(false) Ok(false)
} }
} }
fn atomize_term(&self, term: &Term) -> Option<ClauseName> { fn atomize_term(&self, term: &Term) -> Option<ClauseName> {
match term { match term {
&Term::Constant(_, ref c) => self.atomize_constant(c), Term::Constant(_, ref c) => self.atomize_constant(c),
_ => None _ => None,
} }
} }
fn atomize_constant(&self, c: &Constant) -> Option<ClauseName> { fn atomize_constant(&self, c: &Constant) -> Option<ClauseName> {
match c { match c {
&Constant::Atom(ref name, _) => Some(name.clone()), Constant::Atom(ref name, _) => Some(name.clone()),
&Constant::Char(c) => Constant::Char(c) => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
Some(clause_name!(c.to_string(), self.lexer.atom_tbl)), Constant::EmptyList => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
&Constant::EmptyList => _ => None,
Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
_ => None
} }
} }
fn negate_number<N, Negator, ToConstant>( fn negate_number<N, Negator, ToConstant>(&mut self, n: N, negator: Negator, constr: ToConstant)
&mut self, where
n: N, Negator: Fn(N) -> N,
negator: Negator, ToConstant: Fn(N) -> Constant,
constr: ToConstant
)
where Negator: Fn(N) -> N,
ToConstant: Fn(N) -> Constant
{ {
if let Some(desc) = self.stack.last().cloned() { if let Some(desc) = self.stack.last().cloned() {
if let Some(term) = self.terms.last().cloned() { if let Some(term) = self.terms.last().cloned() {
match term { match term {
Term::Constant(_, Constant::Atom(ref name, _)) Term::Constant(_, Constant::Atom(ref name, _))
if name.as_str() == "-" && (is_prefix!(desc.spec) || is_negate!(desc.spec)) => { if name.as_str() == "-"
self.stack.pop(); && (is_prefix!(desc.spec) || is_negate!(desc.spec)) =>
self.terms.pop(); {
self.stack.pop();
self.terms.pop();
self.shift(Token::Constant(constr(negator(n))), 0, TERM); self.shift(Token::Constant(constr(negator(n))), 0, TERM);
return; return;
}, }
_ => {} _ => {}
} }
} }
@@ -860,42 +872,37 @@ impl<'a, R: Read> Parser<'a, R> {
fn shift_token(&mut self, token: Token, op_dir: &CompositeOpDir) -> Result<(), ParserError> { fn shift_token(&mut self, token: Token, op_dir: &CompositeOpDir) -> Result<(), ParserError> {
fn negate_rc<T: NegAssign>(mut t: Rc<T>) -> Rc<T> { fn negate_rc<T: NegAssign>(mut t: Rc<T>) -> Rc<T> {
match Rc::get_mut(&mut t) { if let Some(t) = Rc::get_mut(&mut t) {
Some(t) => { t.neg_assign();
t.neg_assign();
}
None => {
}
}; };
t t
} }
match token { match token {
Token::Constant(Constant::Fixnum(n)) => Token::Constant(Constant::Fixnum(n)) => self.negate_number(n, |n| -n, Constant::Fixnum),
self.negate_number(n, |n| -n, Constant::Fixnum), Token::Constant(Constant::Integer(n)) => {
Token::Constant(Constant::Integer(n)) => self.negate_number(n, negate_rc, Constant::Integer)
self.negate_number(n, negate_rc, Constant::Integer), }
Token::Constant(Constant::Rational(n)) => Token::Constant(Constant::Rational(n)) => {
self.negate_number(n, negate_rc, Constant::Rational), self.negate_number(n, negate_rc, Constant::Rational)
Token::Constant(Constant::Float(n)) => }
self.negate_number( Token::Constant(Constant::Float(n)) => {
n, self.negate_number(n, |n| OrderedFloat(-n.into_inner()), Constant::Float)
|n| OrderedFloat(-n.into_inner()), }
|n| Constant::Float(n) Token::Constant(c) => {
),
Token::Constant(c) =>
if let Some(name) = self.atomize_constant(&c) { if let Some(name) = self.atomize_constant(&c) {
if !self.shift_op(name, op_dir)? { if !self.shift_op(name, op_dir)? {
self.shift(Token::Constant(c), 0, TERM); self.shift(Token::Constant(c), 0, TERM);
} }
} else { } else {
self.shift(Token::Constant(c), 0, TERM); self.shift(Token::Constant(c), 0, TERM);
}, }
}
Token::Var(v) => self.shift(Token::Var(v), 0, TERM), Token::Var(v) => self.shift(Token::Var(v), 0, TERM),
Token::Open => self.shift(Token::Open, 1300, DELIMITER), Token::Open => self.shift(Token::Open, 1300, DELIMITER),
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER), Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
Token::Close => Token::Close => {
if !self.reduce_term(op_dir) { if !self.reduce_term(op_dir) {
if !self.reduce_brackets() { if !self.reduce_brackets() {
return Err(ParserError::IncompleteReduction( return Err(ParserError::IncompleteReduction(
@@ -903,23 +910,26 @@ impl<'a, R: Read> Parser<'a, R> {
self.lexer.col_num, self.lexer.col_num,
)); ));
} }
}, }
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER), }
Token::CloseList => Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
Token::CloseList => {
if !self.reduce_list()? { if !self.reduce_list()? {
return Err(ParserError::IncompleteReduction( return Err(ParserError::IncompleteReduction(
self.lexer.line_num, self.lexer.line_num,
self.lexer.col_num, self.lexer.col_num,
)); ));
}, }
}
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER), Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
Token::CloseCurly => Token::CloseCurly => {
if !self.reduce_curly()? { if !self.reduce_curly()? {
return Err(ParserError::IncompleteReduction( return Err(ParserError::IncompleteReduction(
self.lexer.line_num, self.lexer.line_num,
self.lexer.col_num, self.lexer.col_num,
)); ));
}, }
}
Token::HeadTailSeparator => { Token::HeadTailSeparator => {
/* '|' as an operator must have priority > 1000 and can only be infix. /* '|' as an operator must have priority > 1000 and can only be infix.
* See: http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#Res_A78 * See: http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#Res_A78
@@ -930,23 +940,25 @@ impl<'a, R: Read> Parser<'a, R> {
self.reduce_op(priority); self.reduce_op(priority);
self.shift(Token::HeadTailSeparator, priority, spec); self.shift(Token::HeadTailSeparator, priority, spec);
}, }
Token::Comma => { Token::Comma => {
self.reduce_op(1000); self.reduce_op(1000);
self.shift(Token::Comma, 1000, XFY); self.shift(Token::Comma, 1000, XFY);
}, }
Token::End => Token::End => match self.stack.last().map(|t| t.tt) {
match self.stack.last().map(|t| t.tt) { Some(TokenType::Open)
Some(TokenType::Open) | Some(TokenType::OpenCT)
| Some(TokenType::OpenCT) | Some(TokenType::OpenList)
| Some(TokenType::OpenList) | Some(TokenType::OpenCurly)
| Some(TokenType::OpenCurly) | Some(TokenType::HeadTailSeparator)
| Some(TokenType::HeadTailSeparator) | Some(TokenType::Comma) => {
| Some(TokenType::Comma) return Err(ParserError::IncompleteReduction(
=> return Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.line_num,
self.lexer.col_num)), self.lexer.col_num,
_ => {} ))
} }
_ => {}
},
} }
Ok(()) Ok(())
@@ -957,8 +969,7 @@ impl<'a, R: Read> Parser<'a, R> {
self.lexer.eof() self.lexer.eof()
} }
pub fn read_term(&mut self, op_dir: &CompositeOpDir) -> Result<Term, ParserError> pub fn read_term(&mut self, op_dir: &CompositeOpDir) -> Result<Term, ParserError> {
{
self.tokens = read_tokens(&mut self.lexer)?; self.tokens = read_tokens(&mut self.lexer)?;
while let Some(token) = self.tokens.pop() { while let Some(token) = self.tokens.pop() {
@@ -968,21 +979,31 @@ impl<'a, R: Read> Parser<'a, R> {
self.reduce_op(1400); self.reduce_op(1400);
if self.terms.len() > 1 || self.stack.len() > 1 { if self.terms.len() > 1 || self.stack.len() > 1 {
return Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num)); return Err(ParserError::IncompleteReduction(
self.lexer.line_num,
self.lexer.col_num,
));
} }
match self.terms.pop() { match self.terms.pop() {
Some(term) => if self.terms.is_empty() { Some(term) => {
Ok(term) if self.terms.is_empty() {
} else { Ok(term)
Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num)) } else {
}, Err(ParserError::IncompleteReduction(
_ => Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num)) self.lexer.line_num,
self.lexer.col_num,
))
}
}
_ => Err(ParserError::IncompleteReduction(
self.lexer.line_num,
self.lexer.col_num,
)),
} }
} }
pub fn read(&mut self, op_dir: &CompositeOpDir) -> Result<Vec<Term>, ParserError> pub fn read(&mut self, op_dir: &CompositeOpDir) -> Result<Vec<Term>, ParserError> {
{
let mut terms = Vec::new(); let mut terms = Vec::new();
loop { loop {

View File

@@ -4,11 +4,11 @@ use std::collections::HashSet;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ops::Deref; use std::ops::Deref;
use std::rc::{Rc}; use std::rc::Rc;
pub struct TabledData<T> { pub struct TabledData<T> {
table: Rc<RefCell<HashSet<Rc<T>>>>, table: Rc<RefCell<HashSet<Rc<T>>>>,
pub(crate) module_name: Rc<String> pub(crate) module_name: Rc<String>,
} }
impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> { impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> {
@@ -22,14 +22,15 @@ impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> {
impl<T> Clone for TabledData<T> { impl<T> Clone for TabledData<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
TabledData { table: self.table.clone(), TabledData {
module_name: self.module_name.clone() } table: self.table.clone(),
module_name: self.module_name.clone(),
}
} }
} }
impl<T: PartialEq> PartialEq for TabledData<T> { impl<T: PartialEq> PartialEq for TabledData<T> {
fn eq(&self, other: &TabledData<T>) -> bool fn eq(&self, other: &TabledData<T>) -> bool {
{
Rc::ptr_eq(&self.table, &other.table) && self.module_name == other.module_name Rc::ptr_eq(&self.table, &other.table) && self.module_name == other.module_name
} }
} }
@@ -39,7 +40,7 @@ impl<T: Hash + Eq> TabledData<T> {
pub fn new(module_name: Rc<String>) -> Self { pub fn new(module_name: Rc<String>) -> Self {
TabledData { TabledData {
table: Rc::new(RefCell::new(HashSet::new())), table: Rc::new(RefCell::new(HashSet::new())),
module_name module_name,
} }
} }
@@ -51,7 +52,7 @@ impl<T: Hash + Eq> TabledData<T> {
pub struct TabledRc<T: Hash + Eq> { pub struct TabledRc<T: Hash + Eq> {
pub(crate) atom: Rc<T>, pub(crate) atom: Rc<T>,
pub table: TabledData<T> pub table: TabledData<T>,
} }
impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledRc<T> { impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledRc<T> {
@@ -67,27 +68,27 @@ impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledRc<T> {
// from complaining when deriving Clone for StringList. // from complaining when deriving Clone for StringList.
impl<T: Hash + Eq> Clone for TabledRc<T> { impl<T: Hash + Eq> Clone for TabledRc<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
TabledRc { atom: self.atom.clone(), table: self.table.clone() } TabledRc {
atom: self.atom.clone(),
table: self.table.clone(),
}
} }
} }
impl<T: Ord + Hash + Eq> PartialOrd for TabledRc<T> { impl<T: Ord + Hash + Eq> PartialOrd for TabledRc<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
{
Some(self.atom.cmp(&other.atom)) Some(self.atom.cmp(&other.atom))
} }
} }
impl<T: Ord + Hash + Eq> Ord for TabledRc<T> { impl<T: Ord + Hash + Eq> Ord for TabledRc<T> {
fn cmp(&self, other: &Self) -> Ordering fn cmp(&self, other: &Self) -> Ordering {
{
self.atom.cmp(&other.atom) self.atom.cmp(&other.atom)
} }
} }
impl<T: Hash + Eq> PartialEq for TabledRc<T> { impl<T: Hash + Eq> PartialEq for TabledRc<T> {
fn eq(&self, other: &TabledRc<T>) -> bool fn eq(&self, other: &TabledRc<T>) -> bool {
{
self.atom == other.atom self.atom == other.atom
} }
} }
@@ -103,8 +104,8 @@ impl<T: Hash + Eq> Hash for TabledRc<T> {
impl<T: Hash + Eq + ToString> TabledRc<T> { impl<T: Hash + Eq + ToString> TabledRc<T> {
pub fn new(atom: T, table: TabledData<T>) -> Self { pub fn new(atom: T, table: TabledData<T>) -> Self {
let atom = match table.borrow_mut().take(&atom) { let atom = match table.borrow_mut().take(&atom) {
Some(atom) => atom.clone(), Some(atom) => atom,
None => Rc::new(atom) None => Rc::new(atom),
}; };
table.borrow_mut().insert(atom.clone()); table.borrow_mut().insert(atom.clone());
@@ -147,7 +148,7 @@ impl<T: Hash + Eq + fmt::Display> fmt::Display for TabledRc<T> {
#[macro_export] #[macro_export]
macro_rules! tabled_rc { macro_rules! tabled_rc {
($e:expr, $tbl:expr) => ( ($e:expr, $tbl:expr) => {
TabledRc::new(String::from($e), $tbl.clone()) $crate::tabled_rc::TabledRc::new(String::from($e), $tbl.clone())
) };
} }

View File

@@ -1,8 +1,6 @@
extern crate prolog_parser_rebis; use prolog_parser::ast::*;
use prolog_parser::lexer::{Lexer, Token};
use prolog_parser_rebis::ast::*; use prolog_parser::tabled_rc::TabledData;
use prolog_parser_rebis::lexer::{Lexer, Token};
use prolog_parser_rebis::tabled_rc::TabledData;
use std::rc::Rc; use std::rc::Rc;
@@ -27,7 +25,7 @@ fn skip_utf8_bom() {
let mut lexer = Lexer::new(atom_tbl, flags, &mut stream); let mut lexer = Lexer::new(atom_tbl, flags, &mut stream);
match lexer.next_token() { match lexer.next_token() {
Ok(Token::Constant(Constant::Fixnum(4))) => (), Ok(Token::Constant(Constant::Fixnum(4))) => (),
_ => assert!(false) _ => assert!(false),
} }
} }
@@ -37,7 +35,6 @@ fn invalid_utf16_bom() {
let stream = parsing_stream(bytes); let stream = parsing_stream(bytes);
match stream { match stream {
Err(ParserError::Utf8Error(0, 0)) => (), Err(ParserError::Utf8Error(0, 0)) => (),
_ => assert!(false) _ => assert!(false),
} }
} }

View File

@@ -1,8 +1,6 @@
extern crate prolog_parser_rebis; use prolog_parser::ast::*;
use prolog_parser::lexer::{Lexer, Token};
use prolog_parser_rebis::ast::*; use prolog_parser::tabled_rc::TabledData;
use prolog_parser_rebis::lexer::{Lexer, Token};
use prolog_parser_rebis::tabled_rc::TabledData;
use std::rc::Rc; use std::rc::Rc;

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::temp_v;
use crate::fixtures::*; use crate::fixtures::*;
use crate::forms::*; use crate::forms::*;
@@ -14,8 +15,13 @@ pub trait Allocator<'a> {
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>) fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
where where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn mark_non_var<Target>(&mut self, _: Level, _: GenContext, _: &'a Cell<RegType>, _: &mut Vec<Target>) fn mark_non_var<Target>(
where &mut self,
_: Level,
_: GenContext,
_: &'a Cell<RegType>,
_: &mut Vec<Target>,
) where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn mark_reserved_var<Target>( fn mark_reserved_var<Target>(
&mut self, &mut self,
@@ -28,8 +34,14 @@ pub trait Allocator<'a> {
_: bool, _: bool,
) where ) where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn mark_var<Target>(&mut self, _: Rc<Var>, _: Level, _: &'a Cell<VarReg>, _: GenContext, _: &mut Vec<Target>) fn mark_var<Target>(
where &mut self,
_: Rc<Var>,
_: Level,
_: &'a Cell<VarReg>,
_: GenContext,
_: &mut Vec<Target>,
) where
Target: CompilationTarget<'a>; Target: CompilationTarget<'a>;
fn reset(&mut self); fn reset(&mut self);
@@ -47,7 +59,7 @@ pub trait Allocator<'a> {
fn drain_var_data( fn drain_var_data(
&mut self, &mut self,
vs: VariableFixtures<'a>, vs: VariableFixtures<'a>,
num_of_chunks: usize num_of_chunks: usize,
) -> VariableFixtures<'a> { ) -> VariableFixtures<'a> {
let mut perm_vs = VariableFixtures::new(); let mut perm_vs = VariableFixtures::new();

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::{atom, clause_name};
use crate::clause_types::*; use crate::clause_types::*;
use crate::fixtures::*; use crate::fixtures::*;
@@ -10,9 +11,9 @@ use crate::machine::heap::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::ordered_float::*;
use crate::rug::ops::PowAssign; use crate::rug::ops::PowAssign;
use crate::rug::{Assign, Integer, Rational}; use crate::rug::{Assign, Integer, Rational};
use ordered_float::*;
use std::cell::Cell; use std::cell::Cell;
use std::cmp::{max, min, Ordering}; use std::cmp::{max, min, Ordering};
@@ -267,9 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> { fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
match c { match c {
&Constant::Fixnum(n) => self &Constant::Fixnum(n) => self.interm.push(ArithmeticTerm::Number(Number::Fixnum(n))),
.interm
.push(ArithmeticTerm::Number(Number::Fixnum(n))),
&Constant::Integer(ref n) => self &Constant::Integer(ref n) => self
.interm .interm
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))), .push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
@@ -326,17 +325,11 @@ impl<'a> ArithmeticEvaluator<'a> {
// integer division rounding function -- 9.1.3.1. // integer division rounding function -- 9.1.3.1.
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> { pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
match n { match n {
&Number::Integer(_) => { &Number::Integer(_) => RefOrOwned::Borrowed(n),
RefOrOwned::Borrowed(n) &Number::Float(OrderedFloat(f)) => RefOrOwned::Owned(Number::from(
} Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
&Number::Float(OrderedFloat(f)) => { )),
RefOrOwned::Owned(Number::from( &Number::Fixnum(n) => RefOrOwned::Owned(Number::from(n)),
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))
))
}
&Number::Fixnum(n) => {
RefOrOwned::Owned(Number::from(n))
}
&Number::Rational(ref r) => { &Number::Rational(ref r) => {
let r_ref = r.fract_floor_ref(); let r_ref = r.fract_floor_ref();
let (mut fract, mut floor) = (Rational::new(), Integer::new()); let (mut fract, mut floor) = (Rational::new(), Integer::new());
@@ -432,31 +425,31 @@ impl Add<Number> for Number {
Number::from(Integer::from(n1) + Integer::from(n2)) Number::from(Integer::from(n1) + Integer::from(n2))
}) })
} }
(Number::Fixnum(n1), Number::Integer(n2)) | (Number::Fixnum(n1), Number::Integer(n2))
(Number::Integer(n2), Number::Fixnum(n1)) => { | (Number::Integer(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Integer::from(n1) + &*n2)) Ok(Number::from(Integer::from(n1) + &*n2))
} }
(Number::Fixnum(n1), Number::Rational(n2)) | (Number::Fixnum(n1), Number::Rational(n2))
(Number::Rational(n2), Number::Fixnum(n1)) => { | (Number::Rational(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Rational::from(n1) + &*n2)) Ok(Number::from(Rational::from(n1) + &*n2))
} }
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) | (Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => { | (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?)) Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
} }
(Number::Integer(n1), Number::Integer(n2)) => { (Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i
} }
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) (Number::Integer(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => { | (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?)) Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
} }
(Number::Integer(n1), Number::Rational(n2)) (Number::Integer(n1), Number::Rational(n2))
| (Number::Rational(n2), Number::Integer(n1)) => { | (Number::Rational(n2), Number::Integer(n1)) => {
Ok(Number::from(Rational::from(&*n1) + &*n2)) Ok(Number::from(Rational::from(&*n1) + &*n2))
} }
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) (Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => { | (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?)) Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
} }
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => { (Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
@@ -474,12 +467,13 @@ impl Neg for Number {
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
match self { match self {
Number::Fixnum(n) => Number::Fixnum(n) => {
if let Some(n) = n.checked_neg() { if let Some(n) = n.checked_neg() {
Number::Fixnum(n) Number::Fixnum(n)
} else { } else {
Number::from(-Integer::from(n)) Number::from(-Integer::from(n))
} }
}
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))), Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)), Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))), Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))),
@@ -507,16 +501,16 @@ impl Mul<Number> for Number {
Number::from(Integer::from(n1) * Integer::from(n2)) Number::from(Integer::from(n1) * Integer::from(n2))
}) })
} }
(Number::Fixnum(n1), Number::Integer(n2)) | (Number::Fixnum(n1), Number::Integer(n2))
(Number::Integer(n2), Number::Fixnum(n1)) => { | (Number::Integer(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Integer::from(n1) * &*n2)) Ok(Number::from(Integer::from(n1) * &*n2))
} }
(Number::Fixnum(n1), Number::Rational(n2)) | (Number::Fixnum(n1), Number::Rational(n2))
(Number::Rational(n2), Number::Fixnum(n1)) => { | (Number::Rational(n2), Number::Fixnum(n1)) => {
Ok(Number::from(Rational::from(n1) * &*n2)) Ok(Number::from(Rational::from(n1) * &*n2))
} }
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) | (Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => { | (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?)) Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
} }
(Number::Integer(n1), Number::Integer(n2)) => { (Number::Integer(n1), Number::Integer(n2)) => {
@@ -549,72 +543,50 @@ impl Div<Number> for Number {
fn div(self, rhs: Number) -> Self::Output { fn div(self, rhs: Number) -> Self::Output {
match (self, rhs) { match (self, rhs) {
(Number::Fixnum(n1), Number::Fixnum(n2)) => { (Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
Ok(Number::Float(div_f( float_fn_to_f(n1)?,
float_fn_to_f(n1)?, float_fn_to_f(n2)?,
float_fn_to_f(n2)?, )?)),
)?)) (Number::Fixnum(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
} float_fn_to_f(n1)?,
(Number::Fixnum(n1), Number::Integer(n2)) => { float_i_to_f(&n2)?,
Ok(Number::Float(div_f( )?)),
float_fn_to_f(n1)?, (Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
float_i_to_f(&n2)?, float_i_to_f(&n1)?,
)?)) float_fn_to_f(n2)?,
} )?)),
(Number::Integer(n1), Number::Fixnum(n2)) => { (Number::Fixnum(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
Ok(Number::Float(div_f( float_fn_to_f(n1)?,
float_i_to_f(&n1)?, float_r_to_f(&n2)?,
float_fn_to_f(n2)?, )?)),
)?)) (Number::Rational(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
} float_r_to_f(&n1)?,
(Number::Fixnum(n1), Number::Rational(n2)) => { float_fn_to_f(n2)?,
Ok(Number::Float(div_f( )?)),
float_fn_to_f(n1)?,
float_r_to_f(&n2)?,
)?))
}
(Number::Rational(n1), Number::Fixnum(n2)) => {
Ok(Number::Float(div_f(
float_r_to_f(&n1)?,
float_fn_to_f(n2)?,
)?))
}
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => { (Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f( Ok(Number::Float(div_f(float_fn_to_f(n1)?, n2)?))
float_fn_to_f(n1)?,
n2,
)?))
} }
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => { (Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
Ok(Number::Float(div_f( Ok(Number::Float(div_f(n1, float_fn_to_f(n2)?)?))
n1,
float_fn_to_f(n2)?,
)?))
}
(Number::Integer(n1), Number::Integer(n2)) => {
Ok(Number::Float(div_f(
float_i_to_f(&n1)?,
float_i_to_f(&n2)?,
)?))
} }
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
float_i_to_f(&n1)?,
float_i_to_f(&n2)?,
)?)),
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => { (Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?)) Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
} }
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => { (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?)) Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
} }
(Number::Integer(n1), Number::Rational(n2)) => { (Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
Ok(Number::Float(div_f( float_i_to_f(&n1)?,
float_i_to_f(&n1)?, float_r_to_f(&n2)?,
float_r_to_f(&n2)?, )?)),
)?)) (Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
} float_r_to_f(&n2)?,
(Number::Rational(n2), Number::Integer(n1)) => { float_i_to_f(&n1)?,
Ok(Number::Float(div_f( )?)),
float_r_to_f(&n2)?,
float_i_to_f(&n1)?,
)?))
}
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => { (Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?)) Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
} }
@@ -727,12 +699,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> { fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
match addr { match addr {
Addr::Fixnum(n) => { Addr::Fixnum(n) => Ok(Number::from(n)),
Ok(Number::from(n)) Addr::Float(n) => Ok(Number::Float(n)),
}
Addr::Float(n) => {
Ok(Number::Float(n))
}
Addr::Usize(n) => { Addr::Usize(n) => {
if let Ok(n) = isize::try_from(n) { if let Ok(n) = isize::try_from(n) {
Ok(Number::from(n)) Ok(Number::from(n))
@@ -740,12 +708,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
Ok(Number::from(Integer::from(n))) Ok(Number::from(Integer::from(n)))
} }
} }
Addr::Con(h) => { Addr::Con(h) => Number::try_from(&heap[h]),
Number::try_from(&heap[h]) _ => Err(()),
}
_ => {
Err(())
}
} }
} }
} }
@@ -755,35 +719,21 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> { fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
match value { match value {
HeapCellValue::Addr(addr) => { HeapCellValue::Addr(addr) => match addr {
match addr { &Addr::Fixnum(n) => Ok(Number::from(n)),
&Addr::Fixnum(n) => { &Addr::Float(n) => Ok(Number::Float(n)),
&Addr::Usize(n) => {
if let Ok(n) = isize::try_from(n) {
Ok(Number::from(n)) Ok(Number::from(n))
} } else {
&Addr::Float(n) => { Ok(Number::from(Integer::from(n)))
Ok(Number::Float(n))
}
&Addr::Usize(n) => {
if let Ok(n) = isize::try_from(n) {
Ok(Number::from(n))
} else {
Ok(Number::from(Integer::from(n)))
}
}
_ => {
Err(())
} }
} }
} _ => Err(()),
HeapCellValue::Integer(n) => { },
Ok(Number::Integer(n.clone())) HeapCellValue::Integer(n) => Ok(Number::Integer(n.clone())),
} HeapCellValue::Rational(n) => Ok(Number::Rational(n.clone())),
HeapCellValue::Rational(n) => { _ => Err(()),
Ok(Number::Rational(n.clone()))
}
_ => {
Err(())
}
} }
} }
} }

View File

@@ -1,10 +1,11 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::{clause_name, temp_v};
use crate::forms::Number; use crate::forms::Number;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::rug::rand::RandState; use crate::rug::rand::RandState;
use crate::ref_thread_local::RefThreadLocal; use ref_thread_local::{ref_thread_local, RefThreadLocal};
use std::collections::BTreeMap; use std::collections::BTreeMap;
@@ -322,7 +323,9 @@ impl SystemClauseType {
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"), &SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"), &SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"), &SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"), &SystemClauseType::CopyTermWithoutAttrVars => {
clause_name!("$copy_term_without_attr_vars")
}
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"), &SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
&SystemClauseType::CurrentInput => clause_name!("$current_input"), &SystemClauseType::CurrentInput => clause_name!("$current_input"),
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"), &SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
@@ -337,58 +340,70 @@ impl SystemClauseType {
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"), &SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"), &SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
&SystemClauseType::FileTime => clause_name!("$file_time"), &SystemClauseType::FileTime => clause_name!("$file_time"),
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => &SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => {
clause_name!("$add_dynamic_predicate"), clause_name!("$add_dynamic_predicate")
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => }
clause_name!("$add_goal_expansion_clause"), &SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => clause_name!("$add_goal_expansion_clause")
clause_name!("$add_term_expansion_clause"), }
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => &SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
clause_name!("$clause_to_evacuable"), clause_name!("$add_term_expansion_clause")
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => }
clause_name!("$conclude_load"), &SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$clause_to_evacuable")
clause_name!("$declare_module"), }
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => &SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
clause_name!("$load_compiled_library"), &SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => &SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
clause_name!("$push_load_state_payload"), clause_name!("$load_compiled_library")
&SystemClauseType::REPL(REPLCodePtr::Asserta) => }
clause_name!("$asserta"), &SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$push_load_state_payload")
clause_name!("$assertz"), }
&SystemClauseType::REPL(REPLCodePtr::Retract) => &SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
clause_name!("$retract_clause"), &SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
&SystemClauseType::REPL(REPLCodePtr::UseModule) => &SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
clause_name!("$use_module"), &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => &SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => {
clause_name!("$push_load_context"), clause_name!("$push_load_context")
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => }
clause_name!("$pop_load_context"), &SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => {
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => clause_name!("$pop_load_context")
clause_name!("$pop_load_state_payload"), }
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => &SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => {
clause_name!("$prolog_lc_source"), clause_name!("$pop_load_state_payload")
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => }
clause_name!("$prolog_lc_file"), &SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => {
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => clause_name!("$prolog_lc_source")
clause_name!("$prolog_lc_dir"), }
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => &SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => {
clause_name!("$prolog_lc_module"), clause_name!("$prolog_lc_file")
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => }
clause_name!("$prolog_lc_stream"), &SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => {
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => clause_name!("$prolog_lc_dir")
clause_name!("$cpp_meta_predicate_property"), }
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => &SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => {
clause_name!("$cpp_built_in_property"), clause_name!("$prolog_lc_module")
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => }
clause_name!("$cpp_dynamic_property"), &SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => {
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => clause_name!("$prolog_lc_stream")
clause_name!("$cpp_multifile_property"), }
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => &SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
clause_name!("$cpp_discontiguous_property"), clause_name!("$cpp_meta_predicate_property")
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => }
clause_name!("$abolish_clause"), &SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => {
clause_name!("$cpp_built_in_property")
}
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => {
clause_name!("$cpp_dynamic_property")
}
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => {
clause_name!("$cpp_multifile_property")
}
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => {
clause_name!("$cpp_discontiguous_property")
}
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => clause_name!("$abolish_clause"),
&SystemClauseType::Close => clause_name!("$close"), &SystemClauseType::Close => clause_name!("$close"),
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
@@ -397,8 +412,9 @@ impl SystemClauseType {
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"), &SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"), &SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"), &SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
&SystemClauseType::FetchGlobalVarWithOffset => &SystemClauseType::FetchGlobalVarWithOffset => {
clause_name!("$fetch_global_var_with_offset"), clause_name!("$fetch_global_var_with_offset")
}
&SystemClauseType::FirstStream => clause_name!("$first_stream"), &SystemClauseType::FirstStream => clause_name!("$first_stream"),
&SystemClauseType::FlushOutput => clause_name!("$flush_output"), &SystemClauseType::FlushOutput => clause_name!("$flush_output"),
&SystemClauseType::GetByte => clause_name!("$get_byte"), &SystemClauseType::GetByte => clause_name!("$get_byte"),
@@ -424,13 +440,13 @@ impl SystemClauseType {
clause_name!("$get_lh_from_offset_diff") clause_name!("$get_lh_from_offset_diff")
} }
&SystemClauseType::GetBValue => clause_name!("$get_b_value"), &SystemClauseType::GetBValue => clause_name!("$get_b_value"),
// &SystemClauseType::GetClause => clause_name!("$get_clause"), // &SystemClauseType::GetClause => clause_name!("$get_clause"),
&SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"), &SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"),
&SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"), &SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"),
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"), &SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
&SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"), &SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"),
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"), &SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
// &SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"), // &SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"), &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
&SystemClauseType::Halt => clause_name!("$halt"), &SystemClauseType::Halt => clause_name!("$halt"),
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"), &SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
@@ -455,7 +471,7 @@ impl SystemClauseType {
// &SystemClauseType::ModuleAssertDynamicPredicateToBack => { // &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
// clause_name!("$module_assertz") // clause_name!("$module_assertz")
// } // }
// &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"), // &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
&SystemClauseType::ModuleExists => clause_name!("$module_exists"), &SystemClauseType::ModuleExists => clause_name!("$module_exists"),
&SystemClauseType::NextStream => clause_name!("$next_stream"), &SystemClauseType::NextStream => clause_name!("$next_stream"),
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"), &SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
@@ -507,7 +523,9 @@ impl SystemClauseType {
&SystemClauseType::ReadTerm => clause_name!("$read_term"), &SystemClauseType::ReadTerm => clause_name!("$read_term"),
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"), &SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"), &SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
&SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"), &SystemClauseType::ResetGlobalVarAtOffset => {
clause_name!("$reset_global_var_at_offset")
}
&SystemClauseType::ResetBlock => clause_name!("$reset_block"), &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"), &SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"), &SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
@@ -521,7 +539,9 @@ impl SystemClauseType {
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"), &SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"), &SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
&SystemClauseType::Succeed => clause_name!("$succeed"), &SystemClauseType::Succeed => clause_name!("$succeed"),
&SystemClauseType::TermAttributedVariables => clause_name!("$term_attributed_variables"), &SystemClauseType::TermAttributedVariables => {
clause_name!("$term_attributed_variables")
}
&SystemClauseType::TermVariables => clause_name!("$term_variables"), &SystemClauseType::TermVariables => clause_name!("$term_variables"),
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"), &SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"), &SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
@@ -542,7 +562,9 @@ impl SystemClauseType {
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"), &SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"), &SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"), &SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
&SystemClauseType::Ed25519KeyPairPublicKey => clause_name!("$ed25519_keypair_public_key"), &SystemClauseType::Ed25519KeyPairPublicKey => {
clause_name!("$ed25519_keypair_public_key")
}
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"), &SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
&SystemClauseType::LoadHTML => clause_name!("$load_html"), &SystemClauseType::LoadHTML => clause_name!("$load_html"),
&SystemClauseType::LoadXML => clause_name!("$load_xml"), &SystemClauseType::LoadXML => clause_name!("$load_xml"),
@@ -556,14 +578,16 @@ impl SystemClauseType {
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> { pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
match (name, arity) { match (name, arity) {
("$abolish_clause", 3) => ("$abolish_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)), ("$add_dynamic_predicate", 3) => {
("$add_dynamic_predicate", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate)), }
("$add_goal_expansion_clause", 4) => ("$add_goal_expansion_clause", 4) => {
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)), Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
("$add_term_expansion_clause", 3) => }
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)), ("$add_term_expansion_clause", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
}
("$atom_chars", 2) => Some(SystemClauseType::AtomChars), ("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes), ("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
("$atom_length", 2) => Some(SystemClauseType::AtomLength), ("$atom_length", 2) => Some(SystemClauseType::AtomLength),
@@ -602,7 +626,9 @@ impl SystemClauseType {
("$peek_code", 2) => Some(SystemClauseType::PeekCode), ("$peek_code", 2) => Some(SystemClauseType::PeekCode),
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString), ("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar), ("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset), ("$fetch_global_var_with_offset", 3) => {
Some(SystemClauseType::FetchGlobalVarWithOffset)
}
("$get_byte", 2) => Some(SystemClauseType::GetByte), ("$get_byte", 2) => Some(SystemClauseType::GetByte),
("$get_char", 2) => Some(SystemClauseType::GetChar), ("$get_char", 2) => Some(SystemClauseType::GetChar),
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars), ("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
@@ -611,18 +637,10 @@ impl SystemClauseType {
("$points_to_cont_reset_marker", 1) => { ("$points_to_cont_reset_marker", 1) => {
Some(SystemClauseType::PointsToContinuationResetMarker) Some(SystemClauseType::PointsToContinuationResetMarker)
} }
("$put_byte", 2) => { ("$put_byte", 2) => Some(SystemClauseType::PutByte),
Some(SystemClauseType::PutByte) ("$put_char", 2) => Some(SystemClauseType::PutChar),
} ("$put_chars", 2) => Some(SystemClauseType::PutChars),
("$put_char", 2) => { ("$put_code", 2) => Some(SystemClauseType::PutCode),
Some(SystemClauseType::PutChar)
}
("$put_chars", 2) => {
Some(SystemClauseType::PutChars)
}
("$put_code", 2) => {
Some(SystemClauseType::PutCode)
}
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState), ("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
("$truncate_if_no_lh_growth", 1) => { ("$truncate_if_no_lh_growth", 1) => {
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth) Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
@@ -691,7 +709,9 @@ impl SystemClauseType {
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept), ("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose), ("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar), ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset), ("$store_global_var_with_offset", 2) => {
Some(SystemClauseType::StoreGlobalVarWithOffset)
}
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables), ("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
("$term_variables", 2) => Some(SystemClauseType::TermVariables), ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo), ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
@@ -708,12 +728,18 @@ impl SystemClauseType {
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory), ("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical), ("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
("$file_time", 3) => Some(SystemClauseType::FileTime), ("$file_time", 3) => Some(SystemClauseType::FileTime),
("$clause_to_evacuable", 3) => Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable)), ("$clause_to_evacuable", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
}
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)), ("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), ("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)), ("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
("$load_compiled_library", 2) => Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary)), ("$load_compiled_library", 2) => {
("$push_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)), Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
}
("$push_load_state_payload", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
}
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)), ("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)), ("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)), ("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
@@ -742,18 +768,38 @@ impl SystemClauseType {
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64), ("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream), ("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)), ("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
("$pop_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload)), ("$pop_load_state_payload", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload))
}
("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)), ("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
("$prolog_lc_source", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource)), ("$prolog_lc_source", 1) => {
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource))
}
("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)), ("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
("$prolog_lc_dir", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory)), ("$prolog_lc_dir", 1) => {
("$prolog_lc_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule)), Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
("$prolog_lc_stream", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream)), }
("$cpp_meta_predicate_property", 4) => Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty)), ("$prolog_lc_module", 1) => {
("$cpp_built_in_property", 2) => Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty)), Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
("$cpp_dynamic_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty)), }
("$cpp_multifile_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty)), ("$prolog_lc_stream", 1) => {
("$cpp_discontiguous_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty)), Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream))
}
("$cpp_meta_predicate_property", 4) => {
Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty))
}
("$cpp_built_in_property", 2) => {
Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty))
}
("$cpp_dynamic_property", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty))
}
("$cpp_multifile_property", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty))
}
("$cpp_discontiguous_property", 3) => {
Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty))
}
_ => None, _ => None,
} }
} }
@@ -832,10 +878,10 @@ impl ClauseType {
match self { match self {
&ClauseType::Op(_, ref spec, _) => Some(spec.clone()), &ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..)) &ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..)) | &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_)) | &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq) | &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)), | &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
_ => None, _ => None,
} }
} }

View File

@@ -1,6 +1,7 @@
/// Code generation to WAM-like instructions. /// Code generation to WAM-like instructions.
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::tabled_rc::TabledData; use prolog_parser::tabled_rc::TabledData;
use prolog_parser::{perm_v, temp_v};
use crate::allocator::*; use crate::allocator::*;
use crate::arithmetic::*; use crate::arithmetic::*;
@@ -14,7 +15,7 @@ use crate::targets::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use std::cell::Cell; use std::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
@@ -66,18 +67,14 @@ impl<'a> ConjunctInfo<'a> {
self.has_deep_cut as usize self.has_deep_cut as usize
} }
fn mark_unsafe_vars( fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
&self,
mut unsafe_var_marker: UnsafeVarMarker,
code: &mut Code,
) {
if code.is_empty() { if code.is_empty() {
return; return;
} }
let mut code_index = 0; let mut code_index = 0;
for phase in 0 .. { for phase in 0.. {
while let Line::Query(ref query_instr) = &code[code_index] { while let Line::Query(ref query_instr) = &code[code_index] {
if !unsafe_var_marker.mark_safe_vars(query_instr) { if !unsafe_var_marker.mark_safe_vars(query_instr) {
unsafe_var_marker.mark_phase(query_instr, phase); unsafe_var_marker.mark_phase(query_instr, phase);
@@ -95,7 +92,7 @@ impl<'a> ConjunctInfo<'a> {
code_index = 0; code_index = 0;
for phase in 0 .. { for phase in 0.. {
while let Line::Query(ref mut query_instr) = &mut code[code_index] { while let Line::Query(ref mut query_instr) = &mut code[code_index] {
unsafe_var_marker.mark_unsafe_vars(query_instr, phase); unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
code_index += 1; code_index += 1;
@@ -173,7 +170,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
code: &mut Code, code: &mut Code,
) -> RegType { ) -> RegType {
let mut target = Vec::new(); let mut target = Vec::new();
self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); self.marker
.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.extend(target.into_iter().map(Line::Query)); code.extend(target.into_iter().map(Line::Query));
@@ -191,9 +189,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
code: &mut Code, code: &mut Code,
) -> RegType { ) -> RegType {
match self.marker.bindings().get(&name) { match self.marker.bindings().get(&name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => { Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
RegType::Temp(t)
}
Some(&VarData::Perm(p)) if p != 0 => { Some(&VarData::Perm(p)) if p != 0 => {
if let GenContext::Last(_) = term_loc { if let GenContext::Last(_) = term_loc {
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code); self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
@@ -202,9 +198,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
RegType::Perm(p) RegType::Perm(p)
} }
} }
_ => { _ => self.mark_var_in_non_callable(name, term_loc, vr, code),
self.mark_var_in_non_callable(name, term_loc, vr, code)
}
} }
} }
@@ -231,7 +225,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
target: &mut Vec<Target>, target: &mut Vec<Target>,
) { ) {
if is_exposed || self.get_var_count(var.as_ref()) > 1 { if is_exposed || self.get_var_count(var.as_ref()) > 1 {
self.marker.mark_var(var.clone(), Level::Deep, cell, term_loc, target); self.marker
.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
} else { } else {
Self::add_or_increment_void_instr(target); Self::add_or_increment_void_instr(target);
} }
@@ -252,7 +247,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
Self::add_or_increment_void_instr(target); Self::add_or_increment_void_instr(target);
} }
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => { &Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
self.marker.mark_non_var(Level::Deep, term_loc, cell, target); self.marker
.mark_non_var(Level::Deep, term_loc, cell, target);
target.push(Target::clause_arg_to_instr(cell.get())); target.push(Target::clause_arg_to_instr(cell.get()));
} }
&Term::Constant(_, ref constant) => { &Term::Constant(_, ref constant) => {
@@ -264,7 +260,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
}; };
} }
fn compile_target<Target, Iter>( fn compile_target<Target, Iter>(
&mut self, &mut self,
iter: Iter, iter: Iter,
term_loc: GenContext, term_loc: GenContext,
@@ -334,13 +330,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
} }
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target); self.marker
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
} }
TermRef::Var(lvl @ Level::Shallow, cell, var) => { TermRef::Var(lvl @ Level::Shallow, cell, var) => {
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target); self.marker
} .mark_var(var.clone(), lvl, cell, term_loc, &mut target);
_ => {
} }
_ => {}
}; };
} }
@@ -353,8 +350,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() { while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
for (i, chunked_term) in chunked_terms.iter().enumerate() { for (i, chunked_term) in chunked_terms.iter().enumerate() {
let term_loc = match chunked_term { let term_loc = match chunked_term {
&ChunkedTerm::HeadClause(..) => &ChunkedTerm::HeadClause(..) => GenContext::Head,
GenContext::Head,
&ChunkedTerm::BodyTerm(_) => { &ChunkedTerm::BodyTerm(_) => {
if i < chunked_terms.len() - 1 { if i < chunked_terms.len() - 1 {
GenContext::Mid(chunk_num) GenContext::Mid(chunk_num)
@@ -391,8 +387,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&QueryTerm::Clause(_, ref ct, ref terms, false) => { &QueryTerm::Clause(_, ref ct, ref terms, false) => {
code.push(call_clause!(ct.clone(), terms.len(), pvs)); code.push(call_clause!(ct.clone(), terms.len(), pvs));
} }
_ => { _ => {}
}
} }
} }
@@ -407,8 +402,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => { &mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
*last_call = true; *last_call = true;
} }
&mut ControlInstruction::Proceed => { &mut ControlInstruction::Proceed => {}
}
_ => { _ => {
dealloc_index += 1; dealloc_index += 1;
} }
@@ -416,8 +410,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
Some(&mut Line::Cut(CutInstruction::Cut(_))) => { Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
dealloc_index += 1; dealloc_index += 1;
} }
_ => { _ => {}
}
}; };
dealloc_index dealloc_index
@@ -437,23 +430,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?; let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?; let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
let at_1 = let at_1 = if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
if let &Term::Var(ref vr, ref name) = terms[0].as_ref() { ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code))
ArithmeticTerm::Reg( } else {
self.mark_non_callable(name.clone(), 1, term_loc, vr, code) at_1.unwrap_or(interm!(1))
) };
} else {
at_1.unwrap_or(interm!(1))
};
let at_2 = let at_2 = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() { ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
ArithmeticTerm::Reg( } else {
self.mark_non_callable(name.clone(), 2, term_loc, vr, code) at_2.unwrap_or(interm!(2))
) };
} else {
at_2.unwrap_or(interm!(2))
};
code.append(&mut lcode); code.append(&mut lcode);
code.append(&mut rcode); code.append(&mut rcode);
@@ -461,9 +448,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
code.push(compare_number_instr!(cmp, at_1, at_2)); code.push(compare_number_instr!(cmp, at_1, at_2));
} }
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() { &InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
&Term::Constant(_, Constant::Char(_)) | &Term::Constant(_, Constant::Char(_))
&Term::Constant(_, Constant::EmptyList) | | &Term::Constant(_, Constant::EmptyList)
&Term::Constant(_, Constant::Atom(..)) => { | &Term::Constant(_, Constant::Atom(..)) => {
code.push(succeed!()); code.push(succeed!());
} }
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -528,11 +515,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
}, },
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() { &InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
&Term::Constant(_, Constant::Float(_)) | &Term::Constant(_, Constant::Float(_))
&Term::Constant(_, Constant::Rational(_)) | | &Term::Constant(_, Constant::Rational(_))
&Term::Constant(_, Constant::Integer(_)) | | &Term::Constant(_, Constant::Integer(_))
&Term::Constant(_, Constant::Fixnum(_)) | | &Term::Constant(_, Constant::Fixnum(_))
&Term::Constant(_, Constant::Usize(_)) => { | &Term::Constant(_, Constant::Usize(_)) => {
code.push(succeed!()); code.push(succeed!());
} }
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -558,9 +545,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
}, },
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() { &InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
&Term::Constant(_, Constant::Integer(_)) | &Term::Constant(_, Constant::Integer(_))
&Term::Constant(_, Constant::Fixnum(_)) | | &Term::Constant(_, Constant::Fixnum(_))
&Term::Constant(_, Constant::Usize(_)) => { | &Term::Constant(_, Constant::Usize(_)) => {
code.push(succeed!()); code.push(succeed!());
} }
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
@@ -615,14 +602,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
let mut target = vec![]; let mut target = vec![];
self.marker.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target); self.marker
.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
if !target.is_empty() { if !target.is_empty() {
code.extend(target.into_iter().map(Line::Query)); code.extend(target.into_iter().map(Line::Query));
} }
} }
&Term::Constant(_, ref c @ Constant::Integer(_)) | &Term::Constant(_, ref c @ Constant::Integer(_))
&Term::Constant(_, ref c @ Constant::Fixnum(_)) => { | &Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
code.push(Line::Query(put_constant!( code.push(Line::Query(put_constant!(
Level::Shallow, Level::Shallow,
c.clone(), c.clone(),
@@ -655,14 +643,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
} }
let at = let at = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() { ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
ArithmeticTerm::Reg( } else {
self.mark_non_callable(name.clone(), 2, term_loc, vr, code) at.unwrap_or(interm!(1))
) };
} else {
at.unwrap_or(interm!(1))
};
Ok(if use_default_call_policy { Ok(if use_default_call_policy {
code.push(is_call_by_default!(temp_v!(1), at)); code.push(is_call_by_default!(temp_v!(1), at));
@@ -721,24 +706,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => { &QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc) self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
} }
&QueryTerm::UnblockedCut(ref cell) => { &QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
self.compile_unblocked_cut(code, cell) &QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
} Line::Cut(CutInstruction::NeckCut)
&QueryTerm::BlockedCut => { } else {
code.push(if chunk_num == 0 { Line::Cut(CutInstruction::Cut(perm_v!(1)))
Line::Cut(CutInstruction::NeckCut) }),
} else {
Line::Cut(CutInstruction::Cut(perm_v!(1)))
})
}
&QueryTerm::Clause( &QueryTerm::Clause(
_, _,
ClauseType::BuiltIn(BuiltInClauseType::Is(..)), ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
ref terms, ref terms,
use_default_call_policy, use_default_call_policy,
) => { ) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
self.compile_is_call(terms, code, term_loc, use_default_call_policy)?
}
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => { &QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
self.compile_inlined(ct, terms, term_loc, code)? self.compile_inlined(ct, terms, term_loc, code)?
} }
@@ -772,7 +751,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
} }
} }
fn compile_cleanup(&mut self, code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) { fn compile_cleanup(
&mut self,
code: &mut Code,
conjunct_info: &ConjunctInfo,
toc: &'a QueryTerm,
) {
// add a proceed to bookend any trailing cuts. // add a proceed to bookend any trailing cuts.
match toc { match toc {
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()), &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
@@ -786,7 +770,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
if conjunct_info.allocates() { if conjunct_info.allocates() {
let offset = self.global_jmp_by_locs_offset; let offset = self.global_jmp_by_locs_offset;
if let Some(jmp_by_offset) = self.jmp_by_locs[offset ..].last_mut() { if let Some(jmp_by_offset) = self.jmp_by_locs[offset..].last_mut() {
if *jmp_by_offset == dealloc_index { if *jmp_by_offset == dealloc_index {
*jmp_by_offset += 1; *jmp_by_offset += 1;
} }
@@ -905,32 +889,32 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
self.add_conditional_call(code, term, num_perm_vars_left); self.add_conditional_call(code, term, num_perm_vars_left);
} }
/* /*
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> { pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
let iter = ChunkedIterator::from_term_sequence(query); let iter = ChunkedIterator::from_term_sequence(query);
let conjunct_info = self.collect_var_data(iter); let conjunct_info = self.collect_var_data(iter);
let mut code = Vec::new(); let mut code = Vec::new();
self.compile_seq_prelude(&conjunct_info, &mut code); self.compile_seq_prelude(&conjunct_info, &mut code);
let iter = ChunkedIterator::from_term_sequence(query); let iter = ChunkedIterator::from_term_sequence(query);
self.compile_seq(iter, &conjunct_info, &mut code, true)?; self.compile_seq(iter, &conjunct_info, &mut code, true)?;
conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code); conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code);
if let Some(query_term) = query.last() { if let Some(query_term) = query.last() {
Self::compile_cleanup(&mut code, &conjunct_info, query_term); Self::compile_cleanup(&mut code, &conjunct_info, query_term);
}
Ok(code)
} }
*/
Ok(code)
}
*/
#[inline] #[inline]
fn increment_jmp_by_locs_by(&mut self, incr: usize) { fn increment_jmp_by_locs_by(&mut self, incr: usize) {
let offset = self.global_jmp_by_locs_offset; let offset = self.global_jmp_by_locs_offset;
for loc in &mut self.jmp_by_locs[offset ..] { for loc in &mut self.jmp_by_locs[offset..] {
*loc += incr; *loc += incr;
} }
} }
@@ -1077,7 +1061,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
if skip_stub_try_me_else { if skip_stub_try_me_else {
// skip the TryMeElse(0) also. // skip the TryMeElse(0) also.
self.increment_jmp_by_locs_by(2); self.increment_jmp_by_locs_by(2);
} else { } else {
self.increment_jmp_by_locs_by(1); self.increment_jmp_by_locs_by(1);
} }
@@ -1105,7 +1089,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
for (l, r) in split_pred { for (l, r) in split_pred {
let skel_lower_bound = self.skeleton.clauses.len(); let skel_lower_bound = self.skeleton.clauses.len();
let code_segment = self.compile_pred_subseq(&clauses[l .. r], optimal_index)?; let code_segment = self.compile_pred_subseq(&clauses[l..r], optimal_index)?;
let clause_start_offset = code.len(); let clause_start_offset = code.len();
if multi_seq { if multi_seq {
@@ -1123,11 +1107,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
if self.is_extensible { if self.is_extensible {
let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some(); let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some();
for clause_index_info in self.skeleton.clauses[skel_lower_bound ..].iter_mut() { for clause_index_info in self.skeleton.clauses[skel_lower_bound..].iter_mut() {
clause_index_info.clause_start += clause_index_info.clause_start +=
clause_start_offset + 2 * (segment_is_indexed as usize); clause_start_offset + 2 * (segment_is_indexed as usize);
clause_index_info.opt_arg_index_key += clause_index_info.opt_arg_index_key += clause_start_offset + 1;
clause_start_offset + 1;
} }
} }

View File

@@ -1,6 +1,7 @@
use crate::indexmap::IndexMap; use indexmap::IndexMap;
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::temp_v;
use crate::allocator::*; use crate::allocator::*;
use crate::fixtures::*; use crate::fixtures::*;
@@ -293,9 +294,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
(pr, true) (pr, true)
} }
r => { r => (r, false),
(r, false)
}
}; };
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var); self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);

View File

@@ -1,10 +1,10 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::forms::*; use crate::forms::*;
use crate::instructions::*; use crate::instructions::*;
use crate::iterators::*; use crate::iterators::*;
use crate::indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use std::cell::Cell; use std::cell::Cell;
use std::collections::BTreeSet; use std::collections::BTreeSet;
@@ -83,18 +83,17 @@ impl TempVarData {
type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>); type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
#[derive(Debug)] #[derive(Debug)]
pub struct VariableFixtures<'a>{ pub struct VariableFixtures<'a> {
perm_vars: IndexMap<Rc<Var>, VariableFixture<'a>>, perm_vars: IndexMap<Rc<Var>, VariableFixture<'a>>,
last_chunk_temp_vars: IndexSet<Rc<Var>> last_chunk_temp_vars: IndexSet<Rc<Var>>,
} }
impl<'a> VariableFixtures<'a> { impl<'a> VariableFixtures<'a> {
pub fn new() -> Self { pub fn new() -> Self {
VariableFixtures { VariableFixtures {
perm_vars: IndexMap::new(), perm_vars: IndexMap::new(),
last_chunk_temp_vars: IndexSet::new() last_chunk_temp_vars: IndexSet::new(),
} }
} }
pub fn insert(&mut self, var: Rc<Var>, vs: VariableFixture<'a>) { pub fn insert(&mut self, var: Rc<Var>, vs: VariableFixture<'a>) {
@@ -262,34 +261,32 @@ impl UnsafeVarMarker {
pub fn new() -> Self { pub fn new() -> Self {
UnsafeVarMarker { UnsafeVarMarker {
unsafe_vars: IndexMap::new(), unsafe_vars: IndexMap::new(),
safe_vars: IndexSet::new() safe_vars: IndexSet::new(),
} }
} }
pub fn from_safe_vars(safe_vars: IndexSet<RegType>) -> Self { pub fn from_safe_vars(safe_vars: IndexSet<RegType>) -> Self {
UnsafeVarMarker { UnsafeVarMarker {
unsafe_vars: IndexMap::new(), unsafe_vars: IndexMap::new(),
safe_vars safe_vars,
} }
} }
pub fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) -> bool { pub fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) -> bool {
match query_instr { match query_instr {
&QueryInstruction::PutVariable(r @ RegType::Temp(_), _) &QueryInstruction::PutVariable(r @ RegType::Temp(_), _)
| &QueryInstruction::SetVariable(r) => { | &QueryInstruction::SetVariable(r) => {
self.safe_vars.insert(r); self.safe_vars.insert(r);
true true
} }
_ => { _ => false,
false
}
} }
} }
pub fn mark_phase(&mut self, query_instr: &QueryInstruction, phase: usize) { pub fn mark_phase(&mut self, query_instr: &QueryInstruction, phase: usize) {
match query_instr { match query_instr {
&QueryInstruction::PutValue(r @ RegType::Perm(_), _) &QueryInstruction::PutValue(r @ RegType::Perm(_), _)
| &QueryInstruction::SetValue(r) => { | &QueryInstruction::SetValue(r) => {
let p = self.unsafe_vars.entry(r).or_insert(0); let p = self.unsafe_vars.entry(r).or_insert(0);
*p = phase; *p = phase;
} }

View File

@@ -1,13 +1,14 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::parser::OpDesc; use prolog_parser::parser::OpDesc;
use prolog_parser::{clause_name, is_infix, is_postfix};
use crate::clause_types::*; use crate::clause_types::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::ordered_float::OrderedFloat;
use crate::rug::{Integer, Rational}; use crate::rug::{Integer, Rational};
use ordered_float::OrderedFloat;
use crate::indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use slice_deque::*; use slice_deque::*;
@@ -36,7 +37,7 @@ pub enum TopLevel {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum AppendOrPrepend { pub enum AppendOrPrepend {
Append, Append,
Prepend Prepend,
} }
impl AppendOrPrepend { impl AppendOrPrepend {
@@ -115,12 +116,8 @@ impl ListingSource {
pub trait ClauseInfo { pub trait ClauseInfo {
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool { fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
match clauses.first() { match clauses.first() {
Some(cl) => { Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
self.name() == cl.name() && self.arity() == cl.arity() None => true,
}
None => {
true
}
} }
} }
@@ -140,38 +137,25 @@ impl ClauseInfo for Term {
_ => Some(clause_name!(":-")), _ => Some(clause_name!(":-")),
} }
} }
_ => { _ => Some(name.clone()),
Some(name.clone())
}
} }
} }
Term::Constant(_, Constant::Atom(ref name, _)) => { Term::Constant(_, Constant::Atom(ref name, _)) => Some(name.clone()),
Some(name.clone()) _ => None,
}
_ => {
None
}
} }
} }
fn arity(&self) -> usize { fn arity(&self) -> usize {
match self { match self {
Term::Clause(_, ref name, ref terms, _) => Term::Clause(_, ref name, ref terms, _) => match name.as_str() {
match name.as_str() { ":-" => match terms.len() {
":-" => { 1 => 0,
match terms.len() { 2 => terms[0].arity(),
1 => 0, _ => terms.len(),
2 => terms[0].arity(),
_ => terms.len(),
}
}
_ => {
terms.len()
}
}, },
_ => { _ => terms.len(),
0 },
} _ => 0,
} }
} }
} }
@@ -189,23 +173,15 @@ impl ClauseInfo for Rule {
impl ClauseInfo for PredicateClause { impl ClauseInfo for PredicateClause {
fn name(&self) -> Option<ClauseName> { fn name(&self) -> Option<ClauseName> {
match self { match self {
&PredicateClause::Fact(ref term, ..) => { &PredicateClause::Fact(ref term, ..) => term.name(),
term.name() &PredicateClause::Rule(ref rule, ..) => rule.name(),
}
&PredicateClause::Rule(ref rule, ..) => {
rule.name()
}
} }
} }
fn arity(&self) -> usize { fn arity(&self) -> usize {
match self { match self {
&PredicateClause::Fact(ref term, ..) => { &PredicateClause::Fact(ref term, ..) => term.arity(),
term.arity() &PredicateClause::Rule(ref rule, ..) => rule.arity(),
}
&PredicateClause::Rule(ref rule, ..) => {
rule.arity()
}
} }
} }
} }
@@ -222,11 +198,9 @@ impl PredicateClause {
// TODO: add this to `Term` in `prolog_parser` like `first_arg`. // TODO: add this to `Term` in `prolog_parser` like `first_arg`.
pub fn args(&self) -> Option<&[Box<Term>]> { pub fn args(&self) -> Option<&[Box<Term>]> {
match *self { match *self {
PredicateClause::Fact(ref term, ..) => { PredicateClause::Fact(ref term, ..) => match term {
match term { Term::Clause(_, _, args, _) => Some(&args),
Term::Clause(_, _, args, _) => Some(&args), _ => None,
_ => None,
}
}, },
PredicateClause::Rule(ref rule, ..) => { PredicateClause::Rule(ref rule, ..) => {
if rule.head.1.is_empty() { if rule.head.1.is_empty() {
@@ -240,14 +214,11 @@ impl PredicateClause {
pub fn arity(&self) -> usize { pub fn arity(&self) -> usize {
match self { match self {
&PredicateClause::Fact(ref term, ..) => { &PredicateClause::Fact(ref term, ..) => term.arity(),
term.arity()
}
&PredicateClause::Rule(ref rule, ..) => { &PredicateClause::Rule(ref rule, ..) => {
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 { if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
match (rule.head.1)[0].as_ref() { match (rule.head.1)[0].as_ref() {
&Term::Constant(_, Constant::Atom(..)) => { &Term::Constant(_, Constant::Atom(..)) => {}
}
_ => { _ => {
return 2; return 2;
} }
@@ -321,7 +292,7 @@ pub enum Declaration {
pub struct OpDecl { pub struct OpDecl {
pub prec: usize, pub prec: usize,
pub spec: Specifier, pub spec: Specifier,
pub name: ClauseName pub name: ClauseName,
} }
impl OpDecl { impl OpDecl {
@@ -345,7 +316,7 @@ impl OpDecl {
XFY | XFX | YFX => Fixity::In, XFY | XFX | YFX => Fixity::In,
XF | YF => Fixity::Post, XF | YF => Fixity::Post,
FX | FY => Fixity::Pre, FX | FY => Fixity::Pre,
_ => unreachable!() _ => unreachable!(),
} }
} }
@@ -356,12 +327,12 @@ impl OpDecl {
Some(cell) => { Some(cell) => {
return Some(cell.shared_op_desc().replace((self.prec, self.spec))); return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
} }
None => { None => {}
}
} }
op_dir.insert(key, OpDirValue::new(self.spec, self.prec)) op_dir
.map(|op_dir_value| op_dir_value.shared_op_desc().get()) .insert(key, OpDirValue::new(self.spec, self.prec))
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
} }
pub fn submit( pub fn submit(
@@ -419,11 +390,7 @@ pub fn fetch_op_spec_from_existing(
spec.or_else(|| fetch_op_spec(name, arity, op_dir)) spec.or_else(|| fetch_op_spec(name, arity, op_dir))
} }
pub fn fetch_op_spec( pub fn fetch_op_spec(name: ClauseName, arity: usize, op_dir: &OpDir) -> Option<SharedOpDesc> {
name: ClauseName,
arity: usize,
op_dir: &OpDir,
) -> Option<SharedOpDesc> {
match arity { match arity {
2 => op_dir 2 => op_dir
.get(&(name, Fixity::In)) .get(&(name, Fixity::In))
@@ -451,9 +418,7 @@ pub fn fetch_op_spec(
} }
}) })
} }
_ => { _ => None,
None
}
} }
} }
@@ -499,7 +464,6 @@ impl Module {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Number { pub enum Number {
Float(OrderedFloat<f64>), Float(OrderedFloat<f64>),
@@ -559,7 +523,6 @@ impl Into<HeapCellValue> for Number {
} }
} }
impl Number { impl Number {
#[inline] #[inline]
pub fn is_positive(&self) -> bool { pub fn is_positive(&self) -> bool {
@@ -594,12 +557,13 @@ impl Number {
#[inline] #[inline]
pub fn abs(self) -> Self { pub fn abs(self) -> Self {
match self { match self {
Number::Fixnum(n) => Number::Fixnum(n) => {
if let Some(n) = n.checked_abs() { if let Some(n) = n.checked_abs() {
Number::from(n) Number::from(n)
} else { } else {
Number::from(Integer::from(n).abs()) Number::from(Integer::from(n).abs())
} }
}
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())), Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
Number::Float(f) => Number::Float(OrderedFloat(f.abs())), Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())), Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
@@ -624,15 +588,13 @@ impl OptArgIndexKey {
#[inline] #[inline]
pub fn arg_num(&self) -> usize { pub fn arg_num(&self) -> usize {
match &self { match &self {
OptArgIndexKey::Constant(arg_num, ..) | OptArgIndexKey::Constant(arg_num, ..)
OptArgIndexKey::Structure(arg_num, ..) | | OptArgIndexKey::Structure(arg_num, ..)
OptArgIndexKey::List(arg_num, _) => { | OptArgIndexKey::List(arg_num, _) => {
// these are always at least 1. // these are always at least 1.
*arg_num *arg_num
} }
OptArgIndexKey::None => { OptArgIndexKey::None => 0,
0
}
} }
} }
@@ -644,27 +606,22 @@ impl OptArgIndexKey {
#[inline] #[inline]
pub fn switch_on_term_loc(&self) -> Option<usize> { pub fn switch_on_term_loc(&self) -> Option<usize> {
match &self { match &self {
OptArgIndexKey::Constant(_, loc, ..) | OptArgIndexKey::Constant(_, loc, ..)
OptArgIndexKey::Structure(_, loc, ..) | | OptArgIndexKey::Structure(_, loc, ..)
OptArgIndexKey::List(_, loc) => { | OptArgIndexKey::List(_, loc) => Some(*loc),
Some(*loc) OptArgIndexKey::None => None,
}
OptArgIndexKey::None => {
None
}
} }
} }
#[inline] #[inline]
pub fn set_switch_on_term_loc(&mut self, value: usize) { pub fn set_switch_on_term_loc(&mut self, value: usize) {
match self { match self {
OptArgIndexKey::Constant(_, ref mut loc, ..) | OptArgIndexKey::Constant(_, ref mut loc, ..)
OptArgIndexKey::Structure(_, ref mut loc, ..) | | OptArgIndexKey::Structure(_, ref mut loc, ..)
OptArgIndexKey::List(_, ref mut loc) => { | OptArgIndexKey::List(_, ref mut loc) => {
*loc = value; *loc = value;
} }
OptArgIndexKey::None => { OptArgIndexKey::None => {}
}
} }
} }
} }
@@ -673,13 +630,12 @@ impl AddAssign<usize> for OptArgIndexKey {
#[inline] #[inline]
fn add_assign(&mut self, n: usize) { fn add_assign(&mut self, n: usize) {
match self { match self {
OptArgIndexKey::Constant(_, ref mut o, ..) | OptArgIndexKey::Constant(_, ref mut o, ..)
OptArgIndexKey::List(_, ref mut o) | | OptArgIndexKey::List(_, ref mut o)
OptArgIndexKey::Structure(_, ref mut o, ..) => { | OptArgIndexKey::Structure(_, ref mut o, ..) => {
*o += n; *o += n;
} }
OptArgIndexKey::None => { OptArgIndexKey::None => {}
}
} }
} }
} }

View File

@@ -1,7 +1,7 @@
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::machine_state::*; use crate::machine::machine_state::*;
use crate::indexmap::IndexSet; use indexmap::IndexSet;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ops::Deref; use std::ops::Deref;
@@ -29,31 +29,21 @@ impl<'a> HCPreOrderIterator<'a> {
fn follow_heap(&mut self, h: usize) -> Addr { fn follow_heap(&mut self, h: usize) -> Addr {
match &self.machine_st.heap[h] { match &self.machine_st.heap[h] {
&HeapCellValue::NamedStr(arity, _, _) => { &HeapCellValue::NamedStr(arity, _, _) => {
for idx in (1 .. arity + 1).rev() { for idx in (1..arity + 1).rev() {
self.state_stack.push(Addr::HeapCell(h + idx)); self.state_stack.push(Addr::HeapCell(h + idx));
} }
Addr::Str(h) Addr::Str(h)
} }
&HeapCellValue::Addr(a) => { &HeapCellValue::Addr(a) => self.follow(a),
self.follow(a) HeapCellValue::PartialString(..) => self.follow(Addr::PStrLocation(h, 0)),
} HeapCellValue::Atom(..)
HeapCellValue::PartialString(..) => { | HeapCellValue::DBRef(_)
self.follow(Addr::PStrLocation(h, 0)) | HeapCellValue::Integer(_)
} | HeapCellValue::Rational(_) => Addr::Con(h),
HeapCellValue::Atom(..) | HeapCellValue::DBRef(_) HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(h),
| HeapCellValue::Integer(_) | HeapCellValue::Rational(_) => { HeapCellValue::Stream(_) => Addr::Stream(h),
Addr::Con(h) HeapCellValue::TcpListener(_) => Addr::TcpListener(h),
}
HeapCellValue::LoadStatePayload(_) => {
Addr::LoadStatePayload(h)
}
HeapCellValue::Stream(_) => {
Addr::Stream(h)
}
HeapCellValue::TcpListener(_) => {
Addr::TcpListener(h)
}
} }
} }
@@ -71,10 +61,12 @@ impl<'a> HCPreOrderIterator<'a> {
da da
} }
Addr::PStrLocation(h, n) => { Addr::PStrLocation(h, n) => {
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] { if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h]
if let Some(c) = pstr.range_from(n ..).next() { {
if let Some(c) = pstr.range_from(n..).next() {
if !pstr.at_end(n + c.len_utf8()) { if !pstr.at_end(n + c.len_utf8()) {
self.state_stack.push(Addr::PStrLocation(h, n + c.len_utf8())); self.state_stack
.push(Addr::PStrLocation(h, n + c.len_utf8()));
} else if has_tail { } else if has_tail {
self.state_stack.push(Addr::HeapCell(h + 1)); self.state_stack.push(Addr::HeapCell(h + 1));
} else { } else {
@@ -95,8 +87,9 @@ impl<'a> HCPreOrderIterator<'a> {
self.follow_heap(s) // record terms of structure. self.follow_heap(s) // record terms of structure.
} }
Addr::Con(h) => { Addr::Con(h) => {
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] { if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h]
if let Some(c) = pstr.range_from(0 ..).next() { {
if let Some(c) = pstr.range_from(0..).next() {
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8())); self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
self.state_stack.push(Addr::Char(c)); self.state_stack.push(Addr::Char(c));
@@ -110,9 +103,7 @@ impl<'a> HCPreOrderIterator<'a> {
Addr::Con(h) Addr::Con(h)
} }
} }
da => { da => da,
da
}
} }
} }
} }
@@ -125,7 +116,9 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
} }
} }
pub trait MutStackHCIterator<'b> where Self: Iterator pub trait MutStackHCIterator<'b>
where
Self: Iterator,
{ {
type MutStack; type MutStack;
@@ -178,7 +171,8 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
} }
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => { &HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
match &self.machine_st.heap[h] { match &self.machine_st.heap[h] {
&HeapCellValue::PartialString(..) => {// ref pstr, _) => { &HeapCellValue::PartialString(..) => {
// ref pstr, _) => {
/* /*
let c = pstr.range_from(n ..).next().unwrap(); let c = pstr.range_from(n ..).next().unwrap();
let next_n = n + c.len_utf8(); let next_n = n + c.len_utf8();
@@ -215,7 +209,7 @@ impl MachineState {
HCPostOrderIterator::new(HCPreOrderIterator::new(self, a)) HCPostOrderIterator::new(HCPreOrderIterator::new(self, a))
} }
pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr,) -> HCAcyclicIterator<'a> { pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicIterator<'a> {
HCAcyclicIterator::new(HCPreOrderIterator::new(self, a)) HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
} }
@@ -270,8 +264,7 @@ impl<'b, 'a: 'b> MutStackHCIterator<'b> for HCAcyclicIterator<'a> {
} }
} }
impl<'a> Iterator for HCAcyclicIterator<'a> impl<'a> Iterator for HCAcyclicIterator<'a> {
{
type Item = Addr; type Item = Addr;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@@ -315,8 +308,7 @@ impl<'a> HCZippedAcyclicIterator<'a> {
} }
} }
impl<'a> Iterator for HCZippedAcyclicIterator<'a> impl<'a> Iterator for HCZippedAcyclicIterator<'a> {
{
type Item = (Addr, Addr); type Item = (Addr, Addr);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@@ -341,9 +333,7 @@ impl<'a> Iterator for HCZippedAcyclicIterator<'a>
self.first_to_expire = Ordering::Less; self.first_to_expire = Ordering::Less;
None None
} }
_ => { _ => None,
None
}
} }
} }
} }

View File

@@ -1,4 +1,10 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::{
alpha_numeric_char, capital_letter_char, clause_name, cut_char, decimal_digit_char,
graphic_token_char, is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx,
semicolon_char, sign_char, single_quote_char, small_letter_char, solo_char,
variable_indicator_char,
};
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -7,14 +13,14 @@ use crate::machine::heap::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::machine_state::*; use crate::machine::machine_state::*;
use crate::machine::streams::*; use crate::machine::streams::*;
use crate::ordered_float::OrderedFloat;
use crate::rug::{Integer, Rational}; use crate::rug::{Integer, Rational};
use ordered_float::OrderedFloat;
use crate::indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use std::cell::Cell; use std::cell::Cell;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::iter::{FromIterator, once}; use std::iter::{once, FromIterator};
use std::net::{IpAddr, TcpListener}; use std::net::{IpAddr, TcpListener};
use std::ops::{Range, RangeFrom}; use std::ops::{Range, RangeFrom};
use std::rc::Rc; use std::rc::Rc;
@@ -99,10 +105,7 @@ impl<'a> HCPreOrderIterator<'a> {
None => return false, None => return false,
}; };
let mut parent_spec = DirectedOp::Left( let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
clause_name!("-"),
SharedOpDesc::new(200, FY),
);
loop { loop {
match self.machine_st.store(self.machine_st.deref(addr)) { match self.machine_st.store(self.machine_st.deref(addr)) {
@@ -154,12 +157,13 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert '\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
'"' if is_quoted => "\\\"".to_string(), '"' if is_quoted => "\\\"".to_string(),
'\\' if is_quoted => "\\\\".to_string(), '\\' if is_quoted => "\\\\".to_string(),
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => '\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
c.to_string(), c.to_string()
'\u{a0}' ..= '\u{d6}' => c.to_string(), }
'\u{d8}' ..= '\u{f6}' => c.to_string(), '\u{a0}'..='\u{d6}' => c.to_string(),
'\u{f8}' ..= '\u{74f}' => c.to_string(), '\u{d8}'..='\u{f6}' => c.to_string(),
'\x20' ..= '\x7e' => c.to_string(), '\u{f8}'..='\u{74f}' => c.to_string(),
'\x20'..='\x7e' => c.to_string(),
_ => format!("\\x{:x}\\", c as u32), _ => format!("\\x{:x}\\", c as u32),
} }
} }
@@ -271,25 +275,13 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
#[inline] #[inline]
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool { fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
if let Some(ref op) = op { if let Some(ref op) = op {
op.is_negative_sign() && op.is_negative_sign()
iter.leftmost_leaf_has_property(|addr, heap| { && iter.leftmost_leaf_has_property(|addr, heap| match Number::try_from((addr, heap)) {
match Number::try_from((addr, heap)) { Ok(Number::Fixnum(n)) => n > 0,
Ok(Number::Fixnum(n)) => { Ok(Number::Float(f)) => f > OrderedFloat(0f64),
n > 0 Ok(Number::Integer(n)) => &*n > &0,
} Ok(Number::Rational(n)) => &*n > &0,
Ok(Number::Float(f)) => { _ => false,
f > OrderedFloat(0f64)
}
Ok(Number::Integer(n)) => {
&*n > &0
}
Ok(Number::Rational(n)) => {
&*n > &0
}
_ => {
false
}
}
}) })
} else { } else {
false false
@@ -298,8 +290,8 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
fn numbervar(n: Integer) -> Var { fn numbervar(n: Integer) -> Var {
static CHAR_CODES: [char; 26] = [ static CHAR_CODES: [char; 26] = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
]; ];
let i = n.mod_u(26) as usize; let i = n.mod_u(26) as usize;
@@ -332,9 +324,7 @@ impl MachineState {
None None
} }
} }
_ => { _ => None,
None
}
} }
} }
} }
@@ -446,8 +436,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
} }
} }
pub(super) pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
if let Some(c) = iter.next() { if let Some(c) = iter.next() {
if small_letter_char!(c) { if small_letter_char!(c) {
iter.all(|c| alpha_numeric_char!(c)) iter.all(|c| alpha_numeric_char!(c))
@@ -505,37 +494,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth: 0, max_depth: 0,
} }
} }
/* /*
pub fn from_heap_locs( pub fn from_heap_locs(
machine_st: &'a MachineState, machine_st: &'a MachineState,
op_dir: &'a OpDir, op_dir: &'a OpDir,
output: Outputter, output: Outputter,
) -> Self { ) -> Self {
let mut printer = Self::new(machine_st, op_dir, output); let mut printer = Self::new(machine_st, op_dir, output);
printer.toplevel_spec = Some(DirectedOp::Right( printer.toplevel_spec = Some(DirectedOp::Right(
clause_name!("="), clause_name!("="),
SharedOpDesc::new(700, XFX), SharedOpDesc::new(700, XFX),
)); ));
printer.heap_locs = reverse_heap_locs(machine_st); printer.heap_locs = reverse_heap_locs(machine_st);
printer printer
}
*/
/*
pub fn drop_toplevel_spec(&mut self) {
self.toplevel_spec = None;
}
*/
/*
#[inline]
pub fn see_all_locs(&mut self) {
for key in self.heap_locs.keys().cloned() {
self.printed_vars.insert(key);
} }
} */
*/ /*
pub fn drop_toplevel_spec(&mut self) {
self.toplevel_spec = None;
}
*/
/*
#[inline]
pub fn see_all_locs(&mut self) {
for key in self.heap_locs.keys().cloned() {
self.printed_vars.insert(key);
}
}
*/
#[inline] #[inline]
fn ambiguity_check(&self, atom: &str) -> bool { fn ambiguity_check(&self, atom: &str) -> bool {
@@ -555,7 +544,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
@@ -579,7 +569,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
return; return;
@@ -587,7 +578,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op)); self.state_stack.push(TokenOrRedirect::CompositeRedirect(
max_depth,
left_directed_op,
));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
} else { } else {
match ct.name().as_str() { match ct.name().as_str() {
@@ -602,9 +596,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
iter.stack().pop(); iter.stack().pop();
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
@@ -612,11 +608,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone()); let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone()); let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
self.state_stack self.state_stack.push(TokenOrRedirect::CompositeRedirect(
.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op)); max_depth,
left_directed_op,
));
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec)); self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
self.state_stack self.state_stack.push(TokenOrRedirect::CompositeRedirect(
.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op)); max_depth,
right_directed_op,
));
} }
} }
@@ -626,15 +626,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
mut max_depth: usize, mut max_depth: usize,
arity: usize, arity: usize,
name: ClauseName, name: ClauseName,
) -> bool ) -> bool {
{
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
for _ in 0 .. arity { for _ in 0..arity {
iter.stack().pop(); iter.stack().pop();
} }
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Open);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
@@ -644,8 +644,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
for _ in 0 .. arity { for _ in 0..arity {
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::Comma); self.state_stack.push(TokenOrRedirect::Comma);
} }
@@ -662,12 +663,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
iter: &mut HCPreOrderIterator, iter: &mut HCPreOrderIterator,
mut max_depth: usize, mut max_depth: usize,
name: ClauseName, name: ClauseName,
spec: SharedOpDesc) spec: SharedOpDesc,
{ ) {
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::Space); self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
@@ -676,7 +678,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let op = DirectedOp::Left(name.clone(), spec); let op = DirectedOp::Left(name.clone(), spec);
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op)); self.state_stack
.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
self.state_stack.push(TokenOrRedirect::Space); self.state_stack.push(TokenOrRedirect::Space);
self.state_stack.push(TokenOrRedirect::Atom(name)); self.state_stack.push(TokenOrRedirect::Atom(name));
} }
@@ -687,14 +690,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
mut max_depth: usize, mut max_depth: usize,
name: ClauseName, name: ClauseName,
spec: SharedOpDesc, spec: SharedOpDesc,
) ) {
{
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::BarAsOp); self.state_stack.push(TokenOrRedirect::BarAsOp);
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
@@ -702,25 +706,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone()); let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone()); let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op)); self.state_stack.push(TokenOrRedirect::CompositeRedirect(
max_depth,
left_directed_op,
));
self.state_stack.push(TokenOrRedirect::BarAsOp); self.state_stack.push(TokenOrRedirect::BarAsOp);
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op)); self.state_stack.push(TokenOrRedirect::CompositeRedirect(
max_depth,
right_directed_op,
));
} }
fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool {
{
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::RightCurly); self.state_stack.push(TokenOrRedirect::RightCurly);
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::LeftCurly); self.state_stack.push(TokenOrRedirect::LeftCurly);
return false; return false;
} }
self.state_stack.push(TokenOrRedirect::RightCurly); self.state_stack.push(TokenOrRedirect::RightCurly);
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::LeftCurly); self.state_stack.push(TokenOrRedirect::LeftCurly);
true true
@@ -795,18 +806,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
match addr { match addr {
Addr::Lis(h) | Addr::Str(h) => { Addr::Lis(h) | Addr::Str(h) => Some(format!("{}", h)),
Some(format!("{}", h))
}
_ => { _ => {
if let Some(r) = addr.as_var() { if let Some(r) = addr.as_var() {
match r { match r {
Ref::StackCell(fr, sc) => { Ref::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
Some(format!("_s_{}_{}", fr, sc)) Ref::HeapCell(h) | Ref::AttrVar(h) => Some(format!("_{}", h)),
}
Ref::HeapCell(h) | Ref::AttrVar(h) => {
Some(format!("_{}", h))
}
} }
} else { } else {
None None
@@ -818,8 +823,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
fn record_children_as_non_cyclic(&mut self, addr: &Addr) { fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
match addr { match addr {
&Addr::Lis(l) => { &Addr::Lis(l) => {
let c1 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l))); let c1 = self
let c2 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l + 1))); .machine_st
.store(self.machine_st.deref(Addr::HeapCell(l)));
let c2 = self
.machine_st
.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
if let Some(c) = functor_location(&c1) { if let Some(c) = functor_location(&c1) {
self.non_cyclic_terms.insert(c); self.non_cyclic_terms.insert(c);
@@ -830,18 +839,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
} }
&Addr::Str(s) => { &Addr::Str(s) => {
let arity = let arity = match &self.machine_st.heap[s] {
match &self.machine_st.heap[s] { HeapCellValue::NamedStr(arity, ..) => arity,
HeapCellValue::NamedStr(arity, ..) => { _ => {
arity unreachable!()
} }
_ => { };
unreachable!()
}
};
for i in 1 .. arity + 1 { for i in 1..arity + 1 {
let c = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(s + i))); let c = self
.machine_st
.store(self.machine_st.deref(Addr::HeapCell(s + i)));
if let Some(c) = functor_location(&c) { if let Some(c) = functor_location(&c) {
self.non_cyclic_terms.insert(c); self.non_cyclic_terms.insert(c);
@@ -856,15 +864,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
self.non_cyclic_terms.insert(c); self.non_cyclic_terms.insert(c);
} }
} }
_ => { _ => {}
}
} }
} }
fn check_for_seen( fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<Addr> {
&mut self,
iter: &mut HCPreOrderIterator,
) -> Option<Addr> {
iter.stack().last().cloned().and_then(|addr| { iter.stack().last().cloned().and_then(|addr| {
let addr = self.machine_st.store(self.machine_st.deref(addr)); let addr = self.machine_st.store(self.machine_st.deref(addr));
@@ -889,9 +893,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
None => { None => {
let offset = match functor_location(&addr) { let offset = match functor_location(&addr) {
Some(offset) => { Some(offset) => offset,
offset
}
None => { None => {
return iter.next(); return iter.next();
} }
@@ -1036,19 +1038,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let rdiv_ct = clause_name!("rdiv"); let rdiv_ct = clause_name!("rdiv");
let left_directed_op = let left_directed_op = if spec.prec() > 0 {
if spec.prec() > 0 { Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone())) } else {
} else { None
None };
};
let right_directed_op = let right_directed_op = if spec.prec() > 0 {
if spec.prec() > 0 { Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone())) } else {
} else { None
None };
};
if spec.prec() > 0 { if spec.prec() > 0 {
self.state_stack.push(TokenOrRedirect::Number( self.state_stack.push(TokenOrRedirect::Number(
@@ -1056,10 +1056,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
left_directed_op, left_directed_op,
)); ));
self.state_stack.push(TokenOrRedirect::Op( self.state_stack
rdiv_ct, .push(TokenOrRedirect::Op(rdiv_ct, spec.clone()));
spec.clone(),
));
self.state_stack.push(TokenOrRedirect::Number( self.state_stack.push(TokenOrRedirect::Number(
Number::from(r.numer()), Number::from(r.numer()),
@@ -1068,17 +1066,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} else { } else {
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
self.state_stack.push(TokenOrRedirect::Number( self.state_stack
Number::from(r.denom()), .push(TokenOrRedirect::Number(Number::from(r.denom()), None));
None,
));
self.state_stack.push(TokenOrRedirect::Comma); self.state_stack.push(TokenOrRedirect::Comma);
self.state_stack.push(TokenOrRedirect::Number( self.state_stack
Number::from(r.numer()), .push(TokenOrRedirect::Number(Number::from(r.numer()), None));
None,
));
self.state_stack.push(TokenOrRedirect::Open); self.state_stack.push(TokenOrRedirect::Open);
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct)); self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
@@ -1092,8 +1086,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
} }
fn print_char(&mut self, is_quoted: bool, c: char) fn print_char(&mut self, is_quoted: bool, c: char) {
{
if non_quoted_token(once(c)) { if non_quoted_token(once(c)) {
let c = char_to_string(false, c); let c = char_to_string(false, c);
@@ -1120,46 +1113,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
fn print_proper_string(&mut self, buf: String, max_depth: usize) { fn print_proper_string(&mut self, buf: String, max_depth: usize) {
self.push_char('"'); self.push_char('"');
let buf = let buf = if max_depth == 0 {
if max_depth == 0 { String::from_iter(buf.chars().map(|c| char_to_string(self.quoted, c)))
String::from_iter(buf.chars().map(|c| { } else {
char_to_string(self.quoted, c) let mut char_count = 0;
})) let mut buf = String::from_iter(buf.chars().take(max_depth).map(|c| {
} else { char_count += 1;
let mut char_count = 0; char_to_string(self.quoted, c)
let mut buf = }));
String::from_iter(buf.chars().take(max_depth).map(|c| {
char_count += 1;
char_to_string(self.quoted, c)
}));
if char_count == max_depth { if char_count == max_depth {
buf += " ..."; buf += " ...";
} }
buf buf
}; };
self.append_str(&buf); self.append_str(&buf);
self.push_char('"'); self.push_char('"');
} }
fn print_list_like( fn print_list_like(&mut self, iter: &mut HCPreOrderIterator, addr: Addr, mut max_depth: usize) {
&mut self,
iter: &mut HCPreOrderIterator,
addr: Addr,
mut max_depth: usize,
) {
if self.check_max_depth(&mut max_depth) { if self.check_max_depth(&mut max_depth) {
iter.stack().pop(); iter.stack().pop();
iter.stack().pop(); iter.stack().pop();
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
return; return;
} }
let mut heap_pstr_iter = let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(addr);
self.machine_st.heap_pstr_iter(addr);
let buf = heap_pstr_iter.to_string(); let buf = heap_pstr_iter.to_string();
@@ -1184,12 +1168,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let buf_len = buf.len(); let buf_len = buf.len();
let buf_iter: Box<dyn Iterator<Item=char>> = let buf_iter: Box<dyn Iterator<Item = char>> = if self.max_depth == 0 {
if self.max_depth == 0 { Box::new(buf.chars())
Box::new(buf.chars()) } else {
} else { Box::new(buf.chars().take(max_depth))
Box::new(buf.chars().take(max_depth)) };
};
let mut byte_len = 0; let mut byte_len = 0;
@@ -1207,14 +1190,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
byte_len += c.len_utf8(); byte_len += c.len_utf8();
} }
for _ in 0 .. char_count { for _ in 0..char_count {
self.state_stack.push(TokenOrRedirect::Close); self.state_stack.push(TokenOrRedirect::Close);
} }
if self.max_depth > 0 && buf_len > byte_len { if self.max_depth > 0 && buf_len > byte_len {
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
} else { } else {
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
iter.stack().push(end_addr); iter.stack().push(end_addr);
} }
} else { } else {
@@ -1232,15 +1217,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
byte_len += c.len_utf8(); byte_len += c.len_utf8();
} }
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new( self.state_stack
Cell::new((switch, 0)) .push(TokenOrRedirect::CloseList(Rc::new(Cell::new((switch, 0)))));
)));
if self.max_depth > 0 && buf_len > byte_len { if self.max_depth > 0 && buf_len > byte_len {
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); self.state_stack
} else { .push(TokenOrRedirect::Atom(clause_name!("...")));
self.outputter.truncate(self.outputter.len() - ','.len_utf8()); } else {
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.outputter
.truncate(self.outputter.len() - ','.len_utf8());
self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
iter.stack().push(end_addr); iter.stack().push(end_addr);
} }
@@ -1268,8 +1255,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let cell = Rc::new(Cell::new((true, 0))); let cell = Rc::new(Cell::new((true, 0)));
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone())); self.state_stack
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("..."))); .push(TokenOrRedirect::CloseList(cell.clone()));
self.state_stack
.push(TokenOrRedirect::Atom(clause_name!("...")));
self.state_stack.push(TokenOrRedirect::OpenList(cell)); self.state_stack.push(TokenOrRedirect::OpenList(cell));
return; return;
@@ -1277,11 +1266,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
let cell = Rc::new(Cell::new((true, max_depth))); let cell = Rc::new(Cell::new((true, max_depth)));
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone())); self.state_stack
.push(TokenOrRedirect::CloseList(cell.clone()));
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth)); self.state_stack
.push(TokenOrRedirect::FunctorRedirect(max_depth));
self.state_stack.push(TokenOrRedirect::OpenList(cell)); self.state_stack.push(TokenOrRedirect::OpenList(cell));
} }
@@ -1298,23 +1290,24 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
max_depth: usize, max_depth: usize,
) { ) {
let add_brackets = if !self.ignore_ops { let add_brackets = if !self.ignore_ops {
negated_operand || if let Some(ref op) = op { negated_operand
if self.numbervars && arity == 1 && name.as_str() == "$VAR" { || if let Some(ref op) = op {
!iter.immediate_leaf_has_property(|addr, heap| { if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
match heap.index_addr(&addr).as_ref() { !iter.immediate_leaf_has_property(|addr, heap| {
&HeapCellValue::Integer(ref n) => &**n >= &0, match heap.index_addr(&addr).as_ref() {
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0, &HeapCellValue::Integer(ref n) => &**n >= &0,
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64), &HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
&HeapCellValue::Rational(ref r) => &**r >= &0, &HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
_ => false &HeapCellValue::Rational(ref r) => &**r >= &0,
} _ => false,
}) && needs_bracketing(&spec, op) }
}) && needs_bracketing(&spec, op)
} else {
needs_bracketing(&spec, op)
}
} else { } else {
needs_bracketing(&spec, op) is_functor_redirect && spec.prec() >= 1000
} }
} else {
is_functor_redirect && spec.prec() >= 1000
}
} else { } else {
false false
}; };
@@ -1344,15 +1337,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
tcp_listener: &TcpListener, tcp_listener: &TcpListener,
max_depth: usize, max_depth: usize,
) { ) {
let (ip, port) = let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
if let Some(addr) = tcp_listener.local_addr().ok() { (addr.ip(), Number::from(addr.port() as isize))
(addr.ip(), Number::from(addr.port() as isize)) } else {
} else { let disconnected_atom = clause_name!("$disconnected_tcp_listener");
let disconnected_atom = clause_name!("$disconnected_tcp_listener"); self.state_stack
self.state_stack.push(TokenOrRedirect::Atom(disconnected_atom)); .push(TokenOrRedirect::Atom(disconnected_atom));
return; return;
}; };
if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) { if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) {
let atom = self.state_stack.pop().unwrap(); let atom = self.state_stack.pop().unwrap();
@@ -1369,22 +1362,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
} }
fn print_stream( fn print_stream(&mut self, iter: &mut HCPreOrderIterator, stream: &Stream, max_depth: usize) {
&mut self,
iter: &mut HCPreOrderIterator,
stream: &Stream,
max_depth: usize,
) {
if let Some(alias) = &stream.options.alias { if let Some(alias) = &stream.options.alias {
self.print_atom(alias); self.print_atom(alias);
} else { } else {
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) { if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
let atom = let atom = if stream.is_stdout() || stream.is_stdin() {
if stream.is_stdout() || stream.is_stdin() { TokenOrRedirect::Atom(clause_name!("user"))
TokenOrRedirect::Atom(clause_name!("user")) } else {
} else { TokenOrRedirect::RawPtr(stream.as_ptr())
TokenOrRedirect::RawPtr(stream.as_ptr()) };
};
let stream_root = self.state_stack.pop().unwrap(); let stream_root = self.state_stack.pop().unwrap();
@@ -1414,7 +1401,8 @@ 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_from_existing(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(

View File

@@ -1,11 +1,12 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*; use prolog_parser::clause_name;
use prolog_parser::tabled_rc::*;
use crate::forms::*; use crate::forms::*;
use crate::instructions::*; use crate::instructions::*;
use crate::indexmap::IndexMap;
use crate::rug::Integer; use crate::rug::Integer;
use indexmap::IndexMap;
use slice_deque::{sdeq, SliceDeque}; use slice_deque::{sdeq, SliceDeque};
@@ -43,14 +44,10 @@ impl OptArgIndexKey {
#[inline] #[inline]
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool { fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
match (self, key_type) { match (self, key_type) {
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant) | (OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant)
(OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure) | | (OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure)
(OptArgIndexKey::List(..), OptArgIndexKeyType::List) => { | (OptArgIndexKey::List(..), OptArgIndexKeyType::List) => true,
true _ => false,
}
_ => {
false
}
} }
} }
} }
@@ -93,16 +90,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
indexing_code: &'a mut Vec<IndexingLine>, indexing_code: &'a mut Vec<IndexingLine>,
append_or_prepend: AppendOrPrepend, append_or_prepend: AppendOrPrepend,
) -> Self { ) -> Self {
Self { skeleton, indexing_code, offset: 0, append_or_prepend } Self {
skeleton,
indexing_code,
offset: 0,
append_or_prepend,
}
} }
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) { fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
let constant_key = let constant_key = search_skeleton_for_first_key_type(
search_skeleton_for_first_key_type( self.skeleton,
self.skeleton, OptArgIndexKeyType::Constant,
OptArgIndexKeyType::Constant, self.append_or_prepend,
self.append_or_prepend, );
);
let mut constants = IndexMap::new(); let mut constants = IndexMap::new();
@@ -117,7 +118,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
if let IndexingCodePtr::Internal(_) = constant_ptr { if let IndexingCodePtr::Internal(_) = constant_ptr {
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnConstant(constants) IndexingInstruction::SwitchOnConstant(constants),
)); ));
let last_index = self.indexing_code.len() - 1; let last_index = self.indexing_code.len() - 1;
@@ -126,34 +127,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
self.offset = self.indexing_code.len(); self.offset = self.indexing_code.len();
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnConstant(constants) IndexingInstruction::SwitchOnConstant(constants),
)); ));
} }
} }
fn add_indexed_choice_for_constant(&mut self, external: usize, constant: Constant, index: usize) fn add_indexed_choice_for_constant(
{ &mut self,
let third_level_index = external: usize,
if self.append_or_prepend.is_append() { constant: Constant,
sdeq![ index: usize,
IndexedChoiceInstruction::Try(external), ) {
IndexedChoiceInstruction::Trust(index) let third_level_index = if self.append_or_prepend.is_append() {
] sdeq![
} else { IndexedChoiceInstruction::Try(external),
sdeq![ IndexedChoiceInstruction::Trust(index)
IndexedChoiceInstruction::Try(index), ]
IndexedChoiceInstruction::Trust(external) } else {
] sdeq![
}; IndexedChoiceInstruction::Try(index),
IndexedChoiceInstruction::Trust(external)
]
};
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index)); self.indexing_code
.push(IndexingLine::IndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
IndexingInstruction::SwitchOnConstant(ref mut constants) constants.insert(
) => { constant,
constants.insert(constant, IndexingCodePtr::Internal(indexing_code_len - self.offset)); IndexingCodePtr::Internal(indexing_code_len - self.offset),
);
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -164,10 +170,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
fn extend_indexed_choice(&mut self, index: usize) { fn extend_indexed_choice(&mut self, index: usize) {
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
if self.append_or_prepend.is_append() => { if self.append_or_prepend.is_append() =>
uncap_choice_seq_with_trust(indexed_choice_instrs); {
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index)); uncap_choice_seq_with_trust(indexed_choice_instrs);
} indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
}
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => { IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => {
uncap_choice_seq_with_try(indexed_choice_instrs); uncap_choice_seq_with_try(indexed_choice_instrs);
indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index)); indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index));
@@ -188,9 +195,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
match *c { match *c {
IndexingCodePtr::Fail => { IndexingCodePtr::Fail => {
*c = IndexingCodePtr::External(index); *c = IndexingCodePtr::External(index);
@@ -203,7 +208,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
*c = IndexingCodePtr::Internal(indexing_code_len); *c = IndexingCodePtr::Internal(indexing_code_len);
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnConstant(constants) IndexingInstruction::SwitchOnConstant(constants),
)); ));
self.offset = indexing_code_len; self.offset = indexing_code_len;
@@ -213,12 +218,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
} }
} }
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
IndexingInstruction::SwitchOnConstant(constants)
) => {
match constants.get(&overlapping_constant).cloned() { match constants.get(&overlapping_constant).cloned() {
None | Some(IndexingCodePtr::Fail) => { None | Some(IndexingCodePtr::Fail) => {
constants.insert(overlapping_constant, IndexingCodePtr::External(index)); constants
.insert(overlapping_constant, IndexingCodePtr::External(index));
} }
Some(IndexingCodePtr::External(o)) => { Some(IndexingCodePtr::External(o)) => {
self.add_indexed_choice_for_constant(o, overlapping_constant, index); self.add_indexed_choice_for_constant(o, overlapping_constant, index);
@@ -232,9 +236,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
break; break;
} }
IndexingLine::IndexedChoice(_) => { IndexingLine::IndexedChoice(_) => {
self.internalize_constant( self.internalize_constant(IndexingCodePtr::Internal(
IndexingCodePtr::Internal(indexing_code_len - self.offset), indexing_code_len - self.offset,
); ));
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -248,9 +252,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
match *c { match *c {
IndexingCodePtr::Fail => { IndexingCodePtr::Fail => {
*c = IndexingCodePtr::External(index); *c = IndexingCodePtr::External(index);
@@ -265,9 +267,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
} }
} }
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
IndexingInstruction::SwitchOnConstant(constants)
) => {
match constants.get(&constant).cloned() { match constants.get(&constant).cloned() {
None | Some(IndexingCodePtr::Fail) => { None | Some(IndexingCodePtr::Fail) => {
constants.insert(constant, IndexingCodePtr::External(index)); constants.insert(constant, IndexingCodePtr::External(index));
@@ -284,9 +284,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
break; break;
} }
IndexingLine::IndexedChoice(_) => { IndexingLine::IndexedChoice(_) => {
self.internalize_constant( self.internalize_constant(IndexingCodePtr::Internal(
IndexingCodePtr::Internal(indexing_code_len - self.offset), indexing_code_len - self.offset,
); ));
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -295,13 +295,12 @@ impl<'a> IndexingCodeMergingPtr<'a> {
} }
} }
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) { fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
let structure_key = let structure_key = search_skeleton_for_first_key_type(
search_skeleton_for_first_key_type( self.skeleton,
self.skeleton, OptArgIndexKeyType::Structure,
OptArgIndexKeyType::Structure, self.append_or_prepend,
self.append_or_prepend, );
);
let mut structures = IndexMap::new(); let mut structures = IndexMap::new();
@@ -316,7 +315,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
if let IndexingCodePtr::Internal(_) = structure_ptr { if let IndexingCodePtr::Internal(_) = structure_ptr {
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnStructure(structures) IndexingInstruction::SwitchOnStructure(structures),
)); ));
let last_index = self.indexing_code.len() - 1; let last_index = self.indexing_code.len() - 1;
@@ -325,34 +324,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
self.offset = self.indexing_code.len(); self.offset = self.indexing_code.len();
self.indexing_code.push(IndexingLine::Indexing( self.indexing_code.push(IndexingLine::Indexing(
IndexingInstruction::SwitchOnStructure(structures) IndexingInstruction::SwitchOnStructure(structures),
)); ));
} }
} }
fn add_indexed_choice_for_structure(&mut self, external: usize, key: PredicateKey, index: usize) fn add_indexed_choice_for_structure(
{ &mut self,
let third_level_index = external: usize,
if self.append_or_prepend.is_append() { key: PredicateKey,
sdeq![ index: usize,
IndexedChoiceInstruction::Try(external), ) {
IndexedChoiceInstruction::Trust(index) let third_level_index = if self.append_or_prepend.is_append() {
] sdeq![
} else { IndexedChoiceInstruction::Try(external),
sdeq![ IndexedChoiceInstruction::Trust(index)
IndexedChoiceInstruction::Try(index), ]
IndexedChoiceInstruction::Trust(external) } else {
] sdeq![
}; IndexedChoiceInstruction::Try(index),
IndexedChoiceInstruction::Trust(external)
]
};
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index)); self.indexing_code
.push(IndexingLine::IndexedChoice(third_level_index));
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
IndexingInstruction::SwitchOnStructure(ref mut structures) structures.insert(
) => { key,
structures.insert(key, IndexingCodePtr::Internal(indexing_code_len - self.offset)); IndexingCodePtr::Internal(indexing_code_len - self.offset),
);
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -365,26 +369,26 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s) _,
) => { _,
match *s { _,
IndexingCodePtr::Fail => { _,
*s = IndexingCodePtr::External(index); ref mut s,
break; )) => match *s {
} IndexingCodePtr::Fail => {
IndexingCodePtr::External(o) => { *s = IndexingCodePtr::External(index);
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset); break;
self.internalize_structure(IndexingCodePtr::External(o));
}
IndexingCodePtr::Internal(o) => {
self.offset += o;
}
} }
} IndexingCodePtr::External(o) => {
IndexingLine::Indexing( *s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
IndexingInstruction::SwitchOnStructure(structures) self.internalize_structure(IndexingCodePtr::External(o));
) => { }
IndexingCodePtr::Internal(o) => {
self.offset += o;
}
},
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(structures)) => {
match structures.get(&key).cloned() { match structures.get(&key).cloned() {
None | Some(IndexingCodePtr::Fail) => { None | Some(IndexingCodePtr::Fail) => {
structures.insert(key, IndexingCodePtr::External(index)); structures.insert(key, IndexingCodePtr::External(index));
@@ -404,9 +408,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
// replace this value, at self.offset, with // replace this value, at self.offset, with
// SwitchOnStructures, and swap this IndexedChoice // SwitchOnStructures, and swap this IndexedChoice
// vector to the end of self.indexing_code. // vector to the end of self.indexing_code.
self.internalize_structure( self.internalize_structure(IndexingCodePtr::Internal(
IndexingCodePtr::Internal(indexing_code_len - self.offset), indexing_code_len - self.offset,
); ));
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -419,9 +423,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
let indexing_code_len = self.indexing_code.len(); let indexing_code_len = self.indexing_code.len();
match &mut self.indexing_code[self.offset] { match &mut self.indexing_code[self.offset] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
) => {
match *l { match *l {
IndexingCodePtr::Fail => { IndexingCodePtr::Fail => {
*l = IndexingCodePtr::External(index); *l = IndexingCodePtr::External(index);
@@ -429,22 +431,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
IndexingCodePtr::External(o) => { IndexingCodePtr::External(o) => {
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset); *l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
let third_level_index = let third_level_index = if self.append_or_prepend.is_append() {
if self.append_or_prepend.is_append() { sdeq![
sdeq![ IndexedChoiceInstruction::Try(o),
IndexedChoiceInstruction::Try(o), IndexedChoiceInstruction::Trust(index)
IndexedChoiceInstruction::Trust(index) ]
] } else {
} else { sdeq![
sdeq![ IndexedChoiceInstruction::Try(index),
IndexedChoiceInstruction::Try(index), IndexedChoiceInstruction::Trust(o)
IndexedChoiceInstruction::Trust(o) ]
] };
};
self.indexing_code.push( self.indexing_code
IndexingLine::IndexedChoice(third_level_index), .push(IndexingLine::IndexedChoice(third_level_index));
);
} }
IndexingCodePtr::Internal(o) => { IndexingCodePtr::Internal(o) => {
self.offset += o; self.offset += o;
@@ -462,24 +462,16 @@ impl<'a> IndexingCodeMergingPtr<'a> {
pub fn merge_clause_index( pub fn merge_clause_index(
target_indexing_code: &mut Vec<IndexingLine>, target_indexing_code: &mut Vec<IndexingLine>,
skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton. skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton.
new_clause_loc: usize, // the absolute location of the new clause in the code vector. new_clause_loc: usize, // the absolute location of the new clause in the code vector.
append_or_prepend: AppendOrPrepend, append_or_prepend: AppendOrPrepend,
) { ) {
let opt_arg_index_key = let opt_arg_index_key = match append_or_prepend {
match append_or_prepend { AppendOrPrepend::Append => skeleton.last_mut().unwrap().opt_arg_index_key.take(),
AppendOrPrepend::Append => { AppendOrPrepend::Prepend => skeleton.first_mut().unwrap().opt_arg_index_key.take(),
skeleton.last_mut().unwrap().opt_arg_index_key.take() };
}
AppendOrPrepend::Prepend => {
skeleton.first_mut().unwrap().opt_arg_index_key.take()
}
};
let mut merging_ptr = IndexingCodeMergingPtr::new( let mut merging_ptr =
skeleton, IndexingCodeMergingPtr::new(skeleton, target_indexing_code, append_or_prepend);
target_indexing_code,
append_or_prepend,
);
match &opt_arg_index_key { match &opt_arg_index_key {
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => { OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
@@ -488,7 +480,9 @@ pub fn merge_clause_index(
for overlapping_constant in overlapping_constants { for overlapping_constant in overlapping_constants {
merging_ptr.index_overlapping_constant( merging_ptr.index_overlapping_constant(
constant, overlapping_constant.clone(), offset, constant,
overlapping_constant.clone(),
offset,
); );
} }
} }
@@ -514,10 +508,7 @@ pub fn merge_clause_index(
} }
#[inline] #[inline]
fn remove_instruction_with_offset( fn remove_instruction_with_offset(code: &mut SliceDeque<IndexedChoiceInstruction>, offset: usize) {
code: &mut SliceDeque<IndexedChoiceInstruction>,
offset: usize,
) {
for (index, line) in code.iter().enumerate() { for (index, line) in code.iter().enumerate() {
if offset == line.offset() { if offset == line.offset() {
code.remove(index); code.remove(index);
@@ -537,9 +528,7 @@ pub fn remove_constant_indices(
let iter = once(constant).chain(overlapping_constants.iter()); let iter = once(constant).chain(overlapping_constants.iter());
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
match *c { match *c {
IndexingCodePtr::External(_) => { IndexingCodePtr::External(_) => {
*c = IndexingCodePtr::Fail; *c = IndexingCodePtr::Fail;
@@ -560,12 +549,13 @@ pub fn remove_constant_indices(
let mut constants_index = 0; let mut constants_index = 0;
for constant in iter { // (constant, index_loc) in iter.zip(index_locs.iter()) { for constant in iter {
// (constant, index_loc) in iter.zip(index_locs.iter()) {
loop { loop {
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
IndexingInstruction::SwitchOnConstant(ref mut constants) ref mut constants,
) => { )) => {
constants_index = index; constants_index = index;
match constants.get(constant).cloned() { match constants.get(constant).cloned() {
@@ -586,18 +576,21 @@ pub fn remove_constant_indices(
if indexed_choice_instrs.len() == 1 { if indexed_choice_instrs.len() == 1 {
let ext = IndexingCodePtr::External( let ext = IndexingCodePtr::External(
indexed_choice_instrs.pop_back().unwrap().offset() indexed_choice_instrs.pop_back().unwrap().offset(),
); );
match &mut indexing_code[constants_index] { match &mut indexing_code[constants_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..) _,
) => { _,
ref mut c,
..,
)) => {
*c = ext; *c = ext;
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
IndexingInstruction::SwitchOnConstant(ref mut constants) ref mut constants,
) => { )) => {
constants.insert(constant.clone(), ext); constants.insert(constant.clone(), ext);
} }
_ => { _ => {
@@ -616,13 +609,11 @@ pub fn remove_constant_indices(
} }
match &indexing_code[constants_index] { match &indexing_code[constants_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref constants))
IndexingInstruction::SwitchOnConstant(ref constants) if constants.is_empty() =>
) if constants.is_empty() => { {
match &mut indexing_code[0] { match &mut indexing_code[0] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
) => {
*c = IndexingCodePtr::Fail; *c = IndexingCodePtr::Fail;
} }
_ => { _ => {
@@ -630,8 +621,7 @@ pub fn remove_constant_indices(
} }
} }
} }
_ => { _ => {}
}
} }
} }
@@ -644,9 +634,7 @@ pub fn remove_structure_index(
let mut index = 0; let mut index = 0;
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)) => {
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
) => {
match *s { match *s {
IndexingCodePtr::External(_) => { IndexingCodePtr::External(_) => {
*s = IndexingCodePtr::Fail; *s = IndexingCodePtr::Fail;
@@ -669,9 +657,7 @@ pub fn remove_structure_index(
loop { loop {
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
IndexingInstruction::SwitchOnStructure(ref mut structures)
) => {
structures_index = index; structures_index = index;
match structures.get(&(name.clone(), arity)).cloned() { match structures.get(&(name.clone(), arity)).cloned() {
@@ -692,18 +678,22 @@ pub fn remove_structure_index(
if indexed_choice_instrs.len() == 1 { if indexed_choice_instrs.len() == 1 {
let ext = IndexingCodePtr::External( let ext = IndexingCodePtr::External(
indexed_choice_instrs.pop_back().unwrap().offset() indexed_choice_instrs.pop_back().unwrap().offset(),
); );
match &mut indexing_code[structures_index] { match &mut indexing_code[structures_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s) _,
) => { _,
_,
_,
ref mut s,
)) => {
*s = ext; *s = ext;
} }
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
IndexingInstruction::SwitchOnStructure(ref mut structures) ref mut structures,
) => { )) => {
structures.insert((name.clone(), arity), ext); structures.insert((name.clone(), arity), ext);
} }
_ => { _ => {
@@ -721,13 +711,17 @@ pub fn remove_structure_index(
} }
match &indexing_code[structures_index] { match &indexing_code[structures_index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref structures))
IndexingInstruction::SwitchOnStructure(ref structures) if structures.is_empty() =>
) if structures.is_empty() => { {
match &mut indexing_code[0] { match &mut indexing_code[0] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s) _,
) => { _,
_,
_,
ref mut s,
)) => {
*s = IndexingCodePtr::Fail; *s = IndexingCodePtr::Fail;
} }
_ => { _ => {
@@ -735,21 +729,15 @@ pub fn remove_structure_index(
} }
} }
} }
_ => { _ => {}
}
} }
} }
pub fn remove_list_index( pub fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
indexing_code: &mut Vec<IndexingLine>,
offset: usize,
) {
let mut index = 0; let mut index = 0;
match &mut indexing_code[index] { match &mut indexing_code[index] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
) => {
match *l { match *l {
IndexingCodePtr::External(_) => { IndexingCodePtr::External(_) => {
*l = IndexingCodePtr::Fail; *l = IndexingCodePtr::Fail;
@@ -773,14 +761,17 @@ pub fn remove_list_index(
remove_instruction_with_offset(indexed_choice_instrs, offset); remove_instruction_with_offset(indexed_choice_instrs, offset);
if indexed_choice_instrs.len() == 1 { if indexed_choice_instrs.len() == 1 {
let ext = IndexingCodePtr::External( let ext =
indexed_choice_instrs.pop_back().unwrap().offset() IndexingCodePtr::External(indexed_choice_instrs.pop_back().unwrap().offset());
);
match &mut indexing_code[0] { match &mut indexing_code[0] {
IndexingLine::Indexing( IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _) _,
) => { _,
_,
ref mut l,
_,
)) => {
*l = ext; *l = ext;
} }
_ => { _ => {
@@ -836,8 +827,7 @@ pub fn remove_index(
fn second_level_index<IndexKey: Eq + Hash>( fn second_level_index<IndexKey: Eq + Hash>(
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>, indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut SliceDeque<IndexingLine>,
) -> IndexMap<IndexKey, IndexingCodePtr> ) -> IndexMap<IndexKey, IndexingCodePtr> {
{
let mut index_locs = IndexMap::new(); let mut index_locs = IndexMap::new();
for (key, mut code) in indices.into_iter() { for (key, mut code) in indices.into_iter() {
@@ -868,10 +858,11 @@ fn switch_on<IndexKey: Eq + Hash>(
IndexingCodePtr::Internal(1) IndexingCodePtr::Internal(1)
} else { } else {
index.into_iter() index
.next() .into_iter()
.map(|(_, v)| v) .next()
.unwrap_or(IndexingCodePtr::Fail) .map(|(_, v)| v)
.unwrap_or(IndexingCodePtr::Fail)
} }
} }
@@ -884,9 +875,10 @@ fn switch_on_list(
prelude.push_back(IndexingLine::from(lists)); prelude.push_back(IndexingLine::from(lists));
IndexingCodePtr::Internal(1) IndexingCodePtr::Internal(1)
} else { } else {
lists.first() lists
.map(|i| IndexingCodePtr::External(i.offset())) .first()
.unwrap_or(IndexingCodePtr::Fail) .map(|i| IndexingCodePtr::External(i.offset()))
.unwrap_or(IndexingCodePtr::Fail)
} }
} }
@@ -978,8 +970,7 @@ pub fn constant_key_alternatives(constant: &Constant, atom_tbl: TabledData<Atom>
constants.push(Constant::Fixnum(n)); constants.push(Constant::Fixnum(n));
} }
} }
_ => { _ => {}
}
} }
constants constants
@@ -1001,7 +992,7 @@ impl CodeOffsets {
constants: IndexMap::new(), constants: IndexMap::new(),
lists: sdeq![], lists: sdeq![],
structures: IndexMap::new(), structures: IndexMap::new(),
optimal_index optimal_index,
} }
} }
@@ -1011,20 +1002,15 @@ impl CodeOffsets {
} }
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> { fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
let overlapping_constants = let overlapping_constants = constant_key_alternatives(constant, self.atom_tbl.clone());
constant_key_alternatives(constant, self.atom_tbl.clone());
let code = self.constants let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
.entry(constant.clone())
.or_insert(sdeq![]);
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
code.push_back(compute_index(is_initial_index, index)); code.push_back(compute_index(is_initial_index, index));
for constant in &overlapping_constants { for constant in &overlapping_constants {
let code = self.constants let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
.entry(constant.clone())
.or_insert(sdeq![]);
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
let index = compute_index(is_initial_index, index); let index = compute_index(is_initial_index, index);
@@ -1062,25 +1048,21 @@ impl CodeOffsets {
self.index_structure(name, terms.len(), index); self.index_structure(name, terms.len(), index);
} }
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => { &Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
clause_index_info.opt_arg_index_key = clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0);
OptArgIndexKey::List(self.optimal_index, 0);
self.index_list(index); self.index_list(index);
} }
&Term::Constant(_, ref constant) => { &Term::Constant(_, ref constant) => {
let overlapping_constants = let overlapping_constants = self.index_constant(constant, index);
self.index_constant(constant, index);
clause_index_info.opt_arg_index_key = clause_index_info.opt_arg_index_key = OptArgIndexKey::Constant(
OptArgIndexKey::Constant( self.optimal_index,
self.optimal_index, 0,
0, constant.clone(),
constant.clone(), overlapping_constants,
overlapping_constants, );
);
}
_ => {
} }
_ => {}
} }
} }
@@ -1117,8 +1099,7 @@ impl CodeOffsets {
IndexingCodePtr::Internal(ref mut i) => { IndexingCodePtr::Internal(ref mut i) => {
*i += con_loc.is_internal() as usize; *i += con_loc.is_internal() as usize;
} }
_ => { _ => {}
}
}; };
match &mut lst_loc { match &mut lst_loc {
@@ -1126,15 +1107,18 @@ impl CodeOffsets {
*i += con_loc.is_internal() as usize; *i += con_loc.is_internal() as usize;
*i += str_loc.is_internal() as usize; *i += str_loc.is_internal() as usize;
} }
_ => { _ => {}
}
}; };
let var_offset = 1 + skip_stub_try_me_else as usize; let var_offset = 1 + skip_stub_try_me_else as usize;
prelude.push_front(IndexingLine::from( prelude.push_front(IndexingLine::from(IndexingInstruction::SwitchOnTerm(
IndexingInstruction::SwitchOnTerm(self.optimal_index, var_offset, con_loc, lst_loc, str_loc) self.optimal_index,
)); var_offset,
con_loc,
lst_loc,
str_loc,
)));
prelude.into_iter().collect() prelude.into_iter().collect()
} }

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::clause_name;
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -8,7 +9,7 @@ use crate::machine::machine_errors::MachineStub;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::rug::Integer; use crate::rug::Integer;
use crate::indexmap::IndexMap; use indexmap::IndexMap;
use slice_deque::SliceDeque; use slice_deque::SliceDeque;
@@ -34,9 +35,7 @@ impl Level {
impl ArithmeticTerm { impl ArithmeticTerm {
fn into_functor(&self) -> MachineStub { fn into_functor(&self) -> MachineStub {
match self { match self {
&ArithmeticTerm::Reg(r) => { &ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
reg_type_into_functor(r)
}
&ArithmeticTerm::Interm(i) => { &ArithmeticTerm::Interm(i) => {
functor!("intermediate", [integer(i)]) functor!("intermediate", [integer(i)])
} }
@@ -185,16 +184,11 @@ impl Line {
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) { pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
match self { match self {
&Line::Arithmetic(ref arith_instr) => &Line::Arithmetic(ref arith_instr) => functors.push(arith_instr.to_functor(h)),
functors.push(arith_instr.to_functor(h)), &Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor()),
&Line::Choice(ref choice_instr) => &Line::Control(ref control_instr) => functors.push(control_instr.to_functor()),
functors.push(choice_instr.to_functor()), &Line::Cut(ref cut_instr) => functors.push(cut_instr.to_functor(h)),
&Line::Control(ref control_instr) => &Line::Fact(ref fact_instr) => functors.push(fact_instr.to_functor(h)),
functors.push(control_instr.to_functor()),
&Line::Cut(ref cut_instr) =>
functors.push(cut_instr.to_functor(h)),
&Line::Fact(ref fact_instr) =>
functors.push(fact_instr.to_functor(h)),
&Line::IndexingCode(ref indexing_instrs) => { &Line::IndexingCode(ref indexing_instrs) => {
for indexing_instr in indexing_instrs { for indexing_instr in indexing_instrs {
match indexing_instr { match indexing_instr {
@@ -213,10 +207,10 @@ impl Line {
} }
} }
} }
&Line::IndexedChoice(ref indexed_choice_instr) => &Line::IndexedChoice(ref indexed_choice_instr) => {
functors.push(indexed_choice_instr.to_functor()), functors.push(indexed_choice_instr.to_functor())
&Line::Query(ref query_instr) => }
functors.push(query_instr.to_functor(h)), &Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
} }
} }
} }
@@ -224,24 +218,16 @@ impl Line {
#[inline] #[inline]
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> { pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
match line { match line {
Line::IndexingCode(ref mut indexing_code) => { Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
Some(indexing_code) _ => None,
}
_ => {
None
}
} }
} }
#[inline] #[inline]
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> { pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
match line { match line {
Line::IndexingCode(ref indexing_code) => { Line::IndexingCode(ref indexing_code) => Some(indexing_code),
Some(indexing_code) _ => None,
}
_ => {
None
}
} }
} }
@@ -296,11 +282,7 @@ fn arith_instr_unary_functor(
) -> MachineStub { ) -> MachineStub {
let at_stub = at.into_functor(); let at_stub = at.into_functor();
functor!( functor!(name, [aux(h, 0), integer(t)], [at_stub])
name,
[aux(h, 0), integer(t)],
[at_stub]
)
} }
fn arith_instr_bin_functor( fn arith_instr_bin_functor(
@@ -383,39 +365,17 @@ impl ArithmeticInstruction {
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => { &ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
arith_instr_bin_functor(h, "gcd", at_1, at_2, t) arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
} }
&ArithmeticInstruction::Sign(ref at, t) => { &ArithmeticInstruction::Sign(ref at, t) => arith_instr_unary_functor(h, "sign", at, t),
arith_instr_unary_functor(h, "sign", at, t) &ArithmeticInstruction::Cos(ref at, t) => arith_instr_unary_functor(h, "cos", at, t),
} &ArithmeticInstruction::Sin(ref at, t) => arith_instr_unary_functor(h, "sin", at, t),
&ArithmeticInstruction::Cos(ref at, t) => { &ArithmeticInstruction::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t),
arith_instr_unary_functor(h, "cos", at, t) &ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t),
} &ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t),
&ArithmeticInstruction::Sin(ref at, t) => { &ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t),
arith_instr_unary_functor(h, "sin", at, t) &ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t),
} &ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t),
&ArithmeticInstruction::Tan(ref at, t) => { &ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t),
arith_instr_unary_functor(h, "tan", at, t) &ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t),
}
&ArithmeticInstruction::Log(ref at, t) => {
arith_instr_unary_functor(h, "log", at, t)
}
&ArithmeticInstruction::Exp(ref at, t) => {
arith_instr_unary_functor(h, "exp", at, t)
}
&ArithmeticInstruction::ACos(ref at, t) => {
arith_instr_unary_functor(h, "acos", at, t)
}
&ArithmeticInstruction::ASin(ref at, t) => {
arith_instr_unary_functor(h, "asin", at, t)
}
&ArithmeticInstruction::ATan(ref at, t) => {
arith_instr_unary_functor(h, "atan", at, t)
}
&ArithmeticInstruction::Sqrt(ref at, t) => {
arith_instr_unary_functor(h, "sqrt", at, t)
}
&ArithmeticInstruction::Abs(ref at, t) => {
arith_instr_unary_functor(h, "abs", at, t)
}
&ArithmeticInstruction::Float(ref at, t) => { &ArithmeticInstruction::Float(ref at, t) => {
arith_instr_unary_functor(h, "float", at, t) arith_instr_unary_functor(h, "float", at, t)
} }
@@ -431,12 +391,8 @@ impl ArithmeticInstruction {
&ArithmeticInstruction::Floor(ref at, t) => { &ArithmeticInstruction::Floor(ref at, t) => {
arith_instr_unary_functor(h, "floor", at, t) arith_instr_unary_functor(h, "floor", at, t)
} }
&ArithmeticInstruction::Neg(ref at, t) => { &ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t),
arith_instr_unary_functor(h, "-", at, t) &ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t),
}
&ArithmeticInstruction::Plus(ref at, t) => {
arith_instr_unary_functor(h, "+", at, t)
}
&ArithmeticInstruction::BitwiseComplement(ref at, t) => { &ArithmeticInstruction::BitwiseComplement(ref at, t) => {
arith_instr_unary_functor(h, "\\", at, t) arith_instr_unary_functor(h, "\\", at, t)
} }
@@ -451,21 +407,18 @@ pub enum ControlInstruction {
CallClause(ClauseType, usize, usize, bool, bool), CallClause(ClauseType, usize, usize, bool, bool),
Deallocate, Deallocate,
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call. JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
RevJmpBy(usize), // notice the lack of context change as in RevJmpBy(usize), // notice the lack of context change as in
// JmpBy. RevJmpBy is used only to patch extensible // JmpBy. RevJmpBy is used only to patch extensible
// predicates together. // predicates together.
Proceed, Proceed,
} }
impl ControlInstruction { impl ControlInstruction {
pub fn perm_vars(&self) -> Option<usize> { pub fn perm_vars(&self) -> Option<usize> {
match self { match self {
ControlInstruction::CallClause(_, _, num_cells, ..) => ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
Some(*num_cells), ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
ControlInstruction::JmpBy(_, _, num_cells, ..) => _ => None,
Some(*num_cells),
_ =>
None
} }
} }
@@ -500,7 +453,13 @@ impl ControlInstruction {
#[derive(Debug)] #[derive(Debug)]
pub enum IndexingInstruction { pub enum IndexingInstruction {
// The first index is the optimal argument being indexed. // The first index is the optimal argument being indexed.
SwitchOnTerm(usize, usize, IndexingCodePtr, IndexingCodePtr, IndexingCodePtr), SwitchOnTerm(
usize,
usize,
IndexingCodePtr,
IndexingCodePtr,
IndexingCodePtr,
),
SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>), SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>),
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>), SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
} }
@@ -511,11 +470,13 @@ impl IndexingInstruction {
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => { &IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
functor!( functor!(
"switch_on_term", "switch_on_term",
[integer(arg), [
integer(vars), integer(arg),
indexing_code_ptr(h, constants), integer(vars),
indexing_code_ptr(h, lists), indexing_code_ptr(h, constants),
indexing_code_ptr(h, structures)] indexing_code_ptr(h, lists),
indexing_code_ptr(h, structures)
]
) )
} }
&IndexingInstruction::SwitchOnConstant(ref constants) => { &IndexingInstruction::SwitchOnConstant(ref constants) => {
@@ -528,15 +489,14 @@ impl IndexingInstruction {
let key_value_pair = functor!( let key_value_pair = functor!(
":", ":",
SharedOpDesc::new(600, XFY), SharedOpDesc::new(600, XFY),
[constant(c), [constant(c), indexing_code_ptr(h + 3, *ptr)]
indexing_code_ptr(h + 3, *ptr)]
); );
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
key_value_list_stub.push(HeapCellValue::Addr( key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
Addr::HeapCell(h + 3 + key_value_pair.len()) h + 3 + key_value_pair.len(),
)); )));
h += key_value_pair.len() + 3; h += key_value_pair.len() + 3;
key_value_list_stub.extend(key_value_pair.into_iter()); key_value_list_stub.extend(key_value_pair.into_iter());
@@ -560,23 +520,21 @@ impl IndexingInstruction {
let predicate_indicator_stub = functor!( let predicate_indicator_stub = functor!(
"/", "/",
SharedOpDesc::new(400, YFX), SharedOpDesc::new(400, YFX),
[clause_name(name.clone()), [clause_name(name.clone()), integer(*arity)]
integer(*arity)]
); );
let key_value_pair = functor!( let key_value_pair = functor!(
":", ":",
SharedOpDesc::new(600, XFY), SharedOpDesc::new(600, XFY),
[aux(h + 3, 0), [aux(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
indexing_code_ptr(h + 3, *ptr)],
[predicate_indicator_stub] [predicate_indicator_stub]
); );
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3))); key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
key_value_list_stub.push(HeapCellValue::Addr( key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
Addr::HeapCell(h + 3 + key_value_pair.len()) h + 3 + key_value_pair.len(),
)); )));
h += key_value_pair.len() + 3; h += key_value_pair.len() + 3;
key_value_list_stub.extend(key_value_pair.into_iter()); key_value_list_stub.extend(key_value_pair.into_iter());
@@ -614,7 +572,7 @@ impl FactInstruction {
match self { match self {
&FactInstruction::GetConstant(lvl, ref c, r) => { &FactInstruction::GetConstant(lvl, ref c, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"get_constant", "get_constant",
@@ -624,17 +582,13 @@ impl FactInstruction {
} }
&FactInstruction::GetList(lvl, r) => { &FactInstruction::GetList(lvl, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
"get_list",
[aux(h, 0), aux(h, 1)],
[lvl_stub, rt_stub]
)
} }
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => { &FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"get_partial_string", "get_partial_string",
@@ -654,20 +608,12 @@ impl FactInstruction {
&FactInstruction::GetValue(r, arg) => { &FactInstruction::GetValue(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_value", [aux(h, 0), integer(arg)], [rt_stub])
"get_value",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&FactInstruction::GetVariable(r, arg) => { &FactInstruction::GetVariable(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
"get_variable",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&FactInstruction::UnifyConstant(ref c) => { &FactInstruction::UnifyConstant(ref c) => {
functor!("unify_constant", [constant(h, c)], []) functor!("unify_constant", [constant(h, c)], [])
@@ -675,29 +621,17 @@ impl FactInstruction {
&FactInstruction::UnifyLocalValue(r) => { &FactInstruction::UnifyLocalValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("unify_local_value", [aux(h, 0)], [rt_stub])
"unify_local_value",
[aux(h, 0)],
[rt_stub]
)
} }
&FactInstruction::UnifyVariable(r) => { &FactInstruction::UnifyVariable(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("unify_variable", [aux(h, 0)], [rt_stub])
"unify_variable",
[aux(h, 0)],
[rt_stub]
)
} }
&FactInstruction::UnifyValue(r) => { &FactInstruction::UnifyValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("unify_value", [aux(h, 0)], [rt_stub])
"unify_value",
[aux(h, 0)],
[rt_stub]
)
} }
&FactInstruction::UnifyVoid(vars) => { &FactInstruction::UnifyVoid(vars) => {
functor!("unify_void", [integer(vars)]) functor!("unify_void", [integer(vars)])
@@ -726,13 +660,12 @@ pub enum QueryInstruction {
impl QueryInstruction { impl QueryInstruction {
pub fn to_functor(&self, h: usize) -> MachineStub { pub fn to_functor(&self, h: usize) -> MachineStub {
match self { match self {
&QueryInstruction::PutUnsafeValue(norm, arg) => functor!( &QueryInstruction::PutUnsafeValue(norm, arg) => {
"put_unsafe_value", functor!("put_unsafe_value", [integer(norm), integer(arg)])
[integer(norm), integer(arg)] }
),
&QueryInstruction::PutConstant(lvl, ref c, r) => { &QueryInstruction::PutConstant(lvl, ref c, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"put_constant", "put_constant",
@@ -742,17 +675,13 @@ impl QueryInstruction {
} }
&QueryInstruction::PutList(lvl, r) => { &QueryInstruction::PutList(lvl, r) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("put_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
"put_list",
[aux(h, 0), aux(h, 1)],
[lvl_stub, rt_stub]
)
} }
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => { &QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
let lvl_stub = lvl.into_functor(); let lvl_stub = lvl.into_functor();
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!(
"put_partial_string", "put_partial_string",
@@ -772,29 +701,17 @@ impl QueryInstruction {
&QueryInstruction::PutValue(r, arg) => { &QueryInstruction::PutValue(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("put_value", [aux(h, 0), integer(arg)], [rt_stub])
"put_value",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&QueryInstruction::GetVariable(r, arg) => { &QueryInstruction::GetVariable(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
"get_variable",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&QueryInstruction::PutVariable(r, arg) => { &QueryInstruction::PutVariable(r, arg) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("put_variable", [aux(h, 0), integer(arg)], [rt_stub])
"put_variable",
[aux(h, 0), integer(arg)],
[rt_stub]
)
} }
&QueryInstruction::SetConstant(ref c) => { &QueryInstruction::SetConstant(ref c) => {
functor!("set_constant", [constant(h, c)], []) functor!("set_constant", [constant(h, c)], [])
@@ -802,29 +719,17 @@ impl QueryInstruction {
&QueryInstruction::SetLocalValue(r) => { &QueryInstruction::SetLocalValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("set_local_value", [aux(h, 0)], [rt_stub])
"set_local_value",
[aux(h, 0)],
[rt_stub]
)
} }
&QueryInstruction::SetVariable(r) => { &QueryInstruction::SetVariable(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("set_variable", [aux(h, 0)], [rt_stub])
"set_variable",
[aux(h, 0)],
[rt_stub]
)
} }
&QueryInstruction::SetValue(r) => { &QueryInstruction::SetValue(r) => {
let rt_stub = reg_type_into_functor(r); let rt_stub = reg_type_into_functor(r);
functor!( functor!("set_value", [aux(h, 0)], [rt_stub])
"set_value",
[aux(h, 0)],
[rt_stub]
)
} }
&QueryInstruction::SetVoid(vars) => { &QueryInstruction::SetVoid(vars) => {
functor!("set_void", [integer(vars)]) functor!("set_void", [integer(vars)])

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::rc_atom;
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -25,11 +26,11 @@ impl<'a> TermRef<'a> {
pub fn level(self) -> Level { pub fn level(self) -> Level {
match self { match self {
TermRef::AnonVar(lvl) TermRef::AnonVar(lvl)
| TermRef::Cons(lvl, ..) | TermRef::Cons(lvl, ..)
| TermRef::Constant(lvl, ..) | TermRef::Constant(lvl, ..)
| TermRef::Var(lvl, ..) | TermRef::Var(lvl, ..)
| TermRef::Clause(lvl, ..) => lvl, | TermRef::Clause(lvl, ..) => lvl,
| TermRef::PartialString(lvl, ..) => lvl, TermRef::PartialString(lvl, ..) => lvl,
} }
} }
} }
@@ -51,23 +52,16 @@ pub enum TermIterState<'a> {
Var(Level, &'a Cell<VarReg>, Rc<Var>), Var(Level, &'a Cell<VarReg>, Rc<Var>),
} }
fn is_partial_string<'a>( fn is_partial_string<'a>(head: &'a Term, mut tail: &'a Term) -> Option<(String, Option<&'a Term>)> {
head: &'a Term, let mut string = match head {
mut tail: &'a Term, &Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
) -> Option<(String, Option<&'a Term>)> atom.as_str().chars().next().unwrap().to_string()
{ }
let mut string = &Term::Constant(_, Constant::Char(c)) => c.to_string(),
match head { _ => {
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => { return None;
atom.as_str().chars().next().unwrap().to_string() }
} };
&Term::Constant(_, Constant::Char(c)) => {
c.to_string()
}
_ => {
return None;
}
};
while let Term::Cons(_, ref head, ref succ) = tail { while let Term::Cons(_, ref head, ref succ) = tail {
match head.as_ref() { match head.as_ref() {
@@ -105,9 +99,7 @@ fn is_partial_string<'a>(
impl<'a> TermIterState<'a> { impl<'a> TermIterState<'a> {
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> { pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
match term { match term {
&Term::AnonVar => { &Term::AnonVar => TermIterState::AnonVar(lvl),
TermIterState::AnonVar(lvl)
}
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => { &Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
let ct = if let Some(spec) = spec { let ct = if let Some(spec) = spec {
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default()) ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
@@ -120,12 +112,8 @@ impl<'a> TermIterState<'a> {
&Term::Cons(ref cell, ref head, ref tail) => { &Term::Cons(ref cell, ref head, ref tail) => {
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()) TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
} }
&Term::Constant(ref cell, ref constant) => { &Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
TermIterState::Constant(lvl, cell, constant) &Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
}
&Term::Var(ref cell, ref var) => {
TermIterState::Var(lvl, cell, var.clone())
}
} }
} }
} }
@@ -175,8 +163,7 @@ impl<'a> QueryIterator<'a> {
state_stack: vec![], state_stack: vec![],
} }
} }
&Term::Var(ref cell, ref var) => &Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
TermIterState::Var(Level::Root, cell, (*var).clone()),
}; };
QueryIterator { QueryIterator {
@@ -265,18 +252,15 @@ impl<'a> Iterator for QueryIterator<'a> {
} }
TermIterState::InitialCons(lvl, cell, head, tail) => { TermIterState::InitialCons(lvl, cell, head, tail) => {
if let Some((string, tail)) = is_partial_string(head, tail) { if let Some((string, tail)) = is_partial_string(head, tail) {
self.state_stack.push(TermIterState::PartialString( self.state_stack
lvl, .push(TermIterState::PartialString(lvl, cell, string, tail));
cell,
string,
tail,
));
if let Some(tail) = tail { if let Some(tail) = tail {
self.push_subterm(lvl.child_level(), tail); self.push_subterm(lvl.child_level(), tail);
} }
} else { } else {
self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail)); self.state_stack
.push(TermIterState::FinalCons(lvl, cell, head, tail));
self.push_subterm(lvl.child_level(), tail); self.push_subterm(lvl.child_level(), tail);
self.push_subterm(lvl.child_level(), head); self.push_subterm(lvl.child_level(), head);
@@ -309,7 +293,8 @@ pub struct FactIterator<'a> {
impl<'a> FactIterator<'a> { impl<'a> FactIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) { fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term)); self.state_queue
.push_back(TermIterState::subterm_to_state(lvl, term));
} }
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self { pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
@@ -393,8 +378,7 @@ impl<'a> Iterator for FactIterator<'a> {
TermIterState::Var(lvl, cell, var) => { TermIterState::Var(lvl, cell, var) => {
return Some(TermRef::Var(lvl, cell, var)); return Some(TermRef::Var(lvl, cell, var));
} }
_ => { _ => {}
}
} }
} }
@@ -481,16 +465,16 @@ impl<'a> ChunkedIterator<'a> {
} }
})) }))
} }
/* /*
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self { pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
ChunkedIterator { ChunkedIterator {
chunk_num: 0, chunk_num: 0,
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))), iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
deep_cut_encountered: false, deep_cut_encountered: false,
cut_var_in_head: false, cut_var_in_head: false,
}
} }
} */
*/
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self { pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
use crate::heap_iter::*; use crate::heap_iter::*;
use crate::machine::*; use crate::machine::*;
use prolog_parser::temp_v;
use crate::indexmap::IndexSet; use indexmap::IndexSet;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::vec::IntoIter; use std::vec::IntoIter;
@@ -20,8 +21,7 @@ pub(super) struct AttrVarInitializer {
} }
impl AttrVarInitializer { impl AttrVarInitializer {
pub(super) pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
AttrVarInitializer { AttrVarInitializer {
attribute_goals: vec![], attribute_goals: vec![],
attr_var_queue: vec![], attr_var_queue: vec![],
@@ -34,24 +34,21 @@ impl AttrVarInitializer {
} }
#[inline] #[inline]
pub(super) pub(super) fn reset(&mut self) {
fn reset(&mut self) { self.attribute_goals.clear();
self.attribute_goals.clear();
self.attr_var_queue.clear(); self.attr_var_queue.clear();
self.bindings.clear(); self.bindings.clear();
} }
#[inline] #[inline]
pub(super) pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
self.attr_var_queue.truncate(queue_b); self.attr_var_queue.truncate(queue_b);
self.bindings.truncate(bindings_b); self.bindings.truncate(bindings_b);
} }
} }
impl MachineState { impl MachineState {
pub(super) pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
if self.attr_var_init.bindings.is_empty() { if self.attr_var_init.bindings.is_empty() {
self.attr_var_init.instigating_p = self.p.local(); self.attr_var_init.instigating_p = self.p.local();
@@ -79,7 +76,7 @@ impl MachineState {
let iter = self let iter = self
.attr_var_init .attr_var_init
.bindings .bindings
.drain(0 ..) .drain(0..)
.map(|(_, addr)| HeapCellValue::Addr(addr)); .map(|(_, addr)| HeapCellValue::Addr(addr));
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter)); let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
@@ -97,8 +94,7 @@ impl MachineState {
self[temp_v!(2)] = value_list_addr; self[temp_v!(2)] = value_list_addr;
} }
pub(super) pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..] let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
.iter() .iter()
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) { .filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
@@ -107,29 +103,25 @@ impl MachineState {
}) })
.collect(); .collect();
attr_vars.sort_unstable_by(|a1, a2| { attr_vars
self.compare_term_test(a1, a2).unwrap_or(Ordering::Less) .sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2).unwrap_or(Ordering::Less));
});
self.term_dedup(&mut attr_vars); self.term_dedup(&mut attr_vars);
attr_vars.into_iter() attr_vars.into_iter()
} }
pub(super) pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
fn verify_attr_interrupt(&mut self, p: usize) {
self.allocate(self.num_of_args + 2); self.allocate(self.num_of_args + 2);
let e = self.e; let e = self.e;
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp; self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
for i in 1 .. self.num_of_args + 1 { for i in 1..self.num_of_args + 1 {
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)]; self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
} }
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::CutPoint(self.b0);
Addr::CutPoint(self.b0); self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Usize(self.num_of_args);
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] =
Addr::Usize(self.num_of_args);
self.verify_attributes(); self.verify_attributes();
@@ -138,9 +130,8 @@ impl MachineState {
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p)); self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
} }
pub(super) pub(super) fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> { let mut seen_set = IndexSet::new();
let mut seen_set = IndexSet::new();
let mut seen_vars = vec![]; let mut seen_vars = vec![];
let mut iter = self.acyclic_pre_order_iter(addr); let mut iter = self.acyclic_pre_order_iter(addr);

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use crate::prolog_parser_rebis::ast::Constant; use prolog_parser::ast::Constant;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::partial_string::*; use crate::machine::partial_string::*;
@@ -42,16 +42,17 @@ impl<T: RawBlockTraits> Drop for HeapTemplate<T> {
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) pub(crate) struct HeapIntoIter<T: RawBlockTraits> {
struct HeapIntoIter<T: RawBlockTraits> {
offset: usize, offset: usize,
buf: RawBlock<T>, buf: RawBlock<T>,
} }
impl<T: RawBlockTraits> Drop for HeapIntoIter<T> { impl<T: RawBlockTraits> Drop for HeapIntoIter<T> {
fn drop(&mut self) { fn drop(&mut self) {
let mut heap = let mut heap = HeapTemplate {
HeapTemplate { buf: self.buf.take(), _marker: PhantomData }; buf: self.buf.take(),
_marker: PhantomData,
};
heap.truncate(self.offset / mem::size_of::<HeapCellValue>()); heap.truncate(self.offset / mem::size_of::<HeapCellValue>());
heap.buf.deallocate(); heap.buf.deallocate();
@@ -66,9 +67,7 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
self.offset += mem::size_of::<HeapCellValue>(); self.offset += mem::size_of::<HeapCellValue>();
if ptr < self.buf.top as usize { if ptr < self.buf.top as usize {
unsafe { unsafe { Some(ptr::read(ptr as *const HeapCellValue)) }
Some(ptr::read(ptr as *const HeapCellValue))
}
} else { } else {
None None
} }
@@ -76,15 +75,13 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) pub(crate) struct HeapIter<'a, T: RawBlockTraits> {
struct HeapIter<'a, T: RawBlockTraits> {
offset: usize, offset: usize,
buf: &'a RawBlock<T>, buf: &'a RawBlock<T>,
} }
impl<'a, T: RawBlockTraits> HeapIter<'a, T> { impl<'a, T: RawBlockTraits> HeapIter<'a, T> {
pub(crate) pub(crate) fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
HeapIter { buf, offset } HeapIter { buf, offset }
} }
} }
@@ -97,9 +94,7 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
self.offset += mem::size_of::<HeapCellValue>(); self.offset += mem::size_of::<HeapCellValue>();
if ptr < self.buf.top as usize { if ptr < self.buf.top as usize {
unsafe { unsafe { Some(&*(ptr as *const _)) }
Some(&*(ptr as *const _))
}
} else { } else {
None None
} }
@@ -107,23 +102,20 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) pub(crate) fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
for (index, term) in heap.enumerate() { for (index, term) in heap.enumerate() {
println!("{} : {}", h + index, term); println!("{} : {}", h + index, term);
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) pub(crate) struct HeapIterMut<'a, T: RawBlockTraits> {
struct HeapIterMut<'a, T: RawBlockTraits> {
offset: usize, offset: usize,
buf: &'a mut RawBlock<T>, buf: &'a mut RawBlock<T>,
} }
impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> { impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> {
pub(crate) pub(crate) fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
HeapIterMut { buf, offset } HeapIterMut { buf, offset }
} }
} }
@@ -136,9 +128,7 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
self.offset += mem::size_of::<HeapCellValue>(); self.offset += mem::size_of::<HeapCellValue>();
if ptr < self.buf.top as usize { if ptr < self.buf.top as usize {
unsafe { unsafe { Some(&mut *(ptr as *mut _)) }
Some(&mut *(ptr as *mut _))
}
} else { } else {
None None
} }
@@ -147,51 +137,33 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
impl<T: RawBlockTraits> HeapTemplate<T> { impl<T: RawBlockTraits> HeapTemplate<T> {
#[inline] #[inline]
pub(crate) pub(crate) fn new() -> Self {
fn new() -> Self { HeapTemplate {
HeapTemplate { buf: RawBlock::new(), _marker: PhantomData } buf: RawBlock::new(),
} _marker: PhantomData,
#[inline]
pub(crate)
fn clone(&self, h: usize) -> HeapCellValue {
match &self[h] {
&HeapCellValue::Addr(addr) => {
HeapCellValue::Addr(addr)
}
&HeapCellValue::Atom(ref name, ref op) => {
HeapCellValue::Atom(name.clone(), op.clone())
}
&HeapCellValue::DBRef(ref db_ref) => {
HeapCellValue::DBRef(db_ref.clone())
}
&HeapCellValue::Integer(ref n) => {
HeapCellValue::Integer(n.clone())
}
&HeapCellValue::LoadStatePayload(_) => {
HeapCellValue::Addr(Addr::LoadStatePayload(h))
}
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
}
&HeapCellValue::PartialString(..) => {
HeapCellValue::Addr(Addr::PStrLocation(h, 0))
}
&HeapCellValue::Rational(ref r) => {
HeapCellValue::Rational(r.clone())
}
&HeapCellValue::Stream(_) => {
HeapCellValue::Addr(Addr::Stream(h))
}
&HeapCellValue::TcpListener(_) => {
HeapCellValue::Addr(Addr::TcpListener(h))
}
} }
} }
#[inline] #[inline]
pub(crate) pub(crate) fn clone(&self, h: usize) -> HeapCellValue {
fn put_complete_string(&mut self, s: &str) -> Addr { match &self[h] {
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr),
&HeapCellValue::Atom(ref name, ref op) => HeapCellValue::Atom(name.clone(), op.clone()),
&HeapCellValue::DBRef(ref db_ref) => HeapCellValue::DBRef(db_ref.clone()),
&HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
&HeapCellValue::LoadStatePayload(_) => HeapCellValue::Addr(Addr::LoadStatePayload(h)),
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
}
&HeapCellValue::PartialString(..) => HeapCellValue::Addr(Addr::PStrLocation(h, 0)),
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
&HeapCellValue::Stream(_) => HeapCellValue::Addr(Addr::Stream(h)),
&HeapCellValue::TcpListener(_) => HeapCellValue::Addr(Addr::TcpListener(h)),
}
}
#[inline]
pub(crate) fn put_complete_string(&mut self, s: &str) -> Addr {
if s.is_empty() { if s.is_empty() {
return Addr::EmptyList; return Addr::EmptyList;
} }
@@ -214,30 +186,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn put_constant(&mut self, c: Constant) -> Addr {
fn put_constant(&mut self, c: Constant) -> Addr {
match c { match c {
Constant::Atom(name, op) => { Constant::Atom(name, op) => Addr::Con(self.push(HeapCellValue::Atom(name, op))),
Addr::Con(self.push(HeapCellValue::Atom(name, op))) Constant::Char(c) => Addr::Char(c),
} Constant::EmptyList => Addr::EmptyList,
Constant::Char(c) => { Constant::Fixnum(n) => Addr::Fixnum(n),
Addr::Char(c) Constant::Integer(n) => Addr::Con(self.push(HeapCellValue::Integer(n))),
} Constant::Rational(r) => Addr::Con(self.push(HeapCellValue::Rational(r))),
Constant::EmptyList => { Constant::Float(f) => Addr::Float(f),
Addr::EmptyList
}
Constant::Fixnum(n) => {
Addr::Fixnum(n)
}
Constant::Integer(n) => {
Addr::Con(self.push(HeapCellValue::Integer(n)))
}
Constant::Rational(r) => {
Addr::Con(self.push(HeapCellValue::Rational(r)))
}
Constant::Float(f) => {
Addr::Float(f)
}
Constant::String(s) => { Constant::String(s) => {
if s.is_empty() { if s.is_empty() {
Addr::EmptyList Addr::EmptyList
@@ -245,15 +202,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
self.put_complete_string(&s) self.put_complete_string(&s)
} }
} }
Constant::Usize(n) => { Constant::Usize(n) => Addr::Usize(n),
Addr::Usize(n)
}
} }
} }
#[inline] #[inline]
pub(crate) pub(crate) fn pop(&mut self) {
fn pop(&mut self) {
let h = self.h(); let h = self.h();
if h > 0 { if h > 0 {
@@ -262,8 +216,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn push(&mut self, val: HeapCellValue) -> usize {
fn push(&mut self, val: HeapCellValue) -> usize {
let h = self.h(); let h = self.h();
unsafe { unsafe {
@@ -276,8 +229,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn atom_at(&self, h: usize) -> bool {
fn atom_at(&self, h: usize) -> bool {
if let HeapCellValue::Atom(..) = &self[h] { if let HeapCellValue::Atom(..) = &self[h] {
true true
} else { } else {
@@ -286,24 +238,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
match non_heap_value { match non_heap_value {
HeapCellValue::Addr(addr) => { HeapCellValue::Addr(addr) => addr,
addr val @ HeapCellValue::Atom(..)
} | val @ HeapCellValue::Integer(_)
val @ HeapCellValue::Atom(..) | | val @ HeapCellValue::DBRef(_)
val @ HeapCellValue::Integer(_) | | val @ HeapCellValue::Rational(_) => Addr::Con(self.push(val)),
val @ HeapCellValue::DBRef(_) | val @ HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(self.push(val)),
val @ HeapCellValue::Rational(_) => { val @ HeapCellValue::NamedStr(..) => Addr::Str(self.push(val)),
Addr::Con(self.push(val))
}
val @ HeapCellValue::LoadStatePayload(_) => {
Addr::LoadStatePayload(self.push(val))
}
val @ HeapCellValue::NamedStr(..) => {
Addr::Str(self.push(val))
}
HeapCellValue::PartialString(pstr, has_tail) => { HeapCellValue::PartialString(pstr, has_tail) => {
let h = self.push(HeapCellValue::PartialString(pstr, has_tail)); let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
@@ -313,20 +256,14 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
Addr::Con(h) Addr::Con(h)
} }
val @ HeapCellValue::Stream(..) => { val @ HeapCellValue::Stream(..) => Addr::Stream(self.push(val)),
Addr::Stream(self.push(val)) val @ HeapCellValue::TcpListener(..) => Addr::TcpListener(self.push(val)),
}
val @ HeapCellValue::TcpListener(..) => {
Addr::TcpListener(self.push(val))
}
} }
} }
#[inline] #[inline]
pub(crate) pub(crate) fn allocate_pstr(&mut self, src: &str) -> Addr {
fn allocate_pstr(&mut self, src: &str) -> Addr { self.write_pstr(src).unwrap_or_else(|| Addr::EmptyList)
self.write_pstr(src)
.unwrap_or_else(|| Addr::EmptyList)
} }
#[inline] #[inline]
@@ -347,23 +284,20 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
let h = self.h(); let h = self.h();
let (pstr, rest_src) = let (pstr, rest_src) = match PartialString::new(src) {
match PartialString::new(src) { Some(tuple) => tuple,
Some(tuple) => { None => {
tuple if src.len() > '\u{0}'.len_utf8() {
src = &src['\u{0}'.len_utf8()..];
continue;
} else if orig_h == h {
return None;
} else {
self[h - 1] = HeapCellValue::Addr(Addr::HeapCell(h - 1));
return Some(Addr::PStrLocation(orig_h, 0));
} }
None => { }
if src.len() > '\u{0}'.len_utf8() { };
src = &src['\u{0}'.len_utf8() ..];
continue;
} else if orig_h == h {
return None;
} else {
self[h - 1] = HeapCellValue::Addr(Addr::HeapCell(h - 1));
return Some(Addr::PStrLocation(orig_h, 0));
}
}
};
self.push(HeapCellValue::PartialString(pstr, true)); self.push(HeapCellValue::PartialString(pstr, true));
@@ -378,8 +312,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn truncate(&mut self, h: usize) {
fn truncate(&mut self, h: usize) {
let new_top = h * mem::size_of::<HeapCellValue>() + self.buf.base as usize; let new_top = h * mem::size_of::<HeapCellValue>() + self.buf.base as usize;
let mut h = new_top; let mut h = new_top;
@@ -395,30 +328,27 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn h(&self) -> usize {
fn h(&self) -> usize {
(self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>() (self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>()
} }
pub(crate) pub(crate) fn append(&mut self, vals: Vec<HeapCellValue>) {
fn append(&mut self, vals: Vec<HeapCellValue>) {
for val in vals { for val in vals {
self.push(val); self.push(val);
} }
} }
pub(crate) pub(crate) fn clear(&mut self) {
fn clear(&mut self) {
if !self.buf.base.is_null() { if !self.buf.base.is_null() {
self.truncate(0); self.truncate(0);
self.buf.top = self.buf.base; self.buf.top = self.buf.base;
} }
} }
pub(crate) pub(crate) fn to_list<Iter, SrcT>(&mut self, values: Iter) -> usize
fn to_list<Iter, SrcT>(&mut self, values: Iter) -> usize where
where Iter: Iterator<Item = SrcT>, Iter: Iterator<Item = SrcT>,
SrcT: Into<HeapCellValue> SrcT: Into<HeapCellValue>,
{ {
let head_addr = self.h(); let head_addr = self.h();
let mut h = head_addr; let mut h = head_addr;
@@ -436,35 +366,33 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
} }
/* Create an iterator starting from the passed offset. */ /* Create an iterator starting from the passed offset. */
pub(crate) pub(crate) fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>()) HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
} }
pub(crate) pub(crate) fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>()) HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
} }
pub(crate) pub(crate) fn into_iter(mut self) -> HeapIntoIter<T> {
fn into_iter(mut self) -> HeapIntoIter<T> { HeapIntoIter {
HeapIntoIter { buf: self.buf.take(), offset: 0 } buf: self.buf.take(),
offset: 0,
}
} }
pub(crate) pub(crate) fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
for hcv in iter { for hcv in iter {
self.push(hcv); self.push(hcv);
} }
} }
pub(crate) pub(crate) fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
let extract_integer = |s: usize| -> Option<usize> { let extract_integer = |s: usize| -> Option<usize> {
match &self[s] { match &self[s] {
&HeapCellValue::Addr(Addr::Fixnum(n)) => usize::try_from(n).ok(), &HeapCellValue::Addr(Addr::Fixnum(n)) => usize::try_from(n).ok(),
&HeapCellValue::Integer(ref n) => n.to_usize(), &HeapCellValue::Integer(ref n) => n.to_usize(),
_ => None _ => None,
} }
}; };
@@ -473,9 +401,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
match &self[*s] { match &self[*s] {
HeapCellValue::NamedStr(arity, ref name, _) => { HeapCellValue::NamedStr(arity, ref name, _) => {
match (name.as_str(), *arity) { match (name.as_str(), *arity) {
("dir_entry", 1) => { ("dir_entry", 1) => extract_integer(s + 1).map(LocalCodePtr::DirEntry),
extract_integer(s+1).map(LocalCodePtr::DirEntry)
}
/* /*
("top_level", 2) => { ("top_level", 2) => {
if let Some(chunk_num) = extract_integer(s+1) { if let Some(chunk_num) = extract_integer(s+1) {
@@ -487,15 +413,13 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
None None
} }
*/ */
_ => { _ => None,
None
}
} }
} }
_ => unreachable!() _ => unreachable!(),
} }
} }
_ => None _ => None,
} }
} }
@@ -505,9 +429,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => { &Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => {
RefOrOwned::Borrowed(&self[h]) RefOrOwned::Borrowed(&self[h])
} }
addr => { addr => RefOrOwned::Owned(HeapCellValue::Addr(*addr)),
RefOrOwned::Owned(HeapCellValue::Addr(*addr))
}
} }
} }
} }

View File

@@ -1,10 +1,11 @@
use crate::machine::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::term_stream::*; use crate::machine::*;
use prolog_parser::clause_name;
use crate::machine::term_stream::*;
use indexmap::IndexSet; use indexmap::IndexSet;
use crate::ref_thread_local::RefThreadLocal; use ref_thread_local::RefThreadLocal;
type ModuleOpExports = Vec<(OpDecl, Option<(usize, Specifier)>)>; type ModuleOpExports = Vec<(OpDecl, Option<(usize, Specifier)>)>;
@@ -19,37 +20,35 @@ pub(super) struct LoadState<'a> {
pub(super) wam: &'a mut Machine, pub(super) wam: &'a mut Machine,
} }
pub(super) pub(super) fn set_code_index(
fn set_code_index(
retraction_info: &mut RetractionInfo, retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
key: PredicateKey, key: PredicateKey,
code_index: &CodeIndex, code_index: &CodeIndex,
code_ptr: IndexPtr, code_ptr: IndexPtr,
) { ) {
let record = let record = match compilation_target {
match compilation_target { CompilationTarget::User => {
CompilationTarget::User => { if IndexPtr::Undefined == code_index.get() {
if IndexPtr::Undefined == code_index.get() { code_index.set(code_ptr);
code_index.set(code_ptr); RetractionRecord::AddedUserPredicate(key)
RetractionRecord::AddedUserPredicate(key) } else {
} else { // TODO: emit warning about overwriting previous record
// TODO: emit warning about overwriting previous record let replaced = code_index.replace(code_ptr);
let replaced = code_index.replace(code_ptr); RetractionRecord::ReplacedUserPredicate(key, replaced)
RetractionRecord::ReplacedUserPredicate(key, replaced)
}
} }
CompilationTarget::Module(ref module_name) => { }
if IndexPtr::Undefined == code_index.get() { CompilationTarget::Module(ref module_name) => {
code_index.set(code_ptr); if IndexPtr::Undefined == code_index.get() {
RetractionRecord::AddedModulePredicate(module_name.clone(), key) code_index.set(code_ptr);
} else { RetractionRecord::AddedModulePredicate(module_name.clone(), key)
// TODO: emit warning about overwriting previous record } else {
let replaced = code_index.replace(code_ptr); // TODO: emit warning about overwriting previous record
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced) let replaced = code_index.replace(code_ptr);
} RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
} }
}; }
};
retraction_info.push_record(record); retraction_info.push_record(record);
} }
@@ -71,16 +70,16 @@ fn add_op_decl_as_module_export(
match op_decl.insert_into_op_dir(wam_op_dir) { match op_decl.insert_into_op_dir(wam_op_dir) {
Some((prec, spec)) => { Some((prec, spec)) => {
retraction_info.push_record( retraction_info.push_record(RetractionRecord::ReplacedUserOp(
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec) op_decl.clone(),
); prec,
spec,
));
module_op_exports.push((op_decl.clone(), Some((prec, spec)))); module_op_exports.push((op_decl.clone(), Some((prec, spec))));
} }
None => { None => {
retraction_info.push_record( retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
RetractionRecord::AddedUserOp(op_decl.clone())
);
module_op_exports.push((op_decl.clone(), None)); module_op_exports.push((op_decl.clone(), None));
} }
@@ -89,49 +88,45 @@ fn add_op_decl_as_module_export(
add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl); add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
} }
pub(super) pub(super) fn add_op_decl(
fn add_op_decl(
retraction_info: &mut RetractionInfo, retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
op_dir: &mut OpDir, op_dir: &mut OpDir,
op_decl: &OpDecl, op_decl: &OpDecl,
) { ) {
match op_decl.insert_into_op_dir(op_dir) { match op_decl.insert_into_op_dir(op_dir) {
Some((prec, spec)) => { Some((prec, spec)) => match &compilation_target {
match &compilation_target { CompilationTarget::User => {
CompilationTarget::User => { retraction_info.push_record(RetractionRecord::ReplacedUserOp(
retraction_info.push_record( op_decl.clone(),
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec), prec,
); spec,
} ));
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(
RetractionRecord::ReplacedModuleOp(
module_name.clone(), op_decl.clone(), prec, spec,
),
);
}
} }
} CompilationTarget::Module(ref module_name) => {
None => { retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
match &compilation_target { module_name.clone(),
CompilationTarget::User => { op_decl.clone(),
retraction_info.push_record( prec,
RetractionRecord::AddedUserOp(op_decl.clone()), spec,
); ));
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(
RetractionRecord::AddedModuleOp(module_name.clone(), op_decl.clone()),
);
}
} }
} },
None => match &compilation_target {
CompilationTarget::User => {
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(RetractionRecord::AddedModuleOp(
module_name.clone(),
op_decl.clone(),
));
}
},
} }
} }
pub(super) pub(super) fn import_module_exports(
fn import_module_exports(
retraction_info: &mut RetractionInfo, retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
imported_module: &Module, imported_module: &Module,
@@ -166,12 +161,7 @@ fn import_module_exports(
} }
} }
ModuleExport::OpDecl(ref op_decl) => { ModuleExport::OpDecl(ref op_decl) => {
add_op_decl( add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
retraction_info,
compilation_target,
op_dir,
op_decl,
);
} }
} }
} }
@@ -185,7 +175,7 @@ fn import_module_exports_into_module(
op_dir: &mut OpDir, op_dir: &mut OpDir,
meta_predicates: &mut MetaPredicateDir, meta_predicates: &mut MetaPredicateDir,
wam_op_dir: &mut OpDir, wam_op_dir: &mut OpDir,
module_op_exports: &mut ModuleOpExports module_op_exports: &mut ModuleOpExports,
) { ) {
for export in imported_module.module_decl.exports.iter() { for export in imported_module.module_decl.exports.iter() {
match export { match export {
@@ -227,7 +217,6 @@ fn import_module_exports_into_module(
} }
} }
fn import_qualified_module_exports( fn import_qualified_module_exports(
retraction_info: &mut RetractionInfo, retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
@@ -263,12 +252,7 @@ fn import_qualified_module_exports(
} }
} }
ModuleExport::OpDecl(ref op_decl) => { ModuleExport::OpDecl(ref op_decl) => {
add_op_decl( add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
retraction_info,
compilation_target,
op_dir,
op_decl,
);
} }
} }
} }
@@ -326,29 +310,28 @@ fn import_qualified_module_exports_into_module(
impl<'a> LoadState<'a> { impl<'a> LoadState<'a> {
#[inline] #[inline]
pub(super) pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
fn increment_clause_assert_margin(&mut self, incr: usize) {
match &self.compilation_target { match &self.compilation_target {
CompilationTarget::User => { CompilationTarget::User => {}
}
CompilationTarget::Module(ref module_name) => { CompilationTarget::Module(ref module_name) => {
self.retraction_info.push_record( self.retraction_info
RetractionRecord::IncreasedClauseAssertMargin( .push_record(RetractionRecord::IncreasedClauseAssertMargin(
module_name.clone(), module_name.clone(),
incr, incr,
), ));
);
self.wam.indices.modules.get_mut(module_name) self.wam
.indices
.modules
.get_mut(module_name)
.map(|module| module.clause_assert_margin += incr); .map(|module| module.clause_assert_margin += incr);
} }
} }
} }
#[inline] #[inline]
pub(super) pub(super) fn remove_module_op_exports(&mut self) {
fn remove_module_op_exports(&mut self) { for (mut op_decl, record) in self.module_op_exports.drain(0..) {
for (mut op_decl, record) in self.module_op_exports.drain(0 ..) {
op_decl.remove(&mut self.wam.indices.op_dir); op_decl.remove(&mut self.wam.indices.op_dir);
if let Some((prec, spec)) = record { if let Some((prec, spec)) = record {
@@ -365,26 +348,28 @@ impl<'a> LoadState<'a> {
key: PredicateKey, key: PredicateKey,
) -> CodeIndex { ) -> CodeIndex {
match self.wam.indices.modules.get_mut(&module_name) { match self.wam.indices.modules.get_mut(&module_name) {
Some(ref mut module) => { Some(ref mut module) => module
module.code_dir .code_dir
.entry(key) .entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone() .clone(),
}
None => { None => {
let mut module = Module::new( let mut module = Module::new(
ModuleDecl { name: module_name.clone(), exports: vec![] }, ModuleDecl {
name: module_name.clone(),
exports: vec![],
},
ListingSource::DynamicallyGenerated, ListingSource::DynamicallyGenerated,
); );
let code_index = module.code_dir let code_index = module
.code_dir
.entry(key) .entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone(); .clone();
self.retraction_info.push_record( self.retraction_info
RetractionRecord::AddedModule(module_name.clone()), .push_record(RetractionRecord::AddedModule(module_name.clone()));
);
self.wam.indices.modules.insert(module_name, module); self.wam.indices.modules.insert(module_name, module);
code_index code_index
@@ -392,29 +377,31 @@ impl<'a> LoadState<'a> {
} }
} }
pub(super) pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
match self.compilation_target.clone() { match self.compilation_target.clone() {
CompilationTarget::User => { CompilationTarget::User => self
self.wam.indices.code_dir .wam
.entry(key) .indices
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) .code_dir
.clone() .entry(key)
} .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone(),
CompilationTarget::Module(module_name) => { CompilationTarget::Module(module_name) => {
self.get_or_insert_local_code_index(module_name, key) self.get_or_insert_local_code_index(module_name, key)
} }
} }
} }
pub(super) pub(super) fn get_or_insert_qualified_code_index(
fn get_or_insert_qualified_code_index(
&mut self, &mut self,
module_name: ClauseName, module_name: ClauseName,
key: PredicateKey, key: PredicateKey,
) -> CodeIndex { ) -> CodeIndex {
if module_name.as_str() == "user" { if module_name.as_str() == "user" {
return self.wam.indices.code_dir return self
.wam
.indices
.code_dir
.entry(key) .entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)) .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
.clone(); .clone();
@@ -424,15 +411,20 @@ impl<'a> LoadState<'a> {
} }
#[inline] #[inline]
pub(super) pub(super) fn add_extensible_predicate(
fn add_extensible_predicate(&mut self, key: PredicateKey, skeleton: PredicateSkeleton) { &mut self,
key: PredicateKey,
skeleton: PredicateSkeleton,
) {
match &self.compilation_target { match &self.compilation_target {
CompilationTarget::User => { CompilationTarget::User => {
self.wam.indices.extensible_predicates.insert(key.clone(), skeleton); self.wam
.indices
.extensible_predicates
.insert(key.clone(), skeleton);
self.retraction_info.push_record( self.retraction_info
RetractionRecord::AddedUserExtensiblePredicate(key), .push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
);
} }
CompilationTarget::Module(ref module_name) => { CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.wam.indices.modules.get_mut(module_name) { if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
@@ -448,8 +440,7 @@ impl<'a> LoadState<'a> {
} }
} }
pub(super) pub(super) fn add_op_decl(&mut self, op_decl: &OpDecl) {
fn add_op_decl(&mut self, op_decl: &OpDecl) {
match &self.compilation_target { match &self.compilation_target {
CompilationTarget::User => { CompilationTarget::User => {
add_op_decl( add_op_decl(
@@ -479,8 +470,7 @@ impl<'a> LoadState<'a> {
} }
} }
pub(super) pub(super) fn get_clause_type(
fn get_clause_type(
&mut self, &mut self,
name: ClauseName, name: ClauseName,
arity: usize, arity: usize,
@@ -495,14 +485,11 @@ impl<'a> LoadState<'a> {
let idx = self.get_or_insert_code_index((name.clone(), arity)); let idx = self.get_or_insert_code_index((name.clone(), arity));
ClauseType::Op(name, fixity, idx) ClauseType::Op(name, fixity, idx)
} }
ct => { ct => ct,
ct
}
} }
} }
pub(super) pub(super) fn get_qualified_clause_type(
fn get_qualified_clause_type(
&mut self, &mut self,
module_name: ClauseName, module_name: ClauseName,
name: ClauseName, name: ClauseName,
@@ -522,14 +509,11 @@ impl<'a> LoadState<'a> {
ClauseType::Op(name, fixity, idx) ClauseType::Op(name, fixity, idx)
} }
ct => { ct => ct,
ct
}
} }
} }
pub(super) pub(super) fn add_meta_predicate_record(
fn add_meta_predicate_record(
&mut self, &mut self,
module_name: ClauseName, module_name: ClauseName,
name: ClauseName, name: ClauseName,
@@ -540,20 +524,26 @@ impl<'a> LoadState<'a> {
match module_name.as_str() { match module_name.as_str() {
"user" => { "user" => {
match self.wam.indices.meta_predicates.insert(key.clone(), meta_specs) { match self
.wam
.indices
.meta_predicates
.insert(key.clone(), meta_specs)
{
Some(old_meta_specs) => { Some(old_meta_specs) => {
self.retraction_info.push_record( self.retraction_info
RetractionRecord::ReplacedMetaPredicate( .push_record(RetractionRecord::ReplacedMetaPredicate(
module_name.clone(), key.0, old_meta_specs, module_name.clone(),
), key.0,
); old_meta_specs,
));
} }
None => { None => {
self.retraction_info.push_record( self.retraction_info
RetractionRecord::AddedMetaPredicate( .push_record(RetractionRecord::AddedMetaPredicate(
module_name.clone(), key, module_name.clone(),
) key,
); ));
} }
} }
} }
@@ -564,15 +554,15 @@ impl<'a> LoadState<'a> {
Some(old_meta_specs) => { Some(old_meta_specs) => {
self.retraction_info.push_record( self.retraction_info.push_record(
RetractionRecord::ReplacedMetaPredicate( RetractionRecord::ReplacedMetaPredicate(
module_name.clone(), key.0, old_meta_specs, module_name.clone(),
key.0,
old_meta_specs,
), ),
); );
} }
None => { None => {
self.retraction_info.push_record( self.retraction_info.push_record(
RetractionRecord::AddedMetaPredicate( RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
module_name.clone(), key,
)
); );
} }
} }
@@ -588,15 +578,14 @@ impl<'a> LoadState<'a> {
module.meta_predicates.insert(key.clone(), meta_specs); module.meta_predicates.insert(key.clone(), meta_specs);
self.retraction_info.push_record( self.retraction_info
RetractionRecord::AddedMetaPredicate( .push_record(RetractionRecord::AddedMetaPredicate(
module_name.clone(), key, module_name.clone(),
) key,
); ));
self.retraction_info.push_record( self.retraction_info
RetractionRecord::AddedModule(module_name.clone()), .push_record(RetractionRecord::AddedModule(module_name.clone()));
);
self.wam.indices.modules.insert(module_name, module); self.wam.indices.modules.insert(module_name, module);
} }
@@ -623,32 +612,29 @@ impl<'a> LoadState<'a> {
} }
} }
pub(crate) pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
let module_name = module_decl.name.clone(); let module_name = module_decl.name.clone();
let mut module = let mut module = match self.wam.indices.modules.remove(&module_name) {
match self.wam.indices.modules.remove(&module_name) { Some(mut module) => {
Some(mut module) => { let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
self.retraction_info.push_record( self.retraction_info
RetractionRecord::ReplacedModule( .push_record(RetractionRecord::ReplacedModule(
old_module_decl, listing_src.clone(), old_module_decl,
), listing_src.clone(),
); ));
module.listing_src = listing_src; module.listing_src = listing_src;
module module
} }
None => { None => {
self.retraction_info.push_record( self.retraction_info
RetractionRecord::AddedModule(module_name.clone()), .push_record(RetractionRecord::AddedModule(module_name.clone()));
);
Module::new(module_decl, listing_src) Module::new(module_decl, listing_src)
} }
}; };
self.import_builtins_in_module( self.import_builtins_in_module(
&mut module.code_dir, &mut module.code_dir,
@@ -676,8 +662,7 @@ impl<'a> LoadState<'a> {
self.wam.indices.modules.insert(module_name, module); self.wam.indices.modules.insert(module_name, module);
} }
pub(super) pub(super) fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
if let Some(module) = self.wam.indices.modules.remove(&module_name) { if let Some(module) = self.wam.indices.modules.remove(&module_name) {
match &self.compilation_target { match &self.compilation_target {
CompilationTarget::User => { CompilationTarget::User => {
@@ -717,7 +702,9 @@ impl<'a> LoadState<'a> {
self.wam.indices.modules.insert(module_name, module); self.wam.indices.modules.insert(module_name, module);
Ok(()) Ok(())
} else { } else {
Err(SessionError::ExistenceError(ExistenceError::Module(module_name))) Err(SessionError::ExistenceError(ExistenceError::Module(
module_name,
)))
} }
} }
@@ -765,41 +752,41 @@ impl<'a> LoadState<'a> {
self.wam.indices.modules.insert(module_name, module); self.wam.indices.modules.insert(module_name, module);
Ok(()) Ok(())
} else { } else {
Err(SessionError::ExistenceError(ExistenceError::Module(module_name))) Err(SessionError::ExistenceError(ExistenceError::Module(
module_name,
)))
} }
} }
pub(crate) pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> { let (stream, listing_src) = match module_src {
let (stream, listing_src) = ModuleSource::File(filename) => {
match module_src { let mut path_buf = PathBuf::from(filename.as_str());
ModuleSource::File(filename) => { path_buf.set_extension("pl");
let mut path_buf = PathBuf::from(filename.as_str()); let file = File::open(&path_buf)?;
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
(Stream::from_file_as_input(filename.clone(), file), (
ListingSource::File(filename, path_buf)) Stream::from_file_as_input(filename.clone(), file),
} ListingSource::File(filename, path_buf),
ModuleSource::Library(library) => { )
match LIBRARIES.borrow().get(library.as_str()) { }
Some(code) => { ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
if let Some(ref module) = self.wam.indices.modules.get(&library) { Some(code) => {
if let ListingSource::DynamicallyGenerated = &module.listing_src { if let Some(ref module) = self.wam.indices.modules.get(&library) {
(Stream::from(*code), ListingSource::User) if let ListingSource::DynamicallyGenerated = &module.listing_src {
} else { (Stream::from(*code), ListingSource::User)
return self.import_module(library); } else {
}
} else {
(Stream::from(*code), ListingSource::User)
}
}
None => {
return self.import_module(library); return self.import_module(library);
} }
} else {
(Stream::from(*code), ListingSource::User)
} }
} }
}; None => {
return self.import_module(library);
}
},
};
let compilation_target = { let compilation_target = {
let stream = &mut parsing_stream(stream)?; let stream = &mut parsing_stream(stream)?;
@@ -820,43 +807,39 @@ impl<'a> LoadState<'a> {
// nothing to do. // nothing to do.
Ok(()) Ok(())
} }
CompilationTarget::Module(module_name) => { CompilationTarget::Module(module_name) => self.import_module(module_name),
self.import_module(module_name)
}
} }
} }
pub(crate) pub(crate) fn use_qualified_module(
fn use_qualified_module(
&mut self, &mut self,
module_src: ModuleSource, module_src: ModuleSource,
exports: IndexSet<ModuleExport>, exports: IndexSet<ModuleExport>,
) -> Result<(), SessionError> { ) -> Result<(), SessionError> {
let (stream, listing_src) = let (stream, listing_src) = match module_src {
match module_src { ModuleSource::File(filename) => {
ModuleSource::File(filename) => { let mut path_buf = PathBuf::from(filename.as_str());
let mut path_buf = PathBuf::from(filename.as_str()); path_buf.set_extension("pl");
path_buf.set_extension("pl"); let file = File::open(&path_buf)?;
let file = File::open(&path_buf)?;
(Stream::from_file_as_input(filename.clone(), file), (
ListingSource::File(filename, path_buf)) Stream::from_file_as_input(filename.clone(), file),
} ListingSource::File(filename, path_buf),
ModuleSource::Library(library) => { )
match LIBRARIES.borrow().get(library.as_str()) { }
Some(code) => { ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
if self.wam.indices.modules.contains_key(&library) { Some(code) => {
return self.import_qualified_module(library, exports); if self.wam.indices.modules.contains_key(&library) {
} else { return self.import_qualified_module(library, exports);
(Stream::from(*code), ListingSource::User) } else {
} (Stream::from(*code), ListingSource::User)
}
None => {
return self.import_qualified_module(library, exports);
}
} }
} }
}; None => {
return self.import_qualified_module(library, exports);
}
},
};
let compilation_target = { let compilation_target = {
let stream = &mut parsing_stream(stream)?; let stream = &mut parsing_stream(stream)?;
@@ -884,12 +867,9 @@ impl<'a> LoadState<'a> {
} }
#[inline] #[inline]
pub(super) pub(super) fn composite_op_dir(&self) -> CompositeOpDir {
fn composite_op_dir(&self) -> CompositeOpDir {
match &self.compilation_target { match &self.compilation_target {
CompilationTarget::User => { CompilationTarget::User => CompositeOpDir::new(&self.wam.indices.op_dir, None),
CompositeOpDir::new(&self.wam.indices.op_dir, None)
}
CompilationTarget::Module(ref module_name) => { CompilationTarget::Module(ref module_name) => {
match self.wam.indices.modules.get(module_name) { match self.wam.indices.modules.get(module_name) {
Some(ref module) => { Some(ref module) => {

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::{clause_name, temp_v};
use crate::forms::{ModuleSource, Number}; //, PredicateKey}; use crate::forms::{ModuleSource, Number}; //, PredicateKey};
use crate::machine::heap::*; use crate::machine::heap::*;
@@ -23,74 +24,59 @@ pub(crate) struct MachineError {
from: ErrorProvenance, from: ErrorProvenance,
} }
pub(crate) pub(crate) trait TypeError {
trait TypeError {
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError; fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
} }
impl TypeError for Addr { impl TypeError for Addr {
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError { fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
let stub = functor!( let stub = functor!("type_error", [atom(valid_type.as_str()), addr(self)]);
"type_error",
[atom(valid_type.as_str()), addr(self)]
);
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Received from: ErrorProvenance::Received,
} }
} }
} }
impl TypeError for HeapCellValue { impl TypeError for HeapCellValue {
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError { fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
let stub = functor!( let stub = functor!("type_error", [atom(valid_type.as_str()), value(self)]);
"type_error",
[atom(valid_type.as_str()), value(self)]
);
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Received from: ErrorProvenance::Received,
} }
} }
} }
impl TypeError for MachineStub { impl TypeError for MachineStub {
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError { fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
let stub = functor!( let stub = functor!("type_error", [atom(valid_type.as_str()), aux(h, 0)], [self]);
"type_error",
[atom(valid_type.as_str()), aux(h, 0)],
[self]
);
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Constructed from: ErrorProvenance::Constructed,
} }
} }
} }
impl TypeError for Number { impl TypeError for Number {
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError { fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
let stub = functor!( let stub = functor!("type_error", [atom(valid_type.as_str()), number(self)]);
"type_error",
[atom(valid_type.as_str()), number(self)]
);
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Received from: ErrorProvenance::Received,
} }
} }
} }
pub(crate) pub(crate) trait PermissionError {
trait PermissionError {
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError; fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
} }
@@ -104,7 +90,7 @@ impl PermissionError for Addr {
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Received from: ErrorProvenance::Received,
} }
} }
} }
@@ -120,22 +106,18 @@ impl PermissionError for MachineStub {
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Constructed from: ErrorProvenance::Constructed,
} }
} }
} }
pub(super) pub(super) trait DomainError {
trait DomainError {
fn domain_error(self, error: DomainErrorType) -> MachineError; fn domain_error(self, error: DomainErrorType) -> MachineError;
} }
impl DomainError for Addr { impl DomainError for Addr {
fn domain_error(self, error: DomainErrorType) -> MachineError { fn domain_error(self, error: DomainErrorType) -> MachineError {
let stub = functor!( let stub = functor!("domain_error", [atom(error.as_str()), addr(self)]);
"domain_error",
[atom(error.as_str()), addr(self)]
);
MachineError { MachineError {
stub, stub,
@@ -147,10 +129,7 @@ impl DomainError for Addr {
impl DomainError for Number { impl DomainError for Number {
fn domain_error(self, error: DomainErrorType) -> MachineError { fn domain_error(self, error: DomainErrorType) -> MachineError {
let stub = functor!( let stub = functor!("domain_error", [atom(error.as_str()), number(self)]);
"domain_error",
[atom(error.as_str()), number(self)]
);
MachineError { MachineError {
stub, stub,
@@ -161,8 +140,7 @@ impl DomainError for Number {
} }
impl MachineError { impl MachineError {
pub(super) pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
functor!( functor!(
"/", "/",
SharedOpDesc::new(400, YFX), SharedOpDesc::new(400, YFX),
@@ -171,8 +149,7 @@ impl MachineError {
} }
#[inline] #[inline]
pub(super) pub(super) fn interrupt_error() -> Self {
fn interrupt_error() -> Self {
let stub = functor!("$interrupt_thrown"); let stub = functor!("$interrupt_thrown");
MachineError { MachineError {
@@ -182,8 +159,7 @@ impl MachineError {
} }
} }
pub(super) pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
fn evaluation_error(eval_error: EvalError) -> Self {
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]); let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
MachineError { MachineError {
@@ -193,13 +169,11 @@ impl MachineError {
} }
} }
pub(super) pub(super) fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
culprit.type_error(h, valid_type) culprit.type_error(h, valid_type)
} }
pub(super) pub(super) fn module_resolution_error(
fn module_resolution_error(
h: usize, h: usize,
mod_name: ClauseName, mod_name: ClauseName,
name: ClauseName, name: ClauseName,
@@ -218,11 +192,7 @@ impl MachineError {
[res_stub] [res_stub]
); );
let stub = functor!( let stub = functor!("evaluation_error", [aux(h, 0)], [ind_stub]);
"evaluation_error",
[aux(h, 0)],
[ind_stub]
);
MachineError { MachineError {
stub, stub,
@@ -231,14 +201,10 @@ impl MachineError {
} }
} }
pub(super) pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
fn existence_error(h: usize, err: ExistenceError) -> Self {
match err { match err {
ExistenceError::Module(name) => { ExistenceError::Module(name) => {
let stub = functor!( let stub = functor!("existence_error", [atom("source_sink"), clause_name(name)]);
"existence_error",
[atom("source_sink"), clause_name(name)]
);
MachineError { MachineError {
stub, stub,
@@ -253,11 +219,7 @@ impl MachineError {
[clause_name(name), integer(arity)] [clause_name(name), integer(arity)]
); );
let stub = functor!( let stub = functor!("existence_error", [atom("procedure"), aux(h, 0)], [culprit]);
"existence_error",
[atom("procedure"), aux(h, 0)],
[culprit]
);
MachineError { MachineError {
stub, stub,
@@ -281,10 +243,7 @@ impl MachineError {
} }
} }
ExistenceError::SourceSink(culprit) => { ExistenceError::SourceSink(culprit) => {
let stub = functor!( let stub = functor!("existence_error", [atom("source_sink"), addr(culprit)]);
"existence_error",
[atom("source_sink"), addr(culprit)]
);
MachineError { MachineError {
stub, stub,
@@ -293,10 +252,7 @@ impl MachineError {
} }
} }
ExistenceError::Stream(culprit) => { ExistenceError::Stream(culprit) => {
let stub = functor!( let stub = functor!("existence_error", [atom("stream"), addr(culprit)]);
"existence_error",
[atom("stream"), addr(culprit)]
);
MachineError { MachineError {
stub, stub,
@@ -307,25 +263,18 @@ impl MachineError {
} }
} }
pub(super) pub(super) fn permission_error<T: PermissionError>(
fn permission_error<T: PermissionError>(
h: usize, h: usize,
err: Permission, err: Permission,
index_str: &'static str, index_str: &'static str,
culprit: T, culprit: T,
) -> Self { ) -> Self {
culprit.permission_error( culprit.permission_error(h, index_str, err)
h,
index_str,
err,
)
} }
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self { fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
match err { match err {
ArithmeticError::UninstantiatedVar => { ArithmeticError::UninstantiatedVar => Self::instantiation_error(),
Self::instantiation_error()
}
ArithmeticError::NonEvaluableFunctor(name, arity) => { ArithmeticError::NonEvaluableFunctor(name, arity) => {
let culprit = functor!( let culprit = functor!(
"/", "/",
@@ -339,13 +288,11 @@ impl MachineError {
} }
#[inline] #[inline]
pub(super) pub(super) fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
culprit.domain_error(error) culprit.domain_error(error)
} }
pub(super) pub(super) fn instantiation_error() -> Self {
fn instantiation_error() -> Self {
let stub = functor!("instantiation_error"); let stub = functor!("instantiation_error");
MachineError { MachineError {
@@ -355,8 +302,7 @@ impl MachineError {
} }
} }
pub(super) pub(super) fn session_error(h: usize, err: SessionError) -> Self {
fn session_error(h: usize, err: SessionError) -> Self {
match err { match err {
// SessionError::CannotOverwriteBuiltIn(pred_str) | // SessionError::CannotOverwriteBuiltIn(pred_str) |
/* /*
@@ -369,9 +315,7 @@ impl MachineError {
) )
} }
*/ */
SessionError::ExistenceError(err) => { SessionError::ExistenceError(err) => Self::existence_error(h, err),
Self::existence_error(h, err)
}
// SessionError::InvalidFileName(filename) => { // SessionError::InvalidFileName(filename) => {
// Self::existence_error(h, ExistenceError::Module(filename)) // Self::existence_error(h, ExistenceError::Module(filename))
// } // }
@@ -385,46 +329,32 @@ impl MachineError {
) )
} }
*/ */
SessionError::ModuleCannotImportSelf(module_name) => { SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
Self::permission_error( h,
h, Permission::Modify,
Permission::Modify, "module",
"module", functor!("module_cannot_import_self", [clause_name(module_name)]),
functor!("module_cannot_import_self", [clause_name(module_name)]), ),
) SessionError::NamelessEntry => Self::permission_error(
} h,
SessionError::NamelessEntry => { Permission::Create,
Self::permission_error( "static_procedure",
h, functor!("nameless_procedure"),
Permission::Create, ),
"static_procedure",
functor!("nameless_procedure")
)
}
SessionError::OpIsInfixAndPostFix(op) => { SessionError::OpIsInfixAndPostFix(op) => {
Self::permission_error( Self::permission_error(h, Permission::Create, "operator", functor!(clause_name(op)))
h,
Permission::Create,
"operator",
functor!(clause_name(op)),
)
}
SessionError::CompilationError(err) => {
Self::syntax_error(h, err)
}
SessionError::QueryCannotBeDefinedAsFact => {
Self::permission_error(
h,
Permission::Create,
"static_procedure",
functor!("query_cannot_be_defined_as_fact")
)
} }
SessionError::CompilationError(err) => Self::syntax_error(h, err),
SessionError::QueryCannotBeDefinedAsFact => Self::permission_error(
h,
Permission::Create,
"static_procedure",
functor!("query_cannot_be_defined_as_fact"),
),
} }
} }
pub(super) pub(super) fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
let err = err.into(); let err = err.into();
if let CompilationError::Arithmetic(err) = err { if let CompilationError::Arithmetic(err) = err {
@@ -434,11 +364,7 @@ impl MachineError {
let location = err.line_and_col_num(); let location = err.line_and_col_num();
let stub = err.as_functor(h); let stub = err.as_functor(h);
let stub = functor!( let stub = functor!("syntax_error", [aux(h, 0)], [stub]);
"syntax_error",
[aux(h, 0)],
[stub]
);
MachineError { MachineError {
stub, stub,
@@ -447,8 +373,7 @@ impl MachineError {
} }
} }
pub(super) pub(super) fn representation_error(flag: RepFlag) -> Self {
fn representation_error(flag: RepFlag) -> Self {
let stub = functor!("representation_error", [atom(flag.as_str())]); let stub = functor!("representation_error", [atom(flag.as_str())]);
MachineError { MachineError {
@@ -515,56 +440,39 @@ impl From<ParserError> for CompilationError {
impl CompilationError { impl CompilationError {
pub fn line_and_col_num(&self) -> Option<(usize, usize)> { pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
match self { match self {
&CompilationError::ParserError(ref err) => &CompilationError::ParserError(ref err) => err.line_and_col_num(),
err.line_and_col_num(), _ => None,
_ =>
None
} }
} }
pub fn as_functor(&self, _h: usize) -> MachineStub { pub fn as_functor(&self, _h: usize) -> MachineStub {
match self { match self {
&CompilationError::Arithmetic(..) => &CompilationError::Arithmetic(..) => functor!("arithmetic_error"),
functor!("arithmetic_error"),
// &CompilationError::BadPendingByte => // &CompilationError::BadPendingByte =>
// functor!("bad_pending_byte"), // functor!("bad_pending_byte"),
&CompilationError::CannotParseCyclicTerm => &CompilationError::CannotParseCyclicTerm => functor!("cannot_parse_cyclic_term"),
functor!("cannot_parse_cyclic_term"),
// &CompilationError::ExpandedTermsListNotAList => // &CompilationError::ExpandedTermsListNotAList =>
// functor!("expanded_terms_list_is_not_a_list"), // functor!("expanded_terms_list_is_not_a_list"),
&CompilationError::ExpectedRel => &CompilationError::ExpectedRel => functor!("expected_relation"),
functor!("expected_relation"),
// &CompilationError::ExpectedTopLevelTerm => // &CompilationError::ExpectedTopLevelTerm =>
// functor!("expected_atom_or_cons_or_clause"), // functor!("expected_atom_or_cons_or_clause"),
&CompilationError::InadmissibleFact => &CompilationError::InadmissibleFact => functor!("inadmissible_fact"),
functor!("inadmissible_fact"), &CompilationError::InadmissibleQueryTerm => functor!("inadmissible_query_term"),
&CompilationError::InadmissibleQueryTerm => &CompilationError::InconsistentEntry => functor!("inconsistent_entry"),
functor!("inadmissible_query_term"),
&CompilationError::InconsistentEntry =>
functor!("inconsistent_entry"),
// &CompilationError::InvalidDoubleQuotesDecl => // &CompilationError::InvalidDoubleQuotesDecl =>
// functor!("invalid_double_quotes_declaration"), // functor!("invalid_double_quotes_declaration"),
// &CompilationError::InvalidHook => // &CompilationError::InvalidHook =>
// functor!("invalid_hook"), // functor!("invalid_hook"),
&CompilationError::InvalidMetaPredicateDecl => &CompilationError::InvalidMetaPredicateDecl => functor!("invalid_meta_predicate_decl"),
functor!("invalid_meta_predicate_decl"), &CompilationError::InvalidModuleDecl => functor!("invalid_module_declaration"),
&CompilationError::InvalidModuleDecl => &CompilationError::InvalidModuleExport => functor!("invalid_module_export"),
functor!("invalid_module_declaration"), &CompilationError::InvalidModuleResolution(ref module_name) => {
&CompilationError::InvalidModuleExport => functor!("no_such_module", [clause_name(module_name.clone())])
functor!("invalid_module_export"), }
&CompilationError::InvalidModuleResolution(ref module_name) => &CompilationError::InvalidRuleHead => functor!("invalid_head_of_rule"),
functor!( &CompilationError::InvalidUseModuleDecl => functor!("invalid_use_module_declaration"),
"no_such_module", &CompilationError::ParserError(ref err) => functor!(err.as_str()),
[clause_name(module_name.clone())] &CompilationError::UnreadableTerm => functor!("unreadable_term"),
),
&CompilationError::InvalidRuleHead =>
functor!("invalid_head_of_rule"),
&CompilationError::InvalidUseModuleDecl =>
functor!("invalid_use_module_declaration"),
&CompilationError::ParserError(ref err) =>
functor!(err.as_str()),
&CompilationError::UnreadableTerm =>
functor!("unreadable_term"),
} }
} }
} }
@@ -715,16 +623,15 @@ impl EvalError {
pub(super) enum CycleSearchResult { pub(super) enum CycleSearchResult {
EmptyList, EmptyList,
NotList, NotList,
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap. PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length. ProperList(usize), // the list length.
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string. PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
UntouchedList(usize), // the address of an uniterated Addr::Lis(address). UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
} }
impl MachineState { impl MachineState {
// see 8.4.3 of Draft Technical Corrigendum 2. // see 8.4.3 of Draft Technical Corrigendum 2.
pub(super) pub(super) fn check_sort_errors(&self) -> CallResult {
fn check_sort_errors(&self) -> CallResult {
let stub = MachineError::functor_stub(clause_name!("sort"), 2); let stub = MachineError::functor_stub(clause_name!("sort"), 2);
let list = self.store(self.deref(self[temp_v!(1)].clone())); let list = self.store(self.deref(self[temp_v!(1)].clone()));
let sorted = self.store(self.deref(self[temp_v!(2)].clone())); let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
@@ -734,7 +641,9 @@ impl MachineState {
return Err(self.error_form(MachineError::instantiation_error(), stub)) return Err(self.error_form(MachineError::instantiation_error(), stub))
} }
CycleSearchResult::NotList => { CycleSearchResult::NotList => {
return Err(self.error_form(MachineError::type_error(0, ValidType::List, list), stub)) return Err(
self.error_form(MachineError::type_error(0, ValidType::List, list), stub)
)
} }
_ => {} _ => {}
}; };
@@ -766,7 +675,8 @@ impl MachineState {
new_l = l; new_l = l;
} }
HeapCellValue::NamedStr(2, ref name, Some(_)) HeapCellValue::NamedStr(2, ref name, Some(_))
if name.as_str() == "-" => { if name.as_str() == "-" =>
{
break; break;
} }
HeapCellValue::Addr(Addr::HeapCell(_)) => { HeapCellValue::Addr(Addr::HeapCell(_)) => {
@@ -793,11 +703,10 @@ impl MachineState {
} }
// see 8.4.4 of Draft Technical Corrigendum 2. // see 8.4.4 of Draft Technical Corrigendum 2.
pub(super) pub(super) fn check_keysort_errors(&self) -> CallResult {
fn check_keysort_errors(&self) -> CallResult {
let stub = MachineError::functor_stub(clause_name!("keysort"), 2); let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
let pairs = self.store(self.deref(self[temp_v!(1)].clone())); let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
let sorted = self.store(self.deref(self[temp_v!(2)].clone())); let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
match self.detect_cycles(pairs.clone()) { match self.detect_cycles(pairs.clone()) {
@@ -814,8 +723,7 @@ impl MachineState {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn type_error<T: TypeError>(
fn type_error<T: TypeError>(
&self, &self,
valid_type: ValidType, valid_type: ValidType,
culprit: T, culprit: T,
@@ -823,33 +731,25 @@ impl MachineState {
arity: usize, arity: usize,
) -> MachineStub { ) -> MachineStub {
let stub = MachineError::functor_stub(caller, arity); let stub = MachineError::functor_stub(caller, arity);
let err = MachineError::type_error( let err = MachineError::type_error(self.heap.h(), valid_type, culprit);
self.heap.h(),
valid_type,
culprit,
);
return self.error_form(err, stub); return self.error_form(err, stub);
} }
#[inline] #[inline]
pub(crate) pub(crate) fn representation_error(
fn representation_error(
&self, &self,
rep_flag: RepFlag, rep_flag: RepFlag,
caller: ClauseName, caller: ClauseName,
arity: usize, arity: usize,
) -> MachineStub { ) -> MachineStub {
let stub = MachineError::functor_stub(caller, arity); let stub = MachineError::functor_stub(caller, arity);
let err = MachineError::representation_error( let err = MachineError::representation_error(rep_flag);
rep_flag,
);
return self.error_form(err, stub); return self.error_form(err, stub);
} }
pub(super) pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
let location = err.location; let location = err.location;
let err_len = err.len(); let err_len = err.len();
@@ -874,8 +774,7 @@ impl MachineState {
stub stub
} }
pub(super) pub(super) fn throw_exception(&mut self, err: MachineStub) {
fn throw_exception(&mut self, err: MachineStub) {
let h = self.heap.h(); let h = self.heap.h();
self.ball.boundary = 0; self.ball.boundary = 0;

View File

@@ -1,22 +1,23 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use prolog_parser::clause_name;
use crate::clause_types::*; use crate::clause_types::*;
use crate::fixtures::*; use crate::fixtures::*;
use crate::forms::*; use crate::forms::*;
use crate::machine::CompilationTarget; use crate::instructions::*;
use crate::machine::code_repo::CodeRepo; use crate::machine::code_repo::CodeRepo;
use crate::machine::Ball;
use crate::machine::heap::*; use crate::machine::heap::*;
use crate::machine::machine_state::*; use crate::machine::machine_state::*;
use crate::machine::partial_string::*; use crate::machine::partial_string::*;
use crate::machine::raw_block::RawBlockTraits; use crate::machine::raw_block::RawBlockTraits;
use crate::machine::streams::Stream; use crate::machine::streams::Stream;
use crate::machine::term_stream::LoadStatePayload; use crate::machine::term_stream::LoadStatePayload;
use crate::instructions::*; use crate::machine::Ball;
use crate::ordered_float::OrderedFloat; use crate::machine::CompilationTarget;
use crate::rug::{Integer, Rational}; use crate::rug::{Integer, Rational};
use ordered_float::OrderedFloat;
use crate::indexmap::IndexMap; use indexmap::IndexMap;
use std::cell::Cell; use std::cell::Cell;
use std::cmp::Ordering; use std::cmp::Ordering;
@@ -96,20 +97,14 @@ impl Ord for Ref {
fn cmp(&self, other: &Ref) -> Ordering { fn cmp(&self, other: &Ref) -> Ordering {
match (self, other) { match (self, other) {
(Ref::AttrVar(h1), Ref::AttrVar(h2)) (Ref::AttrVar(h1), Ref::AttrVar(h2))
| (Ref::HeapCell(h1), Ref::HeapCell(h2)) | (Ref::HeapCell(h1), Ref::HeapCell(h2))
| (Ref::HeapCell(h1), Ref::AttrVar(h2)) | (Ref::HeapCell(h1), Ref::AttrVar(h2))
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => { | (Ref::AttrVar(h1), Ref::HeapCell(h2)) => h1.cmp(&h2),
h1.cmp(&h2)
}
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => { (Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2)) fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
} }
(Ref::StackCell(..), _) => { (Ref::StackCell(..), _) => Ordering::Greater,
Ordering::Greater (_, Ref::StackCell(..)) => Ordering::Less,
}
(_, Ref::StackCell(..)) => {
Ordering::Less
}
} }
} }
} }
@@ -124,35 +119,23 @@ impl PartialEq<Ref> for Addr {
impl PartialOrd<Ref> for Addr { impl PartialOrd<Ref> for Addr {
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> { fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
match self { match self {
&Addr::StackCell(fr, sc) => { &Addr::StackCell(fr, sc) => match *r {
match *r { Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater),
Ref::AttrVar(_) | Ref::HeapCell(_) => { Ref::StackCell(fr1, sc1) => {
if fr1 < fr || (fr1 == fr && sc1 < sc) {
Some(Ordering::Greater) Some(Ordering::Greater)
} } else if fr1 == fr && sc1 == sc {
Ref::StackCell(fr1, sc1) => { Some(Ordering::Equal)
if fr1 < fr || (fr1 == fr && sc1 < sc) { } else {
Some(Ordering::Greater)
} else if fr1 == fr && sc1 == sc {
Some(Ordering::Equal)
} else {
Some(Ordering::Less)
}
}
}
}
&Addr::HeapCell(h) | &Addr::AttrVar(h) => {
match r {
Ref::StackCell(..) => {
Some(Ordering::Less) Some(Ordering::Less)
} }
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
h.partial_cmp(h1)
}
} }
} },
_ => { &Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
None Ref::StackCell(..) => Some(Ordering::Less),
} Ref::AttrVar(h1) | Ref::HeapCell(h1) => h.partial_cmp(h1),
},
_ => None,
} }
} }
} }
@@ -161,26 +144,21 @@ impl Addr {
#[inline] #[inline]
pub fn is_heap_bound(&self) -> bool { pub fn is_heap_bound(&self) -> bool {
match self { match self {
Addr::Char(_) | Addr::EmptyList | Addr::Char(_)
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Fixnum(_) | | Addr::EmptyList
Addr::Float(_) => { | Addr::CutPoint(_)
false | Addr::Usize(_)
} | Addr::Fixnum(_)
_ => { | Addr::Float(_) => false,
true _ => true,
}
} }
} }
#[inline] #[inline]
pub fn is_ref(&self) -> bool { pub fn is_ref(&self) -> bool {
match self { match self {
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => { Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => true,
true _ => false,
}
_ => {
false
}
} }
} }
@@ -194,92 +172,54 @@ impl Addr {
} }
} }
pub(super) pub(super) fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
match Number::try_from((*self, heap)) { match Number::try_from((*self, heap)) {
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => { Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
Some(TermOrderCategory::Integer) Some(TermOrderCategory::Integer)
} }
Ok(Number::Float(_)) => { Ok(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
Some(TermOrderCategory::FloatingPoint) _ => match self {
} Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
_ => { Some(TermOrderCategory::Variable)
match self {
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
Some(TermOrderCategory::Variable)
}
Addr::Float(_) => {
Some(TermOrderCategory::FloatingPoint)
}
&Addr::Con(h) => {
match &heap[h] {
HeapCellValue::Atom(..) => {
Some(TermOrderCategory::Atom)
}
HeapCellValue::DBRef(_) => {
None
}
_ => {
unreachable!()
}
}
}
Addr::Char(_) | Addr::EmptyList => {
Some(TermOrderCategory::Atom)
}
Addr::Fixnum(_) | Addr::Usize(_) => {
Some(TermOrderCategory::Integer)
}
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
Some(TermOrderCategory::Compound)
}
Addr::CutPoint(_) | Addr::LoadStatePayload(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
None
}
} }
} Addr::Float(_) => Some(TermOrderCategory::FloatingPoint),
&Addr::Con(h) => match &heap[h] {
HeapCellValue::Atom(..) => Some(TermOrderCategory::Atom),
HeapCellValue::DBRef(_) => None,
_ => {
unreachable!()
}
},
Addr::Char(_) | Addr::EmptyList => Some(TermOrderCategory::Atom),
Addr::Fixnum(_) | Addr::Usize(_) => Some(TermOrderCategory::Integer),
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
Some(TermOrderCategory::Compound)
}
Addr::CutPoint(_)
| Addr::LoadStatePayload(_)
| Addr::Stream(_)
| Addr::TcpListener(_) => None,
},
} }
} }
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> { pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
match self { match self {
&Addr::Char(c) => { &Addr::Char(c) => Some(Constant::Char(c)),
Some(Constant::Char(c)) &Addr::Con(h) => match &machine_st.heap[h] {
} &HeapCellValue::Atom(ref name, _) if name.is_char() => {
&Addr::Con(h) => { Some(Constant::Char(name.as_str().chars().next().unwrap()))
match &machine_st.heap[h] {
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
Some(Constant::Char(name.as_str().chars().next().unwrap()))
}
&HeapCellValue::Atom(ref name, _) => {
Some(Constant::Atom(name.clone(), None))
}
&HeapCellValue::Integer(ref n) => {
Some(Constant::Integer(n.clone()))
}
&HeapCellValue::Rational(ref n) => {
Some(Constant::Rational(n.clone()))
}
_ => {
None
}
} }
} &HeapCellValue::Atom(ref name, _) => Some(Constant::Atom(name.clone(), None)),
&Addr::EmptyList => { &HeapCellValue::Integer(ref n) => Some(Constant::Integer(n.clone())),
Some(Constant::EmptyList) &HeapCellValue::Rational(ref n) => Some(Constant::Rational(n.clone())),
} _ => None,
&Addr::Fixnum(n) => { },
Some(Constant::Fixnum(n)) &Addr::EmptyList => Some(Constant::EmptyList),
} &Addr::Fixnum(n) => Some(Constant::Fixnum(n)),
&Addr::Float(f) => { &Addr::Float(f) => Some(Constant::Float(f)),
Some(Constant::Float(f)) &Addr::Usize(n) => Some(Constant::Usize(n)),
} _ => None,
&Addr::Usize(n) => {
Some(Constant::Usize(n))
}
_ => {
None
}
} }
} }
@@ -383,61 +323,37 @@ impl HeapCellValue {
#[inline] #[inline]
pub fn as_addr(&self, focus: usize) -> Addr { pub fn as_addr(&self, focus: usize) -> Addr {
match self { match self {
HeapCellValue::Addr(ref a) => { HeapCellValue::Addr(ref a) => *a,
*a HeapCellValue::Atom(..)
} | HeapCellValue::DBRef(..)
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) | | HeapCellValue::Integer(..)
HeapCellValue::Rational(..) => { | HeapCellValue::Rational(..) => Addr::Con(focus),
Addr::Con(focus) HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(focus),
} HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
HeapCellValue::LoadStatePayload(_) => { HeapCellValue::PartialString(..) => Addr::PStrLocation(focus, 0),
Addr::LoadStatePayload(focus) HeapCellValue::Stream(_) => Addr::Stream(focus),
} HeapCellValue::TcpListener(_) => Addr::TcpListener(focus),
HeapCellValue::NamedStr(_, _, _) => {
Addr::Str(focus)
}
HeapCellValue::PartialString(..) => {
Addr::PStrLocation(focus, 0)
}
HeapCellValue::Stream(_) => {
Addr::Stream(focus)
}
HeapCellValue::TcpListener(_) => {
Addr::TcpListener(focus)
}
} }
} }
#[inline] #[inline]
pub fn context_free_clone(&self) -> HeapCellValue { pub fn context_free_clone(&self) -> HeapCellValue {
match self { match self {
&HeapCellValue::Addr(addr) => { &HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr),
HeapCellValue::Addr(addr) &HeapCellValue::Atom(ref name, ref op) => HeapCellValue::Atom(name.clone(), op.clone()),
} &HeapCellValue::DBRef(ref db_ref) => HeapCellValue::DBRef(db_ref.clone()),
&HeapCellValue::Atom(ref name, ref op) => { &HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
HeapCellValue::Atom(name.clone(), op.clone())
}
&HeapCellValue::DBRef(ref db_ref) => {
HeapCellValue::DBRef(db_ref.clone())
}
&HeapCellValue::Integer(ref n) => {
HeapCellValue::Integer(n.clone())
}
&HeapCellValue::LoadStatePayload(_) => { &HeapCellValue::LoadStatePayload(_) => {
HeapCellValue::Atom(clause_name!("$live_term_stream"), None) HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
} }
&HeapCellValue::NamedStr(arity, ref name, ref op) => { &HeapCellValue::NamedStr(arity, ref name, ref op) => {
HeapCellValue::NamedStr(arity, name.clone(), op.clone()) HeapCellValue::NamedStr(arity, name.clone(), op.clone())
} }
&HeapCellValue::Rational(ref r) => { &HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
HeapCellValue::Rational(r.clone())
}
&HeapCellValue::PartialString(ref pstr, has_tail) => { &HeapCellValue::PartialString(ref pstr, has_tail) => {
HeapCellValue::PartialString(pstr.clone(), has_tail) HeapCellValue::PartialString(pstr.clone(), has_tail)
} }
&HeapCellValue::Stream(ref stream) => { &HeapCellValue::Stream(ref stream) => HeapCellValue::Stream(stream.clone()),
HeapCellValue::Stream(stream.clone())
}
&HeapCellValue::TcpListener(_) => { &HeapCellValue::TcpListener(_) => {
HeapCellValue::Atom(clause_name!("$tcp_listener"), None) HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
} }
@@ -473,8 +389,7 @@ impl Deref for CodeIndex {
impl CodeIndex { impl CodeIndex {
#[inline] #[inline]
pub(super) pub(super) fn new(ptr: IndexPtr) -> Self {
fn new(ptr: IndexPtr) -> Self {
CodeIndex(Rc::new(Cell::new(ptr))) CodeIndex(Rc::new(Cell::new(ptr)))
} }
@@ -482,7 +397,7 @@ impl CodeIndex {
pub fn is_undefined(&self) -> bool { pub fn is_undefined(&self) -> bool {
match self.0.get() { match self.0.get() {
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true, IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
_ => false _ => false,
} }
} }
@@ -536,7 +451,7 @@ pub enum CodePtr {
CallN(usize, LocalCodePtr, bool), // arity, local, last call. CallN(usize, LocalCodePtr, bool), // arity, local, last call.
Local(LocalCodePtr), Local(LocalCodePtr),
// DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer. // DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer. REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir. VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
} }
@@ -544,10 +459,10 @@ impl CodePtr {
pub fn local(&self) -> LocalCodePtr { pub fn local(&self) -> LocalCodePtr {
match self { match self {
&CodePtr::BuiltInClause(_, ref local) &CodePtr::BuiltInClause(_, ref local)
| &CodePtr::CallN(_, ref local, _) | &CodePtr::CallN(_, ref local, _)
| &CodePtr::Local(ref local) => local.clone(), | &CodePtr::Local(ref local) => local.clone(),
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p), &CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
&CodePtr::REPL(_, p) => p // | &CodePtr::DynamicTransaction(_, p) => p, &CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
} }
} }
@@ -566,12 +481,11 @@ pub enum LocalCodePtr {
DirEntry(usize), // offset DirEntry(usize), // offset
Halt, Halt,
IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
// TopLevel(usize, usize), // chunk_num, offset // TopLevel(usize, usize), // chunk_num, offset
} }
impl LocalCodePtr { impl LocalCodePtr {
pub(crate) pub(crate) fn assign_if_local(&mut self, cp: CodePtr) {
fn assign_if_local(&mut self, cp: CodePtr) {
match cp { match cp {
CodePtr::Local(local) => *self = local, CodePtr::Local(local) => *self = local,
_ => {} _ => {}
@@ -579,8 +493,7 @@ impl LocalCodePtr {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn abs_loc(&self) -> usize {
fn abs_loc(&self) -> usize {
match self { match self {
LocalCodePtr::DirEntry(ref p) => *p, LocalCodePtr::DirEntry(ref p) => *p,
LocalCodePtr::IndexingBuf(ref p, ..) => *p, LocalCodePtr::IndexingBuf(ref p, ..) => *p,
@@ -588,35 +501,28 @@ impl LocalCodePtr {
} }
} }
pub(crate) pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) { match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
Some(line) => { Some(line) => match line.as_ref() {
match line.as_ref() { Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => { if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct { return true;
return true;
}
} }
_ => {}
} }
} _ => {}
},
None => {} None => {}
} }
false false
} }
pub(crate) pub(crate) fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
let addr = Addr::HeapCell(heap.h()); let addr = Addr::HeapCell(heap.h());
match self { match self {
LocalCodePtr::DirEntry(p) => { LocalCodePtr::DirEntry(p) => {
heap.append(functor!( heap.append(functor!("dir_entry", [integer(*p)]));
"dir_entry",
[integer(*p)]
));
} }
LocalCodePtr::Halt => { LocalCodePtr::Halt => {
heap.append(functor!("halt")); heap.append(functor!("halt"));
@@ -658,7 +564,7 @@ impl PartialOrd<CodePtr> for CodePtr {
impl PartialOrd<LocalCodePtr> for LocalCodePtr { impl PartialOrd<LocalCodePtr> for LocalCodePtr {
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> { fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
match (self, other) { match (self, other) {
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) | (&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => { (&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
p1.partial_cmp(p2) p1.partial_cmp(p2)
} }
@@ -693,12 +599,9 @@ impl Add<usize> for LocalCodePtr {
#[inline] #[inline]
fn add(self, rhs: usize) -> Self::Output { fn add(self, rhs: usize) -> Self::Output {
match self { match self {
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
LocalCodePtr::DirEntry(p + rhs), LocalCodePtr::Halt => unreachable!(),
LocalCodePtr::Halt => LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
unreachable!(),
LocalCodePtr::IndexingBuf(p, o, i) =>
LocalCodePtr::IndexingBuf(p, o, i + rhs),
} }
} }
} }
@@ -709,12 +612,11 @@ impl Sub<usize> for LocalCodePtr {
#[inline] #[inline]
fn sub(self, rhs: usize) -> Self::Output { fn sub(self, rhs: usize) -> Self::Output {
match self { match self {
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
p.checked_sub(rhs).map(LocalCodePtr::DirEntry), LocalCodePtr::Halt => unreachable!(),
LocalCodePtr::Halt => LocalCodePtr::IndexingBuf(p, o, i) => i
unreachable!(), .checked_sub(rhs)
LocalCodePtr::IndexingBuf(p, o, i) => .map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
i.checked_sub(rhs).map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
} }
} }
} }
@@ -723,15 +625,12 @@ impl SubAssign<usize> for LocalCodePtr {
#[inline] #[inline]
fn sub_assign(&mut self, rhs: usize) { fn sub_assign(&mut self, rhs: usize) {
match self { match self {
LocalCodePtr::DirEntry(ref mut p) => LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
*p -= rhs, LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(),
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) =>
unreachable!(),
} }
} }
} }
impl AddAssign<usize> for LocalCodePtr { impl AddAssign<usize> for LocalCodePtr {
#[inline] #[inline]
fn add_assign(&mut self, rhs: usize) { fn add_assign(&mut self, rhs: usize) {
@@ -749,14 +648,12 @@ impl Add<usize> for CodePtr {
fn add(self, rhs: usize) -> Self::Output { fn add(self, rhs: usize) -> Self::Output {
match self { match self {
p @ CodePtr::REPL(..) | p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
p @ CodePtr::VerifyAttrInterrupt(_) => { // | // |
// p @ CodePtr::DynamicTransaction(..) => { // p @ CodePtr::DynamicTransaction(..) => {
p p
} }
CodePtr::Local(local) => { CodePtr::Local(local) => CodePtr::Local(local + rhs),
CodePtr::Local(local + rhs)
}
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => { CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
CodePtr::Local(local + rhs) CodePtr::Local(local + rhs)
} }
@@ -784,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
} }
} }
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>; pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>; pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
@@ -830,23 +726,17 @@ impl IndexStore {
key: &PredicateKey, key: &PredicateKey,
) -> Option<&mut PredicateSkeleton> { ) -> Option<&mut PredicateSkeleton> {
match (key.0.as_str(), key.1) { match (key.0.as_str(), key.1) {
("term_expansion", 2) => { ("term_expansion", 2) => self.extensible_predicates.get_mut(key),
self.extensible_predicates.get_mut(key) _ => match compilation_target {
} CompilationTarget::User => self.extensible_predicates.get_mut(key),
_ => { CompilationTarget::Module(ref module_name) => {
match compilation_target { if let Some(module) = self.modules.get_mut(module_name) {
CompilationTarget::User => { module.extensible_predicates.get_mut(key)
self.extensible_predicates.get_mut(key) } else {
} None
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get_mut(module_name) {
module.extensible_predicates.get_mut(key)
} else {
None
}
} }
} }
} },
} }
} }
@@ -858,19 +748,17 @@ impl IndexStore {
match (key.0.as_str(), key.1) { match (key.0.as_str(), key.1) {
("term_expansion", 2) => { ("term_expansion", 2) => {
self.extensible_predicates.remove(key); self.extensible_predicates.remove(key);
}, }
_ => { _ => match compilation_target {
match compilation_target { CompilationTarget::User => {
CompilationTarget::User => { self.extensible_predicates.remove(key);
self.extensible_predicates.remove(key); }
} CompilationTarget::Module(ref module_name) => {
CompilationTarget::Module(ref module_name) => { if let Some(module) = self.modules.get_mut(module_name) {
if let Some(module) = self.modules.get_mut(module_name) { module.extensible_predicates.remove(key);
module.extensible_predicates.remove(key);
}
} }
} }
} },
} }
} }
@@ -883,15 +771,9 @@ impl IndexStore {
) -> Option<CodeIndex> { ) -> Option<CodeIndex> {
if module.as_str() == "user" { if module.as_str() == "user" {
match ClauseType::from(name, arity, op_spec) { match ClauseType::from(name, arity, op_spec) {
ClauseType::Named(name, arity, _) => { ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
self.code_dir.get(&(name, arity)).cloned() ClauseType::Op(name, spec, ..) => self.code_dir.get(&(name, spec.arity())).cloned(),
} _ => None,
ClauseType::Op(name, spec, ..) => {
self.code_dir.get(&(name, spec.arity())).cloned()
}
_ => {
None
}
} }
} else { } else {
self.modules.get(&module).and_then(|module| { self.modules.get(&module).and_then(|module| {
@@ -902,9 +784,7 @@ impl IndexStore {
ClauseType::Op(name, spec, ..) => { ClauseType::Op(name, spec, ..) => {
module.code_dir.get(&(name, spec.arity())).cloned() module.code_dir.get(&(name, spec.arity())).cloned()
} }
_ => { _ => None,
None
}
} }
}) })
} }
@@ -917,44 +797,32 @@ impl IndexStore {
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
) -> Option<&Vec<MetaSpec>> { ) -> Option<&Vec<MetaSpec>> {
match compilation_target { match compilation_target {
CompilationTarget::User => { CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
self.meta_predicates.get(&(name, arity)) CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
} Some(ref module) => module
CompilationTarget::Module(ref module_name) => { .meta_predicates
match self.modules.get(module_name) { .get(&(name.clone(), arity))
Some(ref module) => { .or_else(|| self.meta_predicates.get(&(name, arity))),
module.meta_predicates.get(&(name.clone(), arity)) None => self.meta_predicates.get(&(name, arity)),
.or_else(|| { },
self.meta_predicates.get(&(name, arity))
})
}
None => {
self.meta_predicates.get(&(name, arity))
}
}
}
} }
} }
pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool { pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool {
match module_name.as_str() { match module_name.as_str() {
"user" => { "user" => self
self.extensible_predicates.get(&key) .extensible_predicates
.get(&key)
.map(|skeleton| skeleton.is_dynamic)
.unwrap_or(false),
_ => match self.modules.get(&module_name) {
Some(ref module) => module
.extensible_predicates
.get(&key)
.map(|skeleton| skeleton.is_dynamic) .map(|skeleton| skeleton.is_dynamic)
.unwrap_or(false) .unwrap_or(false),
} None => false,
_ => { },
match self.modules.get(&module_name) {
Some(ref module) => {
module.extensible_predicates.get(&key)
.map(|skeleton| skeleton.is_dynamic)
.unwrap_or(false)
}
None => {
false
}
}
}
} }
} }
@@ -963,8 +831,7 @@ impl IndexStore {
IndexStore::default() IndexStore::default()
} }
pub(super) pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
fn get_cleaner_sites(&self) -> (usize, usize) {
let r_w_h = clause_name!("run_cleaners_with_handling"); let r_w_h = clause_name!("run_cleaners_with_handling");
let r_wo_h = clause_name!("run_cleaners_without_handling"); let r_wo_h = clause_name!("run_cleaners_without_handling");
let iso_ext = clause_name!("iso_ext"); let iso_ext = clause_name!("iso_ext");
@@ -996,10 +863,8 @@ pub enum RefOrOwned<'a, T: 'a> {
impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> { impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
&RefOrOwned::Borrowed(ref borrowed) => &RefOrOwned::Borrowed(ref borrowed) => write!(f, "Borrowed({:?})", borrowed),
write!(f, "Borrowed({:?})", borrowed), &RefOrOwned::Owned(ref owned) => write!(f, "Owned({:?})", owned),
&RefOrOwned::Owned(ref owned) =>
write!(f, "Owned({:?})", owned),
} }
} }
} }
@@ -1012,7 +877,9 @@ impl<'a, T> RefOrOwned<'a, T> {
} }
} }
pub fn to_owned(self) -> T where T: Clone pub fn to_owned(self) -> T
where
T: Clone,
{ {
match self { match self {
RefOrOwned::Borrowed(item) => item.clone(), RefOrOwned::Borrowed(item) => item.clone(),

View File

@@ -1,5 +1,6 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*; use prolog_parser::tabled_rc::*;
use prolog_parser::{clause_name, temp_v};
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -14,9 +15,11 @@ use crate::machine::stack::*;
use crate::machine::streams::*; use crate::machine::streams::*;
use crate::rug::Integer; use crate::rug::Integer;
use crate::downcast::Any; use downcast::{
downcast, downcast_methods, downcast_methods_core, downcast_methods_std, impl_downcast, Any,
};
use crate::indexmap::IndexMap; use indexmap::IndexMap;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::convert::TryFrom; use std::convert::TryFrom;
@@ -32,33 +35,26 @@ pub struct Ball {
} }
impl Ball { impl Ball {
pub(super) pub(super) fn new() -> Self {
fn new() -> Self {
Ball { Ball {
boundary: 0, boundary: 0,
stub: Heap::new(), stub: Heap::new(),
} }
} }
pub(super) pub(super) fn reset(&mut self) {
fn reset(&mut self) {
self.boundary = 0; self.boundary = 0;
self.stub.clear(); self.stub.clear();
} }
pub(super) pub(super) fn copy_and_align(&self, h: usize) -> Heap {
fn copy_and_align(&self, h: usize) -> Heap {
let diff = self.boundary as i64 - h as i64; let diff = self.boundary as i64 - h as i64;
let mut stub = Heap::new(); let mut stub = Heap::new();
for heap_value in self.stub.iter_from(0) { for heap_value in self.stub.iter_from(0) {
stub.push(match heap_value { stub.push(match heap_value {
&HeapCellValue::Addr(addr) => { &HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
HeapCellValue::Addr(addr - diff) heap_value => heap_value.context_free_clone(),
}
heap_value => {
heap_value.context_free_clone()
}
}); });
} }
@@ -123,11 +119,7 @@ pub(super) struct CopyBallTerm<'a> {
} }
impl<'a> CopyBallTerm<'a> { impl<'a> CopyBallTerm<'a> {
pub(super) fn new( pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
stack: &'a mut Stack,
heap: &'a mut Heap,
stub: &'a mut Heap,
) -> Self {
let hb = heap.h(); let hb = heap.h();
CopyBallTerm { CopyBallTerm {
@@ -182,12 +174,8 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
let index = h - self.heap_boundary; let index = h - self.heap_boundary;
self.stub[index].as_addr(h) self.stub[index].as_addr(h)
} }
Addr::StackCell(fr, sc) => { Addr::StackCell(fr, sc) => self.stack.index_and_frame(fr)[sc],
self.stack.index_and_frame(fr)[sc] addr => addr,
}
addr => {
addr
}
} }
} }
@@ -226,9 +214,7 @@ impl Index<RegType> for MachineState {
impl IndexMut<RegType> for MachineState { impl IndexMut<RegType> for MachineState {
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output { fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
match reg { match reg {
RegType::Temp(temp) => { RegType::Temp(temp) => &mut self.registers[temp],
&mut self.registers[temp]
}
RegType::Perm(perm) => { RegType::Perm(perm) => {
let e = self.e; let e = self.e;
@@ -255,15 +241,12 @@ pub(super) enum HeapPtr {
impl HeapPtr { impl HeapPtr {
#[inline] #[inline]
pub(super) pub(super) fn read(&self, heap: &Heap) -> Addr {
fn read(&self, heap: &Heap) -> Addr {
match self { match self {
&HeapPtr::HeapCell(h) => { &HeapPtr::HeapCell(h) => Addr::HeapCell(h),
Addr::HeapCell(h)
}
&HeapPtr::PStrChar(h, n) => { &HeapPtr::PStrChar(h, n) => {
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] { if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
if let Some(c) = pstr.range_from(n ..).next() { if let Some(c) = pstr.range_from(n..).next() {
Addr::Char(c) Addr::Char(c)
} else if has_tail { } else if has_tail {
Addr::HeapCell(h + 1) Addr::HeapCell(h + 1)
@@ -274,9 +257,7 @@ impl HeapPtr {
unreachable!() unreachable!()
} }
} }
&HeapPtr::PStrLocation(h, n) => { &HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
Addr::PStrLocation(h, n)
}
} }
} }
} }
@@ -313,16 +294,11 @@ pub struct MachineState {
pub(super) last_call: bool, pub(super) last_call: bool,
pub(crate) heap_locs: HeapVarDict, pub(crate) heap_locs: HeapVarDict,
pub(crate) flags: MachineFlags, pub(crate) flags: MachineFlags,
pub(crate) at_end_of_expansion: bool pub(crate) at_end_of_expansion: bool,
} }
impl MachineState { impl MachineState {
pub(crate) pub(crate) fn read_term(&mut self, mut stream: Stream, indices: &mut IndexStore) -> CallResult {
fn read_term(
&mut self,
mut stream: Stream,
indices: &mut IndexStore,
) -> CallResult {
self.check_stream_properties( self.check_stream_properties(
&mut stream, &mut stream,
StreamType::Text, StreamType::Text,
@@ -342,11 +318,7 @@ impl MachineState {
let mut orig_stream = stream.clone(); let mut orig_stream = stream.clone();
loop { loop {
match self.read( match self.read(stream.clone(), self.atom_tbl.clone(), &indices.op_dir) {
stream.clone(),
self.atom_tbl.clone(),
&indices.op_dir,
) {
Ok(term_write_result) => { Ok(term_write_result) => {
let term = self[temp_v!(2)]; let term = self[temp_v!(2)];
self.unify(Addr::HeapCell(term_write_result.heap_loc), term); self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
@@ -363,7 +335,8 @@ impl MachineState {
let h = self.heap.h(); let h = self.heap.h();
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir); let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec)); self.heap
.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
self.heap.push(HeapCellValue::Atom(var_atom, None)); self.heap.push(HeapCellValue::Atom(var_atom, None));
self.heap.push(HeapCellValue::Addr(binding)); self.heap.push(HeapCellValue::Addr(binding));
@@ -406,8 +379,7 @@ impl MachineState {
} }
let vars_addr = self[temp_v!(4)]; let vars_addr = self[temp_v!(4)];
let vars_offset = let vars_offset = Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
self.unify(vars_offset, vars_addr); self.unify(vars_offset, vars_addr);
@@ -427,7 +399,7 @@ impl MachineState {
self[temp_v!(2)], self[temp_v!(2)],
&mut orig_stream, &mut orig_stream,
clause_name!("read_term"), clause_name!("read_term"),
3 3,
)?; )?;
if orig_stream.options.eof_action == EOFAction::Reset { if orig_stream.options.eof_action == EOFAction::Reset {
@@ -448,12 +420,10 @@ impl MachineState {
} }
} }
pub(crate) pub(crate) fn write_term<'a>(
fn write_term<'a>(
&'a self, &'a self,
op_dir: &'a OpDir, op_dir: &'a OpDir,
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub> ) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub> {
{
let ignore_ops = self.store(self.deref(self[temp_v!(3)])); let ignore_ops = self.store(self.deref(self[temp_v!(3)]));
let numbervars = self.store(self.deref(self[temp_v!(4)])); let numbervars = self.store(self.deref(self[temp_v!(4)]));
let quoted = self.store(self.deref(self[temp_v!(5)])); let quoted = self.store(self.deref(self[temp_v!(5)]));
@@ -462,7 +432,7 @@ impl MachineState {
let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new()); let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
if let &Addr::Con(h) = &ignore_ops { if let &Addr::Con(h) = &ignore_ops {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] { if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.ignore_ops = name.as_str() == "true"; printer.ignore_ops = name.as_str() == "true";
} else { } else {
unreachable!() unreachable!()
@@ -470,7 +440,7 @@ impl MachineState {
} }
if let &Addr::Con(h) = &numbervars { if let &Addr::Con(h) = &numbervars {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] { if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.numbervars = name.as_str() == "true"; printer.numbervars = name.as_str() == "true";
} else { } else {
unreachable!() unreachable!()
@@ -478,7 +448,7 @@ impl MachineState {
} }
if let &Addr::Con(h) = &quoted { if let &Addr::Con(h) = &quoted {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] { if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.quoted = name.as_str() == "true"; printer.quoted = name.as_str() == "true";
} else { } else {
unreachable!() unreachable!()
@@ -514,9 +484,7 @@ impl MachineState {
for addr in addrs { for addr in addrs {
match addr { match addr {
Addr::Str(s) => match &self.heap[s] { Addr::Str(s) => match &self.heap[s] {
&HeapCellValue::NamedStr(2, ref name, _) &HeapCellValue::NamedStr(2, ref name, _) if name.as_str() == "=" => {
if name.as_str() == "=" =>
{
let atom = self.heap[s + 1].as_addr(s + 1); let atom = self.heap[s + 1].as_addr(s + 1);
let var = self.heap[s + 2].as_addr(s + 2); let var = self.heap[s + 2].as_addr(s + 2);
@@ -540,11 +508,9 @@ impl MachineState {
var_names.insert(var, atom); var_names.insert(var, atom);
} }
_ => { _ => {}
}
}, },
_ => { _ => {}
}
} }
} }
@@ -558,8 +524,7 @@ impl MachineState {
Ok(Some(printer)) Ok(Some(printer))
} }
pub(super) pub(super) fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
let stub = MachineError::functor_stub(name.clone(), arity); let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h(); let h = self.heap.h();
let key = ExistenceError::Procedure(name, arity); let key = ExistenceError::Procedure(name, arity);
@@ -568,13 +533,11 @@ impl MachineState {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
HeapPStrIter::new(self, focus) HeapPStrIter::new(self, focus)
} }
pub(super) pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
let mut chars = String::new(); let mut chars = String::new();
let mut iter = addrs.iter(); let mut iter = addrs.iter();
@@ -594,55 +557,46 @@ impl MachineState {
} }
} }
} }
_ => { _ => {}
}
}; };
let h = self.heap.h(); let h = self.heap.h();
return Err( return Err(MachineError::type_error(h, ValidType::Character, addr));
MachineError::type_error(h, ValidType::Character, addr)
);
} }
Ok(chars) Ok(chars)
} }
pub(super) pub(super) fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
let predicate_name = atom_from!(self, self.store(self.deref(name))); let predicate_name = atom_from!(self, self.store(self.deref(name)));
let arity = self.store(self.deref(arity)); let arity = self.store(self.deref(arity));
let arity = let arity = match Number::try_from((arity, &self.heap)) {
match Number::try_from((arity, &self.heap)) { Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => n.to_usize().unwrap(),
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => {
n.to_usize().unwrap(), usize::try_from(n).unwrap()
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => }
usize::try_from(n).unwrap(), _ => unreachable!(),
_ => };
unreachable!()
};
(predicate_name, arity) (predicate_name, arity)
} }
pub(super) pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
self.cp.assign_if_local(self.p.clone() + 1); self.cp.assign_if_local(self.p.clone() + 1);
self.num_of_args = arity; self.num_of_args = arity;
self.b0 = self.b; self.b0 = self.b;
self.p = CodePtr::Local(p); self.p = CodePtr::Local(p);
} }
pub(super) pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
self.num_of_args = arity; self.num_of_args = arity;
self.b0 = self.b; self.b0 = self.b;
self.p = CodePtr::Local(p); self.p = CodePtr::Local(p);
} }
pub(super) pub(super) fn module_lookup(
fn module_lookup(
&mut self, &mut self,
indices: &IndexStore, indices: &IndexStore,
call_policy: &mut Box<dyn CallPolicy>, call_policy: &mut Box<dyn CallPolicy>,
@@ -687,10 +641,15 @@ pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
pub(crate) trait CallPolicy: Any + fmt::Debug { pub(crate) trait CallPolicy: Any + fmt::Debug {
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells; let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 { for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1]; machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
@@ -706,17 +665,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr; machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr); machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b = let attr_var_init_queue_b = machine_st
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b; .stack
let attr_var_init_bindings_b = .index_or_frame(b)
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b; .prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack( machine_st
attr_var_init_queue_b, .attr_var_init
attr_var_init_bindings_b, .backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
);
machine_st.hb = machine_st.heap.h(); machine_st.hb = machine_st.heap.h();
machine_st.p += 1; machine_st.p += 1;
@@ -726,10 +692,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells; let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 { for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1]; machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
@@ -745,14 +716,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr; machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr); machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b = let attr_var_init_queue_b = machine_st
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b; .stack
let attr_var_init_bindings_b = .index_or_frame(b)
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b; .prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b); machine_st
.attr_var_init
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.hb = machine_st.heap.h(); machine_st.hb = machine_st.heap.h();
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset)); machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
@@ -762,10 +743,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult { fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells; let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 { for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1]; machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
@@ -779,17 +765,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr; machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr); machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b = let attr_var_init_queue_b = machine_st
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b; .stack
let attr_var_init_bindings_b = .index_or_frame(b)
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b; .prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack( machine_st
attr_var_init_queue_b, .attr_var_init
attr_var_init_bindings_b, .backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
);
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b; machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
machine_st.stack.truncate(b); machine_st.stack.truncate(b);
@@ -802,10 +795,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult { fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
let b = machine_st.b; let b = machine_st.b;
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells; let n = machine_st
.stack
.index_or_frame(b)
.prelude
.univ_prelude
.num_cells;
for i in 1 .. n + 1 { for i in 1..n + 1 {
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1]; machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
} }
machine_st.num_of_args = n; machine_st.num_of_args = n;
@@ -819,17 +817,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr; machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr); machine_st.trail.truncate(machine_st.tr);
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h); machine_st
.heap
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
let attr_var_init_queue_b = let attr_var_init_queue_b = machine_st
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b; .stack
let attr_var_init_bindings_b = .index_or_frame(b)
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b; .prelude
.attr_var_init_queue_b;
let attr_var_init_bindings_b = machine_st
.stack
.index_or_frame(b)
.prelude
.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack( machine_st
attr_var_init_queue_b, .attr_var_init
attr_var_init_bindings_b, .backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
);
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b; machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
machine_st.stack.truncate(b); machine_st.stack.truncate(b);
@@ -928,13 +933,13 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
Addr::Con(h) if machine_st.heap.atom_at(h) => { Addr::Con(h) if machine_st.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] { if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
match atom.as_str() { match atom.as_str() {
">" | "<" | "=" => { ">" | "<" | "=" => {}
}
_ => { _ => {
let stub = let stub =
MachineError::functor_stub(clause_name!("compare"), 3); MachineError::functor_stub(clause_name!("compare"), 3);
let err = MachineError::domain_error(DomainErrorType::Order, a1); let err =
MachineError::domain_error(DomainErrorType::Order, a1);
return Err(machine_st.error_form(err, stub)); return Err(machine_st.error_form(err, stub));
} }
} }
@@ -948,8 +953,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let err = MachineError::type_error(h, ValidType::Atom, a1); let err = MachineError::type_error(h, ValidType::Atom, a1);
return Err(machine_st.error_form(err, stub)); return Err(machine_st.error_form(err, stub));
} }
_ => { _ => {}
}
} }
let atom = match machine_st.compare_term_test(&a2, &a3) { let atom = match machine_st.compare_term_test(&a2, &a3) {
@@ -998,9 +1002,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let addr = machine_st[temp_v!(1)]; let addr = machine_st[temp_v!(1)];
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl); let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
let atom = machine_st.heap.to_unifiable( let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
HeapCellValue::Atom(eof, None)
);
machine_st.unify(addr, atom); machine_st.unify(addr, atom);
} }
@@ -1056,7 +1058,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let mut list = machine_st.try_from_list(temp_v!(1), stub)?; let mut list = machine_st.try_from_list(temp_v!(1), stub)?;
list.sort_unstable_by(|a1, a2| { list.sort_unstable_by(|a1, a2| {
machine_st.compare_term_test(a1, a2).unwrap_or(Ordering::Less) machine_st
.compare_term_test(a1, a2)
.unwrap_or(Ordering::Less)
}); });
machine_st.term_dedup(&mut list); machine_st.term_dedup(&mut list);
@@ -1081,7 +1085,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
} }
key_pairs.sort_by(|a1, a2| { key_pairs.sort_by(|a1, a2| {
machine_st.compare_term_test(&a1.0, &a2.0).unwrap_or(Ordering::Less) machine_st
.compare_term_test(&a1.0, &a2.0)
.unwrap_or(Ordering::Less)
}); });
let key_pairs = key_pairs.into_iter().map(|kp| kp.1); let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
@@ -1155,11 +1161,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
return Err(machine_st.error_form( return Err(machine_st.error_form(
MachineError::type_error( MachineError::type_error(machine_st.heap.h(), ValidType::Callable, name),
machine_st.heap.h(),
ValidType::Callable,
name
),
stub, stub,
)); ));
} }
@@ -1200,7 +1202,8 @@ impl CallPolicy for CWILCallPolicy {
arity: usize, arity: usize,
idx: &CodeIndex, idx: &CodeIndex,
) -> CallResult { ) -> CallResult {
self.prev_policy.context_call(machine_st, name, arity, idx)?;//, indices)?; self.prev_policy
.context_call(machine_st, name, arity, idx)?; //, indices)?;
self.increment(machine_st) self.increment(machine_st)
} }
@@ -1239,7 +1242,7 @@ impl CallPolicy for CWILCallPolicy {
code_dir, code_dir,
op_dir, op_dir,
current_input_stream, current_input_stream,
current_output_stream current_output_stream,
)?; )?;
self.increment(machine_st) self.increment(machine_st)
@@ -1283,8 +1286,7 @@ pub(crate) struct CWILCallPolicy {
} }
impl CWILCallPolicy { impl CWILCallPolicy {
pub(crate) pub(crate) fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {}); let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
mem::swap(&mut prev_policy, policy); mem::swap(&mut prev_policy, policy);
@@ -1319,8 +1321,7 @@ impl CWILCallPolicy {
Ok(()) Ok(())
} }
pub(crate) pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
limit += &self.count; limit += &self.count;
match self.limits.last().cloned() { match self.limits.last().cloned() {
@@ -1331,8 +1332,7 @@ impl CWILCallPolicy {
&self.count &self.count
} }
pub(crate) pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
fn remove_limit(&mut self, b: usize) -> &Integer {
if let Some((_, bp)) = self.limits.last().cloned() { if let Some((_, bp)) = self.limits.last().cloned() {
if bp == b { if bp == b {
self.limits.pop(); self.limits.pop();
@@ -1342,13 +1342,11 @@ impl CWILCallPolicy {
&self.count &self.count
} }
pub(crate) pub(crate) fn is_empty(&self) -> bool {
fn is_empty(&self) -> bool {
self.limits.is_empty() self.limits.is_empty()
} }
pub(crate) pub(crate) fn into_inner(&mut self) -> Box<dyn CallPolicy> {
fn into_inner(&mut self) -> Box<dyn CallPolicy> {
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {}); let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
mem::swap(&mut self.prev_policy, &mut new_inner); mem::swap(&mut self.prev_policy, &mut new_inner);
new_inner new_inner

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*; use prolog_parser::tabled_rc::*;
use prolog_parser::{clause_name, temp_v};
use lazy_static::lazy_static;
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;
@@ -34,17 +37,18 @@ mod machine_state_impl;
mod system_calls; mod system_calls;
//use crate::machine::attributed_variables::*; //use crate::machine::attributed_variables::*;
use crate::machine::compile::*;
use crate::machine::code_repo::*; use crate::machine::code_repo::*;
use crate::machine::compile::*;
// use crate::machine::loader::*; // use crate::machine::loader::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::machine_state::*; use crate::machine::machine_state::*;
use crate::machine::streams::*; use crate::machine::streams::*;
use crate::indexmap::IndexMap; use indexmap::IndexMap;
//use std::convert::TryFrom; //use std::convert::TryFrom;
use prolog_parser::ast::ClauseName;
use std::fs::File; use std::fs::File;
use std::mem; use std::mem;
use std::path::PathBuf; use std::path::PathBuf;
@@ -162,18 +166,13 @@ impl Machine {
} }
fn load_file(&mut self, path: String, stream: Stream) { fn load_file(&mut self, path: String, stream: Stream) {
self.machine_st[temp_v!(1)] = Addr::Stream( self.machine_st[temp_v!(1)] =
self.machine_st.heap.push(HeapCellValue::Stream( Addr::Stream(self.machine_st.heap.push(HeapCellValue::Stream(stream)));
stream,
))
);
self.machine_st[temp_v!(2)] = Addr::Con( self.machine_st[temp_v!(2)] = Addr::Con(self.machine_st.heap.push(HeapCellValue::Atom(
self.machine_st.heap.push(HeapCellValue::Atom( clause_name!(path, self.machine_st.atom_tbl),
clause_name!(path, self.machine_st.atom_tbl), None,
None, )));
))
);
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2)); self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
} }
@@ -206,11 +205,9 @@ impl Machine {
bootstrapping_compile( bootstrapping_compile(
Stream::from(include_str!("attributed_variables.pl")), Stream::from(include_str!("attributed_variables.pl")),
self, self,
ListingSource::from_file_and_path( ListingSource::from_file_and_path(clause_name!("attributed_variables"), path_buf),
clause_name!("attributed_variables"), )
path_buf, .unwrap();
),
).unwrap();
let mut path_buf = current_dir(); let mut path_buf = current_dir();
path_buf.push("machine/project_attributes.pl"); path_buf.push("machine/project_attributes.pl");
@@ -218,11 +215,9 @@ impl Machine {
bootstrapping_compile( bootstrapping_compile(
Stream::from(include_str!("project_attributes.pl")), Stream::from(include_str!("project_attributes.pl")),
self, self,
ListingSource::from_file_and_path( ListingSource::from_file_and_path(clause_name!("project_attributes"), path_buf),
clause_name!("project_attributes"), )
path_buf, .unwrap();
),
).unwrap();
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) { if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) { if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
@@ -255,12 +250,13 @@ impl Machine {
fn configure_modules(&mut self) { fn configure_modules(&mut self) {
fn update_call_n_indices(loader: &Module, target_module: &mut Module) { fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
for arity in 1 .. 66 { for arity in 1..66 {
let key = (clause_name!("call"), arity); let key = (clause_name!("call"), arity);
match loader.code_dir.get(&key) { match loader.code_dir.get(&key) {
Some(src_code_index) => { Some(src_code_index) => {
let target_code_index = target_module.code_dir let target_code_index = target_module
.code_dir
.entry(key.clone()) .entry(key.clone())
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined)); .or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
@@ -289,10 +285,11 @@ impl Machine {
builtins.module_decl.exports.push(export.clone()); builtins.module_decl.exports.push(export.clone());
} }
for arity in 10 .. 66 { for arity in 10..66 {
builtins.module_decl.exports.push( builtins
ModuleExport::PredicateKey((clause_name!("call"), arity)), .module_decl
); .exports
.push(ModuleExport::PredicateKey((clause_name!("call"), arity)));
} }
} }
@@ -306,9 +303,8 @@ impl Machine {
} }
} }
pub fn new(user_input: Stream, user_output: Stream) -> Self pub fn new(user_input: Stream, user_output: Stream) -> Self {
{ use ref_thread_local::RefThreadLocal;
use crate::ref_thread_local::RefThreadLocal;
let mut wam = Machine { let mut wam = Machine {
machine_st: MachineState::new(), machine_st: MachineState::new(),
@@ -333,16 +329,15 @@ impl Machine {
clause_name!("ops_and_meta_predicates.pl"), clause_name!("ops_and_meta_predicates.pl"),
lib_path.clone(), lib_path.clone(),
), ),
).unwrap(); )
.unwrap();
bootstrapping_compile( bootstrapping_compile(
Stream::from(LIBRARIES.borrow()["builtins"]), Stream::from(LIBRARIES.borrow()["builtins"]),
&mut wam, &mut wam,
ListingSource::from_file_and_path( ListingSource::from_file_and_path(clause_name!("builtins.pl"), lib_path.clone()),
clause_name!("builtins.pl"), )
lib_path.clone(), .unwrap();
),
).unwrap();
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) { if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
load_module( load_module(
@@ -361,11 +356,9 @@ impl Machine {
bootstrapping_compile( bootstrapping_compile(
Stream::from(include_str!("../loader.pl")), Stream::from(include_str!("../loader.pl")),
&mut wam, &mut wam,
ListingSource::from_file_and_path( ListingSource::from_file_and_path(clause_name!("loader.pl"), lib_path.clone()),
clause_name!("loader.pl"), )
lib_path.clone(), .unwrap();
),
).unwrap();
wam.configure_modules(); wam.configure_modules();
@@ -391,25 +384,19 @@ impl Machine {
pub fn configure_streams(&mut self) { pub fn configure_streams(&mut self) {
self.user_input.options.alias = Some(clause_name!("user_input")); self.user_input.options.alias = Some(clause_name!("user_input"));
self.indices.stream_aliases.insert( self.indices
clause_name!("user_input"), .stream_aliases
self.user_input.clone(), .insert(clause_name!("user_input"), self.user_input.clone());
);
self.indices.streams.insert( self.indices.streams.insert(self.user_input.clone());
self.user_input.clone()
);
self.user_output.options.alias = Some(clause_name!("user_output")); self.user_output.options.alias = Some(clause_name!("user_output"));
self.indices.stream_aliases.insert( self.indices
clause_name!("user_output"), .stream_aliases
self.user_output.clone(), .insert(clause_name!("user_output"), self.user_output.clone());
);
self.indices.streams.insert( self.indices.streams.insert(self.user_output.clone());
self.user_output.clone()
);
} }
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) { fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
@@ -508,8 +495,7 @@ impl Machine {
self.machine_st.p = CodePtr::Local(p); self.machine_st.p = CodePtr::Local(p);
} }
pub(super) pub(super) fn run_query(&mut self) {
fn run_query(&mut self) {
while !self.machine_st.p.is_halt() { while !self.machine_st.p.is_halt() {
self.machine_st.query_stepper( self.machine_st.query_stepper(
&mut self.indices, &mut self.indices,
@@ -546,26 +532,22 @@ impl MachineState {
user_output: &mut Stream, user_output: &mut Stream,
) { ) {
match instr { match instr {
&Line::Arithmetic(ref arith_instr) => { &Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
self.execute_arith_instr(arith_instr)
}
&Line::Choice(ref choice_instr) => { &Line::Choice(ref choice_instr) => {
self.execute_choice_instr(choice_instr, &mut policies.call_policy) self.execute_choice_instr(choice_instr, &mut policies.call_policy)
} }
&Line::Cut(ref cut_instr) => { &Line::Cut(ref cut_instr) => {
self.execute_cut_instr(cut_instr, &mut policies.cut_policy) self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
} }
&Line::Control(ref control_instr) => { &Line::Control(ref control_instr) => self.execute_ctrl_instr(
self.execute_ctrl_instr( indices,
indices, code_repo,
code_repo, &mut policies.call_policy,
&mut policies.call_policy, &mut policies.cut_policy,
&mut policies.cut_policy, user_input,
user_input, user_output,
user_output, control_instr,
control_instr, ),
)
}
&Line::Fact(ref fact_instr) => { &Line::Fact(ref fact_instr) => {
self.execute_fact_instr(&fact_instr); self.execute_fact_instr(&fact_instr);
self.p += 1; self.p += 1;
@@ -617,15 +599,13 @@ impl MachineState {
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool { fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
match self.p { match self.p {
CodePtr::Local(LocalCodePtr::DirEntry(p)) | CodePtr::Local(LocalCodePtr::DirEntry(p))
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..)) | CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
if p < code_repo.code.len() => { if p < code_repo.code.len() => {}
}
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => { CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
return false; return false;
} }
_ => { _ => {}
}
} }
true true
@@ -689,13 +669,7 @@ impl MachineState {
user_output: &mut Stream, user_output: &mut Stream,
) { ) {
loop { loop {
self.execute_instr( self.execute_instr(indices, policies, code_repo, user_input, user_output);
indices,
policies,
code_repo,
user_input,
user_output,
);
if self.fail { if self.fail {
self.backtrack(); self.backtrack();

View File

@@ -1,13 +1,14 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::tabled_rc::*; use prolog_parser::tabled_rc::*;
use prolog_parser::{atom, clause_name, rc_atom};
use crate::forms::*; use crate::forms::*;
use crate::iterators::*; use crate::iterators::*;
use crate::machine::*;
use crate::machine::load_state::*; use crate::machine::load_state::*;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
use crate::machine::*;
use crate::indexmap::IndexSet; use indexmap::IndexSet;
use std::cell::Cell; use std::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
@@ -85,28 +86,25 @@ fn setup_op_decl(
to_op_decl(prec, spec.as_str(), name) to_op_decl(prec, spec.as_str(), name)
} }
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError> fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError> {
{
match term { match term {
Term::Clause(_, ref slash, ref mut terms, Some(_)) Term::Clause(_, ref slash, ref mut terms, Some(_))
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 => if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
{ {
let arity = *terms.pop().unwrap(); let arity = *terms.pop().unwrap();
let name = *terms.pop().unwrap(); let name = *terms.pop().unwrap();
let arity = arity let arity = arity
.to_constant() .into_constant()
.and_then(|c| { .and_then(|c| match c {
match c { Constant::Integer(n) => n.to_usize(),
Constant::Integer(n) => n.to_usize(), Constant::Fixnum(n) => usize::try_from(n).ok(),
Constant::Fixnum(n) => usize::try_from(n).ok(), _ => None,
_ => None
}
}) })
.ok_or(CompilationError::InvalidModuleExport)?; .ok_or(CompilationError::InvalidModuleExport)?;
let name = name let name = name
.to_constant() .into_constant()
.and_then(|c| c.to_atom()) .and_then(|c| c.to_atom())
.ok_or(CompilationError::InvalidModuleExport)?; .ok_or(CompilationError::InvalidModuleExport)?;
@@ -116,9 +114,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
Ok((name, arity + 2)) Ok((name, arity + 2))
} }
} }
_ => { _ => Err(CompilationError::InvalidModuleExport),
Err(CompilationError::InvalidModuleExport)
}
} }
} }
@@ -155,10 +151,7 @@ fn setup_module_export(
.or_else(|_| { .or_else(|_| {
if let Term::Clause(_, name, terms, _) = term { if let Term::Clause(_, name, terms, _) = term {
if terms.len() == 3 && name.as_str() == "op" { if terms.len() == 3 && name.as_str() == "op" {
Ok(ModuleExport::OpDecl(setup_op_decl( Ok(ModuleExport::OpDecl(setup_op_decl(terms, atom_tbl)?))
terms,
atom_tbl
)?))
} else { } else {
Err(CompilationError::InvalidModuleDecl) Err(CompilationError::InvalidModuleDecl)
} }
@@ -168,8 +161,7 @@ fn setup_module_export(
}) })
} }
pub(super) pub(super) fn setup_module_export_list(
fn setup_module_export_list(
mut export_list: Term, mut export_list: Term,
atom_tbl: TabledData<Atom>, atom_tbl: TabledData<Atom>,
) -> Result<Vec<ModuleExport>, CompilationError> { ) -> Result<Vec<ModuleExport>, CompilationError> {
@@ -182,7 +174,7 @@ fn setup_module_export_list(
export_list = *t2; export_list = *t2;
} }
if export_list.to_constant() != Some(Constant::EmptyList) { if export_list.into_constant() != Some(Constant::EmptyList) {
Err(CompilationError::InvalidModuleDecl) Err(CompilationError::InvalidModuleDecl)
} else { } else {
Ok(exports) Ok(exports)
@@ -197,7 +189,7 @@ fn setup_module_decl(
let name = terms let name = terms
.pop() .pop()
.unwrap() .unwrap()
.to_constant() .into_constant()
.and_then(|c| c.to_atom()) .and_then(|c| c.to_atom())
.ok_or(CompilationError::InvalidModuleDecl)?; .ok_or(CompilationError::InvalidModuleDecl)?;
@@ -213,13 +205,12 @@ fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, Comp
terms terms
.pop() .pop()
.unwrap() .unwrap()
.to_constant() .into_constant()
.and_then(|c| c.to_atom()) .and_then(|c| c.to_atom())
.map(|c| ModuleSource::Library(c)) .map(|c| ModuleSource::Library(c))
.ok_or(CompilationError::InvalidUseModuleDecl) .ok_or(CompilationError::InvalidUseModuleDecl)
} }
Term::Constant(_, Constant::Atom(ref name, _)) => Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
Ok(ModuleSource::File(name.clone())),
_ => Err(CompilationError::InvalidUseModuleDecl), _ => Err(CompilationError::InvalidUseModuleDecl),
} }
} }
@@ -266,17 +257,13 @@ fn setup_qualified_import(
terms terms
.pop() .pop()
.unwrap() .unwrap()
.to_constant() .into_constant()
.and_then(|c| c.to_atom()) .and_then(|c| c.to_atom())
.map(|c| ModuleSource::Library(c)) .map(|c| ModuleSource::Library(c))
.ok_or(CompilationError::InvalidUseModuleDecl) .ok_or(CompilationError::InvalidUseModuleDecl)
} }
Term::Constant(_, Constant::Atom(ref name, _)) => { Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
Ok(ModuleSource::File(name.clone())) _ => Err(CompilationError::InvalidUseModuleDecl),
}
_ => {
Err(CompilationError::InvalidUseModuleDecl)
}
}?; }?;
let mut exports = IndexSet::new(); let mut exports = IndexSet::new();
@@ -286,7 +273,7 @@ fn setup_qualified_import(
export_list = *t2; export_list = *t2;
} }
if export_list.to_constant() != Some(Constant::EmptyList) { if export_list.into_constant() != Some(Constant::EmptyList) {
Err(CompilationError::InvalidModuleDecl) Err(CompilationError::InvalidModuleDecl)
} else { } else {
Ok((module_src, exports)) Ok((module_src, exports))
@@ -334,8 +321,7 @@ fn setup_qualified_import(
fn setup_meta_predicate<'a>( fn setup_meta_predicate<'a>(
mut terms: Vec<Box<Term>>, mut terms: Vec<Box<Term>>,
load_state: &LoadState<'a>, load_state: &LoadState<'a>,
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> ) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> {
{
fn get_name_and_meta_specs( fn get_name_and_meta_specs(
name: ClauseName, name: ClauseName,
terms: &mut [Box<Term>], terms: &mut [Box<Term>],
@@ -345,26 +331,23 @@ fn setup_meta_predicate<'a>(
for meta_spec in terms.into_iter() { for meta_spec in terms.into_iter() {
match &**meta_spec { match &**meta_spec {
Term::Constant(_, Constant::Atom(meta_spec, _)) => { Term::Constant(_, Constant::Atom(meta_spec, _)) => {
let meta_spec = let meta_spec = match meta_spec.as_str() {
match meta_spec.as_str() { "+" => MetaSpec::Plus,
"+" => MetaSpec::Plus, "-" => MetaSpec::Minus,
"-" => MetaSpec::Minus, "?" => MetaSpec::Either,
"?" => MetaSpec::Either, _ => return Err(CompilationError::InvalidMetaPredicateDecl),
_ => return Err(CompilationError::InvalidMetaPredicateDecl), };
};
meta_specs.push(meta_spec); meta_specs.push(meta_spec);
} }
Term::Constant(_, Constant::Fixnum(n)) => { Term::Constant(_, Constant::Fixnum(n)) => match usize::try_from(*n) {
match usize::try_from(*n) { Ok(n) if n <= MAX_ARITY => {
Ok(n) if n <= MAX_ARITY => { meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
}
_ => {
return Err(CompilationError::InvalidMetaPredicateDecl);
}
} }
} _ => {
return Err(CompilationError::InvalidMetaPredicateDecl);
}
},
_ => { _ => {
return Err(CompilationError::InvalidMetaPredicateDecl); return Err(CompilationError::InvalidMetaPredicateDecl);
} }
@@ -375,42 +358,35 @@ fn setup_meta_predicate<'a>(
} }
match *terms.pop().unwrap() { match *terms.pop().unwrap() {
Term::Clause(_, name, mut terms, _) Term::Clause(_, name, mut terms, _) if name.as_str() == ":" && terms.len() == 2 => {
if name.as_str() == ":" && terms.len() == 2 => { let spec = *terms.pop().unwrap();
let spec = *terms.pop().unwrap(); let module_name = *terms.pop().unwrap();
let module_name = *terms.pop().unwrap();
match module_name { match module_name {
Term::Constant(_, Constant::Atom(module_name, _)) => { Term::Constant(_, Constant::Atom(module_name, _)) => match spec {
match spec { Term::Clause(_, name, mut terms, _) => {
Term::Clause(_, name, mut terms, _) => { let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
let (name, meta_specs) =
get_name_and_meta_specs(name, &mut terms)?;
Ok((module_name, name, meta_specs)) Ok((module_name, name, meta_specs))
}
_ => {
Err(CompilationError::InvalidMetaPredicateDecl)
}
}
} }
_ => { _ => Err(CompilationError::InvalidMetaPredicateDecl),
Err(CompilationError::InvalidMetaPredicateDecl) },
} _ => Err(CompilationError::InvalidMetaPredicateDecl),
}
} }
}
Term::Clause(_, name, mut terms, _) => { Term::Clause(_, name, mut terms, _) => {
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?; let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
Ok((load_state.compilation_target.module_name(), name, meta_specs)) Ok((
} load_state.compilation_target.module_name(),
_ => { name,
Err(CompilationError::InvalidMetaPredicateDecl) meta_specs,
))
} }
_ => Err(CompilationError::InvalidMetaPredicateDecl),
} }
} }
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError> fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError> {
{
let mut clauses = vec![]; let mut clauses = vec![];
while let Some(tl) = tls.pop_front() { while let Some(tl) = tls.pop_front() {
@@ -432,9 +408,7 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationEr
let clause = PredicateClause::Rule(rule); let clause = PredicateClause::Rule(rule);
clauses.push(clause); clauses.push(clause);
} }
TopLevel::Predicate(predicate) => { TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()),
clauses.extend(predicate.into_iter())
}
_ => { _ => {
tls.push_front(tl); tls.push_front(tl);
break; break;
@@ -506,8 +480,8 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
conq_terms.push_front(Term::Constant( conq_terms.push_front(Term::Constant(
Cell::default(), Cell::default(),
Constant::Atom(clause_name!("blocked_!"), None)) Constant::Atom(clause_name!("blocked_!"), None),
); ));
while let Some(term) = pre_cut_terms.pop_back() { while let Some(term) = pre_cut_terms.pop_back() {
conq_terms.push_front(term); conq_terms.push_front(term);
@@ -531,38 +505,29 @@ fn setup_declaration<'a>(
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone(); let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
match term { match term {
Term::Clause(_, name, mut terms, _) => Term::Clause(_, name, mut terms, _) => match (name.as_str(), terms.len()) {
match (name.as_str(), terms.len()) { ("dynamic", 1) => {
("dynamic", 1) => { let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?; Ok(Declaration::Dynamic(name, arity))
Ok(Declaration::Dynamic(name, arity)) }
} ("module", 2) => Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
("module", 2) => ("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)), ("non_counted_backtracking", 1) => {
("op", 3) => let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)), Ok(Declaration::NonCountedBacktracking(name, arity))
("non_counted_backtracking", 1) => { }
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?; ("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
Ok(Declaration::NonCountedBacktracking(name, arity)) ("use_module", 2) => {
} let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
("use_module", 1) => { Ok(Declaration::UseQualifiedModule(name, exports))
Ok(Declaration::UseModule(setup_use_module_decl(terms)?)) }
} ("meta_predicate", 1) => {
("use_module", 2) => { let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
let (name, exports) = setup_qualified_import(terms, atom_tbl)?; Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
Ok(Declaration::UseQualifiedModule(name, exports)) }
} _ => Err(CompilationError::InconsistentEntry),
("meta_predicate", 1) => { },
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?; _ => Err(CompilationError::InconsistentEntry),
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
}
_ => {
Err(CompilationError::InconsistentEntry)
}
},
_ => {
Err(CompilationError::InconsistentEntry)
}
} }
} }
@@ -596,8 +561,7 @@ pub(crate) struct Preprocessor {
} }
impl Preprocessor { impl Preprocessor {
pub(super) pub(super) fn new(flags: MachineFlags) -> Self {
fn new(flags: MachineFlags) -> Self {
Preprocessor { Preprocessor {
flags, flags,
queue: VecDeque::new(), queue: VecDeque::new(),
@@ -606,12 +570,8 @@ impl Preprocessor {
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> { fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
match term { match term {
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => { Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(term),
Ok(term) _ => Err(CompilationError::InadmissibleFact),
}
_ => {
Err(CompilationError::InadmissibleFact)
}
} }
} }
@@ -712,109 +672,97 @@ impl Preprocessor {
Ok(clause_to_query_term(load_state, name, vec![], fixity)) Ok(clause_to_query_term(load_state, name, vec![], fixity))
} }
} }
Term::Constant(_, Constant::Char('!')) => { Term::Constant(_, Constant::Char('!')) => Ok(QueryTerm::BlockedCut),
Ok(QueryTerm::BlockedCut)
}
Term::Var(_, ref v) if v.as_str() == "!" => { Term::Var(_, ref v) if v.as_str() == "!" => {
Ok(QueryTerm::UnblockedCut(Cell::default())) Ok(QueryTerm::UnblockedCut(Cell::default()))
} }
Term::Clause(r, name, mut terms, fixity) => { Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) {
match (name.as_str(), terms.len()) { (";", 2) => {
(";", 2) => { let term = Term::Clause(r, name.clone(), terms, fixity);
let term = Term::Clause(r, name.clone(), terms, fixity);
let (stub, clauses) = self.fabricate_disjunct(term); let (stub, clauses) = self.fabricate_disjunct(term);
self.queue.push_back(clauses); self.queue.push_back(clauses);
Ok(QueryTerm::Jump(stub)) Ok(QueryTerm::Jump(stub))
} }
("->", 2) => { ("->", 2) => {
let conq = *terms.pop().unwrap(); let conq = *terms.pop().unwrap();
let prec = *terms.pop().unwrap(); let prec = *terms.pop().unwrap();
let (stub, clauses) = self.fabricate_if_then(prec, conq); let (stub, clauses) = self.fabricate_if_then(prec, conq);
self.queue.push_back(clauses); self.queue.push_back(clauses);
Ok(QueryTerm::Jump(stub)) Ok(QueryTerm::Jump(stub))
} }
("\\+", 1) => { ("\\+", 1) => {
terms.push(Box::new(Term::Constant( terms.push(Box::new(Term::Constant(
Cell::default(), Cell::default(),
Constant::Atom(clause_name!("$fail"), None) Constant::Atom(clause_name!("$fail"), None),
))); )));
let conq = Term::Constant( let conq =
Cell::default(), Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
Constant::Atom(clause_name!("true"), None)
);
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None); let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
let terms = vec![Box::new(prec), Box::new(conq)]; let terms = vec![Box::new(prec), Box::new(conq)];
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None); let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
let (stub, clauses) = self.fabricate_disjunct(term); let (stub, clauses) = self.fabricate_disjunct(term);
debug_assert!(clauses.len() > 0); debug_assert!(clauses.len() > 0);
self.queue.push_back(clauses); self.queue.push_back(clauses);
Ok(QueryTerm::Jump(stub)) Ok(QueryTerm::Jump(stub))
} }
("$get_level", 1) => { ("$get_level", 1) => {
if let Term::Var(_, ref var) = *terms[0] { if let Term::Var(_, ref var) = *terms[0] {
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone())) Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
} else { } else {
Err(CompilationError::InadmissibleQueryTerm) Err(CompilationError::InadmissibleQueryTerm)
}
}
(":", 2) => {
let predicate_name = *terms.pop().unwrap();
let module_name = *terms.pop().unwrap();
match (module_name, predicate_name) {
(Term::Constant(_, Constant::Atom(module_name, _)),
Term::Constant(_, Constant::Atom(predicate_name, fixity))) => {
Ok(qualified_clause_to_query_term(
load_state,
module_name,
predicate_name,
vec![],
fixity,
))
}
(Term::Constant(_, Constant::Atom(module_name, _)),
Term::Clause(_, name, terms, fixity)) => {
Ok(qualified_clause_to_query_term(
load_state,
module_name,
name,
terms,
fixity,
))
}
(module_name, predicate_name) => {
terms.push(Box::new(module_name));
terms.push(Box::new(predicate_name));
Ok(clause_to_query_term(load_state, name, terms, fixity))
}
}
}
_ => {
Ok(clause_to_query_term(load_state, name, terms, fixity))
} }
} }
} (":", 2) => {
Term::Var(..) => { let predicate_name = *terms.pop().unwrap();
Ok(QueryTerm::Clause( let module_name = *terms.pop().unwrap();
Cell::default(),
ClauseType::CallN, match (module_name, predicate_name) {
vec![Box::new(term)], (
false, Term::Constant(_, Constant::Atom(module_name, _)),
)) Term::Constant(_, Constant::Atom(predicate_name, fixity)),
} ) => Ok(qualified_clause_to_query_term(
_ => { load_state,
Err(CompilationError::InadmissibleQueryTerm) module_name,
} predicate_name,
vec![],
fixity,
)),
(
Term::Constant(_, Constant::Atom(module_name, _)),
Term::Clause(_, name, terms, fixity),
) => Ok(qualified_clause_to_query_term(
load_state,
module_name,
name,
terms,
fixity,
)),
(module_name, predicate_name) => {
terms.push(Box::new(module_name));
terms.push(Box::new(predicate_name));
Ok(clause_to_query_term(load_state, name, terms, fixity))
}
}
}
_ => Ok(clause_to_query_term(load_state, name, terms, fixity)),
},
Term::Var(..) => Ok(QueryTerm::Clause(
Cell::default(),
ClauseType::CallN,
vec![Box::new(term)],
false,
)),
_ => Err(CompilationError::InadmissibleQueryTerm),
} }
} }
@@ -835,9 +783,7 @@ impl Preprocessor {
self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity)) self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity))
} }
} }
_ => { _ => self.to_query_term(load_state, term),
self.to_query_term(load_state, term)
}
} }
} }
@@ -884,30 +830,23 @@ impl Preprocessor {
mut terms: Vec<Box<Term>>, mut terms: Vec<Box<Term>>,
cut_context: CutContext, cut_context: CutContext,
) -> Result<Rule, CompilationError> { ) -> Result<Rule, CompilationError> {
let post_head_terms: Vec<_> = terms.drain(1 ..).collect(); let post_head_terms: Vec<_> = terms.drain(1..).collect();
let mut query_terms = let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?;
self.setup_query(load_state, post_head_terms, cut_context)?;
let clauses = query_terms.drain(1 ..).collect(); let clauses = query_terms.drain(1..).collect();
let qt = query_terms.pop().unwrap(); let qt = query_terms.pop().unwrap();
match *terms.pop().unwrap() { match *terms.pop().unwrap() {
Term::Clause(_, name, terms, _) => { Term::Clause(_, name, terms, _) => Ok(Rule {
Ok(Rule { head: (name, terms, qt),
head: (name, terms, qt), clauses,
clauses, }),
}) Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule {
} head: (name, vec![], qt),
Term::Constant(_, Constant::Atom(name, _)) => { clauses,
Ok(Rule { }),
head: (name, vec![], qt), _ => Err(CompilationError::InvalidRuleHead),
clauses,
})
}
_ => {
Err(CompilationError::InvalidRuleHead)
}
} }
} }
@@ -917,11 +856,14 @@ impl Preprocessor {
terms: Vec<Box<Term>>, terms: Vec<Box<Term>>,
cut_context: CutContext, cut_context: CutContext,
) -> Result<TopLevel, CompilationError> { ) -> Result<TopLevel, CompilationError> {
Ok(TopLevel::Query(self.setup_query(load_state, terms, cut_context)?)) Ok(TopLevel::Query(self.setup_query(
load_state,
terms,
cut_context,
)?))
} }
pub(super) pub(super) fn try_term_to_tl<'a>(
fn try_term_to_tl<'a>(
&mut self, &mut self,
load_state: &mut LoadState<'a>, load_state: &mut LoadState<'a>,
term: Term, term: Term,
@@ -944,9 +886,7 @@ impl Preprocessor {
Ok(TopLevel::Fact(self.setup_fact(term)?)) Ok(TopLevel::Fact(self.setup_fact(term)?))
} }
} }
term => { term => Ok(TopLevel::Fact(self.setup_fact(term)?)),
Ok(TopLevel::Fact(self.setup_fact(term)?))
}
} }
} }
@@ -965,21 +905,18 @@ impl Preprocessor {
Ok(results) Ok(results)
} }
pub(super) pub(super) fn parse_queue<'a>(
fn parse_queue<'a>(
&mut self, &mut self,
load_state: &mut LoadState<'a>, load_state: &mut LoadState<'a>,
) -> Result<VecDeque<TopLevel>, CompilationError> { ) -> Result<VecDeque<TopLevel>, CompilationError> {
let mut queue = VecDeque::new(); let mut queue = VecDeque::new();
while let Some(terms) = self.queue.pop_front() { while let Some(terms) = self.queue.pop_front() {
let clauses = merge_clauses( let clauses = merge_clauses(&mut self.try_terms_to_tls(
&mut self.try_terms_to_tls( load_state,
load_state, terms,
terms, CutContext::HasCutVariable,
CutContext::HasCutVariable, )?)?;
)?
)?;
queue.push_back(clauses); queue.push_back(clauses);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,16 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::parser::*; use prolog_parser::parser::*;
use crate::machine::*;
use crate::machine::machine_errors::CompilationError; use crate::machine::machine_errors::CompilationError;
use crate::machine::preprocessor::*; use crate::machine::preprocessor::*;
use crate::machine::*;
use indexmap::IndexSet; use indexmap::IndexSet;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt; use std::fmt;
pub(crate) trait TermStream : Sized { pub(crate) trait TermStream: Sized {
type Evacuable; type Evacuable;
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError>; fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError>;
@@ -27,15 +27,17 @@ pub(super) struct BootstrappingTermStream<'a> {
impl<'a> BootstrappingTermStream<'a> { impl<'a> BootstrappingTermStream<'a> {
#[inline] #[inline]
pub(super) pub(super) fn from_prolog_stream(
fn from_prolog_stream(
stream: &'a mut PrologStream, stream: &'a mut PrologStream,
atom_tbl: TabledData<Atom>, atom_tbl: TabledData<Atom>,
flags: MachineFlags, flags: MachineFlags,
listing_src: ListingSource, listing_src: ListingSource,
) -> Self { ) -> Self {
let parser = Parser::new(stream, atom_tbl, flags); let parser = Parser::new(stream, atom_tbl, flags);
Self { parser, listing_src } Self {
parser,
listing_src,
}
} }
} }
@@ -45,13 +47,14 @@ impl<'a> TermStream for BootstrappingTermStream<'a> {
#[inline] #[inline]
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError> { fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError> {
self.parser.reset(); self.parser.reset();
self.parser.read_term(op_dir) self.parser
.read_term(op_dir)
.map_err(CompilationError::from) .map_err(CompilationError::from)
} }
#[inline] #[inline]
fn eof(&mut self) -> Result<bool, CompilationError> { fn eof(&mut self) -> Result<bool, CompilationError> {
self.parser.devour_whitespace()?; // eliminate dangling comments before checking for EOF. self.parser.devour_whitespace()?; // eliminate dangling comments before checking for EOF.
Ok(self.parser.eof()?) Ok(self.parser.eof()?)
} }
@@ -65,9 +68,10 @@ impl<'a> TermStream for BootstrappingTermStream<'a> {
loader.compile_and_submit()?; loader.compile_and_submit()?;
} }
loader.load_state.retraction_info.reset( loader
loader.load_state.wam.code_repo.code.len(), .load_state
); .retraction_info
.reset(loader.load_state.wam.code_repo.code.len());
loader.load_state.remove_module_op_exports(); loader.load_state.remove_module_op_exports();
@@ -82,8 +86,7 @@ pub struct LiveTermStream {
impl LiveTermStream { impl LiveTermStream {
#[inline] #[inline]
pub(super) pub(super) fn new(listing_src: ListingSource) -> Self {
fn new(listing_src: ListingSource) -> Self {
Self { Self {
term_queue: VecDeque::new(), term_queue: VecDeque::new(),
listing_src, listing_src,
@@ -109,8 +112,7 @@ impl fmt::Debug for LoadStatePayload {
} }
impl LoadStatePayload { impl LoadStatePayload {
pub(super) pub(super) fn new(wam: &Machine) -> Self {
fn new(wam: &Machine) -> Self {
Self { Self {
term_stream: LiveTermStream::new(ListingSource::User), term_stream: LiveTermStream::new(ListingSource::User),
compilation_target: CompilationTarget::default(), compilation_target: CompilationTarget::default(),

View File

@@ -1,43 +1,14 @@
extern crate blake2;
extern crate chrono;
extern crate cpu_time;
extern crate crossterm;
extern crate divrem;
#[macro_use]
extern crate downcast;
extern crate git_version;
extern crate hostname;
extern crate indexmap;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate native_tls;
extern crate nix;
extern crate openssl;
extern crate ordered_float;
#[macro_use]
extern crate prolog_parser_rebis;
#[macro_use]
extern crate ref_thread_local;
extern crate ring;
extern crate ripemd160;
#[cfg(feature = "rug")]
extern crate rug;
#[cfg(feature = "num-rug-adapter")] #[cfg(feature = "num-rug-adapter")]
extern crate num_rug_adapter as rug; use num_rug_adapter as rug;
extern crate rustyline; #[cfg(feature = "rug")]
extern crate sha3; use rug;
extern crate unicode_reader;
use crate::nix::sys::signal;
#[macro_use] #[macro_use]
mod macros; mod macros;
mod allocator; mod allocator;
mod arithmetic; mod arithmetic;
mod machine;
mod codegen;
mod clause_types; mod clause_types;
mod codegen;
mod debray_allocator; mod debray_allocator;
mod fixtures; mod fixtures;
mod forms; mod forms;
@@ -46,17 +17,19 @@ mod heap_print;
mod indexing; mod indexing;
mod instructions; mod instructions;
mod iterators; mod iterators;
mod machine;
mod read; mod read;
mod targets; mod targets;
mod write; mod write;
use machine::*;
use machine::streams::*; use machine::streams::*;
use machine::*;
use read::*; use read::*;
use nix::sys::signal;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
extern fn handle_sigint(signal: libc::c_int) { extern "C" fn handle_sigint(signal: libc::c_int) {
let signal = signal::Signal::from_c_int(signal).unwrap(); let signal = signal::Signal::from_c_int(signal).unwrap();
if signal == signal::Signal::SIGINT { if signal == signal::Signal::SIGINT {
INTERRUPT.store(true, Ordering::Relaxed); INTERRUPT.store(true, Ordering::Relaxed);

View File

@@ -1,6 +1,6 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::prolog_parser_rebis::parser::*; use prolog_parser::parser::*;
use crate::prolog_parser_rebis::tabled_rc::TabledData; use prolog_parser::tabled_rc::TabledData;
use crate::forms::*; use crate::forms::*;
use crate::iterators::*; use crate::iterators::*;
@@ -16,8 +16,8 @@ pub type PrologStream = ParsingStream<Stream>;
pub mod readline { pub mod readline {
use crate::machine::streams::Stream; use crate::machine::streams::Stream;
use crate::rustyline::error::ReadlineError; use rustyline::error::ReadlineError;
use crate::rustyline::{Cmd, Config, Editor, KeyEvent}; use rustyline::{Cmd, Config, Editor, KeyEvent};
use std::io::{Cursor, Error, ErrorKind, Read}; use std::io::{Cursor, Error, ErrorKind, Read};
static mut PROMPT: bool = false; static mut PROMPT: bool = false;
@@ -33,7 +33,11 @@ pub mod readline {
#[inline] #[inline]
fn get_prompt() -> &'static str { fn get_prompt() -> &'static str {
unsafe { unsafe {
if PROMPT { "?- " } else { "" } if PROMPT {
"?- "
} else {
""
}
} }
} }
@@ -61,7 +65,10 @@ pub mod readline {
} }
rl.bind_sequence(KeyEvent::from('\t'), Cmd::Insert(1, "\t".to_string())); rl.bind_sequence(KeyEvent::from('\t'), Cmd::Insert(1, "\t".to_string()));
ReadlineStream { rl, pending_input: Cursor::new(pending_input) } ReadlineStream {
rl,
pending_input: Cursor::new(pending_input),
}
} }
#[inline] #[inline]
@@ -89,12 +96,8 @@ pub mod readline {
self.pending_input.read(buf) self.pending_input.read(buf)
} }
Err(ReadlineError::Eof) => { Err(ReadlineError::Eof) => Ok(0),
Ok(0) Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
}
Err(e) => {
Err(Error::new(ErrorKind::InvalidInput, e))
}
} }
} }
@@ -121,21 +124,15 @@ pub mod readline {
Some(b) => { Some(b) => {
return Ok(b); return Ok(b);
} }
None => { None => match self.call_readline(&mut []) {
match self.call_readline(&mut []) { Err(e) => {
Err(e) => { return Err(e);
return Err(e);
}
Ok(0) => {
return Err(Error::new(
ErrorKind::UnexpectedEof,
"end of file",
));
}
_ => {
}
} }
} Ok(0) => {
return Err(Error::new(ErrorKind::UnexpectedEof, "end of file"));
}
_ => {}
},
} }
} }
} }
@@ -148,21 +145,15 @@ pub mod readline {
Some(c) => { Some(c) => {
return Ok(c); return Ok(c);
} }
None => { None => match self.call_readline(&mut []) {
match self.call_readline(&mut []) { Err(e) => {
Err(e) => { return Err(e);
return Err(e);
}
Ok(0) => {
return Err(Error::new(
ErrorKind::UnexpectedEof,
"end of file",
));
}
_ => {
}
} }
} Ok(0) => {
return Err(Error::new(ErrorKind::UnexpectedEof, "end of file"));
}
_ => {}
},
} }
} }
} }
@@ -171,12 +162,8 @@ pub mod readline {
impl Read for ReadlineStream { impl Read for ReadlineStream {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match self.pending_input.read(buf) { match self.pending_input.read(buf) {
Ok(0) => { Ok(0) => self.call_readline(buf),
self.call_readline(buf) result => result,
}
result => {
result
}
} }
} }
} }
@@ -214,8 +201,7 @@ impl MachineState {
} }
#[inline] #[inline]
pub(crate) pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
let term_writer = TermWriter::new(machine_st); let term_writer = TermWriter::new(machine_st);
term_writer.write_term_to_heap(term) term_writer.write_term_to_heap(term)
} }
@@ -246,8 +232,7 @@ impl<'a> TermWriter<'a> {
#[inline] #[inline]
fn modify_head_of_queue(&mut self, term: &TermRef<'a>, h: usize) { fn modify_head_of_queue(&mut self, term: &TermRef<'a>, h: usize) {
if let Some((arity, site_h)) = self.queue.pop_front() { if let Some((arity, site_h)) = self.queue.pop_front() {
self.machine_st.heap[site_h] = self.machine_st.heap[site_h] = HeapCellValue::Addr(self.term_as_addr(term, h));
HeapCellValue::Addr(self.term_as_addr(term, h));
if arity > 1 { if arity > 1 {
self.queue.push_front((arity - 1, site_h + 1)); self.queue.push_front((arity - 1, site_h + 1));
@@ -258,26 +243,18 @@ impl<'a> TermWriter<'a> {
#[inline] #[inline]
fn push_stub_addr(&mut self) { fn push_stub_addr(&mut self) {
let h = self.machine_st.heap.h(); let h = self.machine_st.heap.h();
self.machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); self.machine_st
.heap
.push(HeapCellValue::Addr(Addr::HeapCell(h)));
} }
fn term_as_addr(&mut self, term: &TermRef<'a>, h: usize) -> Addr { fn term_as_addr(&mut self, term: &TermRef<'a>, h: usize) -> Addr {
match term { match term {
&TermRef::AnonVar(_) | &TermRef::Var(..) => { &TermRef::AnonVar(_) | &TermRef::Var(..) => Addr::HeapCell(h),
Addr::HeapCell(h) &TermRef::Cons(..) => Addr::HeapCell(h),
} &TermRef::Constant(_, _, c) => self.machine_st.heap.put_constant(c.clone()),
&TermRef::Cons(..) => { &TermRef::Clause(..) => Addr::Str(h),
Addr::HeapCell(h) &TermRef::PartialString(..) => Addr::PStrLocation(h, 0),
}
&TermRef::Constant(_, _, c) => {
self.machine_st.heap.put_constant(c.clone())
}
&TermRef::Clause(..) => {
Addr::Str(h)
}
&TermRef::PartialString(..) => {
Addr::PStrLocation(h, 0)
}
} }
} }
@@ -290,7 +267,9 @@ impl<'a> TermWriter<'a> {
match &term { match &term {
&TermRef::Cons(lvl, ..) => { &TermRef::Cons(lvl, ..) => {
self.queue.push_back((2, h + 1)); self.queue.push_back((2, h + 1));
self.machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1))); self.machine_st
.heap
.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
self.push_stub_addr(); self.push_stub_addr();
self.push_stub_addr(); self.push_stub_addr();
@@ -359,13 +338,15 @@ impl<'a> TermWriter<'a> {
continue; continue;
} }
_ => { _ => {}
}
}; };
self.modify_head_of_queue(&term, h); self.modify_head_of_queue(&term, h);
} }
TermWriteResult { heap_loc, var_dict: self.var_dict } TermWriteResult {
heap_loc,
var_dict: self.var_dict,
}
} }
} }

View File

@@ -1,4 +1,4 @@
use crate::prolog_parser_rebis::ast::*; use prolog_parser::ast::*;
use crate::clause_types::*; use crate::clause_types::*;
use crate::forms::*; use crate::forms::*;