Merge branch 'rebis-dev' of https://github.com/mthom/scryer-prolog into rebis-dev

This commit is contained in:
Mark Thom
2021-02-09 14:30:09 -07:00
51 changed files with 8274 additions and 9141 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;
@@ -150,11 +151,6 @@ impl InlinedClauseType {
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum SystemClauseType { pub enum SystemClauseType {
// AbolishClause,
// AbolishModuleClause,
// AssertDynamicPredicateToBack,
// AssertDynamicPredicateToFront,
// AtEndOfExpansion,
AtomChars, AtomChars,
AtomCodes, AtomCodes,
AtomLength, AtomLength,
@@ -189,8 +185,6 @@ pub enum SystemClauseType {
DynamicModuleResolution(usize), DynamicModuleResolution(usize),
EnqueueAttributeGoal, EnqueueAttributeGoal,
EnqueueAttributedVar, EnqueueAttributedVar,
// ExpandGoal,
// ExpandTerm,
FetchGlobalVar, FetchGlobalVar,
FetchGlobalVarWithOffset, FetchGlobalVarWithOffset,
FirstStream, FirstStream,
@@ -207,16 +201,13 @@ pub enum SystemClauseType {
GetAttrVarQueueDelimiter, GetAttrVarQueueDelimiter,
GetAttrVarQueueBeyond, GetAttrVarQueueBeyond,
GetBValue, GetBValue,
// GetClause,
GetContinuationChunk, GetContinuationChunk,
// GetModuleClause,
GetNextDBRef, GetNextDBRef,
GetNextOpDBRef, GetNextOpDBRef,
IsPartialString, IsPartialString,
LookupDBRef, LookupDBRef,
LookupOpDBRef, LookupOpDBRef,
Halt, Halt,
// ModuleHeadIsDynamic,
GetLiftedHeapFromOffset, GetLiftedHeapFromOffset,
GetLiftedHeapFromOffsetDiff, GetLiftedHeapFromOffsetDiff,
GetSCCCleaner, GetSCCCleaner,
@@ -225,10 +216,7 @@ pub enum SystemClauseType {
InstallInferenceCounter, InstallInferenceCounter,
LiftedHeapLength, LiftedHeapLength,
LoadLibraryAsStream, LoadLibraryAsStream,
// ModuleAssertDynamicPredicateToFront,
// ModuleAssertDynamicPredicateToBack,
ModuleExists, ModuleExists,
// ModuleRetractClause,
NextEP, NextEP,
NoSuchPredicate, NoSuchPredicate,
NumberToChars, NumberToChars,
@@ -254,7 +242,6 @@ pub enum SystemClauseType {
ResetContinuationMarker, ResetContinuationMarker,
ResetGlobalVarAtKey, ResetGlobalVarAtKey,
ResetGlobalVarAtOffset, ResetGlobalVarAtOffset,
// RetractClause,
RestoreCutPolicy, RestoreCutPolicy,
SetCutPoint(RegType), SetCutPoint(RegType),
SetInput, SetInput,
@@ -324,11 +311,6 @@ pub enum SystemClauseType {
impl SystemClauseType { impl SystemClauseType {
pub fn name(&self) -> ClauseName { pub fn name(&self) -> ClauseName {
match self { match self {
// &SystemClauseType::AbolishClause => clause_name!("$abolish_clause"),
// &SystemClauseType::AbolishModuleClause => clause_name!("$abolish_module_clause"),
// &SystemClauseType::AssertDynamicPredicateToBack => clause_name!("$assertz"),
// &SystemClauseType::AssertDynamicPredicateToFront => clause_name!("$asserta"),
// &SystemClauseType::AtEndOfExpansion => clause_name!("$at_end_of_expansion"),
&SystemClauseType::AtomChars => clause_name!("$atom_chars"), &SystemClauseType::AtomChars => clause_name!("$atom_chars"),
&SystemClauseType::AtomCodes => clause_name!("$atom_codes"), &SystemClauseType::AtomCodes => clause_name!("$atom_codes"),
&SystemClauseType::AtomLength => clause_name!("$atom_length"), &SystemClauseType::AtomLength => clause_name!("$atom_length"),
@@ -341,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"),
@@ -356,52 +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::UserAsserta) => }
clause_name!("$asserta"), &SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
&SystemClauseType::REPL(REPLCodePtr::UserAssertz) => clause_name!("$push_load_state_payload")
clause_name!("$assertz"), }
&SystemClauseType::REPL(REPLCodePtr::UserRetract) => &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::CompilePendingPredicates) => }
clause_name!("$compile_pending_predicates"), &SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => {
clause_name!("$prolog_lc_stream")
}
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
clause_name!("$cpp_meta_predicate_property")
}
&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"),
@@ -410,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"),
@@ -437,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"),
@@ -468,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"),
@@ -520,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"),
@@ -534,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"),
@@ -555,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"),
@@ -569,21 +578,21 @@ 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", 2) => Some(SystemClauseType::AbolishClause), ("$abolish_clause", 3) => 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) => }
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)), ("$add_goal_expansion_clause", 4) => {
("$add_term_expansion_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)), }
// ("$at_end_of_expansion", 0) => Some(SystemClauseType::AtEndOfExpansion), ("$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),
// ("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause), // ("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause),
("$bind_from_register", 2) => Some(SystemClauseType::BindFromRegister), ("$bind_from_register", 2) => Some(SystemClauseType::BindFromRegister),
// ("$module_asserta", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToFront),
// ("$module_assertz", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToBack),
("$call_continuation", 1) => Some(SystemClauseType::CallContinuation), ("$call_continuation", 1) => Some(SystemClauseType::CallContinuation),
("$char_code", 2) => Some(SystemClauseType::CharCode), ("$char_code", 2) => Some(SystemClauseType::CharCode),
("$char_type", 2) => Some(SystemClauseType::CharType), ("$char_type", 2) => Some(SystemClauseType::CharType),
@@ -616,10 +625,10 @@ impl SystemClauseType {
("$peek_char", 2) => Some(SystemClauseType::PeekChar), ("$peek_char", 2) => Some(SystemClauseType::PeekChar),
("$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),
// ("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
// ("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
("$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),
@@ -628,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)
@@ -649,8 +650,6 @@ impl SystemClauseType {
} }
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList), ("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
("$get_b_value", 1) => Some(SystemClauseType::GetBValue), ("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
// ("$get_clause", 2) => Some(SystemClauseType::GetClause),
// ("$get_module_clause", 3) => Some(SystemClauseType::GetModuleClause),
("$get_lh_from_offset", 2) => Some(SystemClauseType::GetLiftedHeapFromOffset), ("$get_lh_from_offset", 2) => Some(SystemClauseType::GetLiftedHeapFromOffset),
("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff), ("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes), ("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
@@ -664,8 +663,6 @@ impl SystemClauseType {
("$cpu_now", 1) => Some(SystemClauseType::CpuNow), ("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
("$current_time", 1) => Some(SystemClauseType::CurrentTime), ("$current_time", 1) => Some(SystemClauseType::CurrentTime),
("$module_exists", 1) => Some(SystemClauseType::ModuleExists), ("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
// ("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
// ("$module_head_is_dynamic", 2) => Some(SystemClauseType::ModuleHeadIsDynamic),
("$no_such_predicate", 2) => Some(SystemClauseType::NoSuchPredicate), ("$no_such_predicate", 2) => Some(SystemClauseType::NoSuchPredicate),
("$number_to_chars", 2) => Some(SystemClauseType::NumberToChars), ("$number_to_chars", 2) => Some(SystemClauseType::NumberToChars),
("$number_to_codes", 2) => Some(SystemClauseType::NumberToCodes), ("$number_to_codes", 2) => Some(SystemClauseType::NumberToCodes),
@@ -700,7 +697,6 @@ impl SystemClauseType {
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker), ("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey), ("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset), ("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
// ("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr), ("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
("$set_ball", 1) => Some(SystemClauseType::SetBall), ("$set_ball", 1) => Some(SystemClauseType::SetBall),
("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))), ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
@@ -713,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),
@@ -730,15 +728,21 @@ 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))
("$asserta", 4) => Some(SystemClauseType::REPL(REPLCodePtr::UserAsserta)), }
("$assertz", 4) => Some(SystemClauseType::REPL(REPLCodePtr::UserAssertz)), ("$push_load_state_payload", 1) => {
("$retract_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UserRetract)), Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
}
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
("$variant", 2) => Some(SystemClauseType::Variant), ("$variant", 2) => Some(SystemClauseType::Variant),
("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions), ("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions),
("$write_term", 7) => Some(SystemClauseType::WriteTerm), ("$write_term", 7) => Some(SystemClauseType::WriteTerm),
@@ -764,16 +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))
("$compile_pending_predicates", 1) => Some(SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates)), }
("$prolog_lc_stream", 1) => {
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,
} }
} }
@@ -852,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,
} }
} }
@@ -863,7 +889,7 @@ impl ClauseType {
pub fn name(&self) -> ClauseName { pub fn name(&self) -> ClauseName {
match self { match self {
&ClauseType::BuiltIn(ref built_in) => built_in.name(), &ClauseType::BuiltIn(ref built_in) => built_in.name(),
&ClauseType::CallN => clause_name!("call"), &ClauseType::CallN => clause_name!("$call"),
&ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()), &ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()),
&ClauseType::Op(ref name, ..) => name.clone(), &ClauseType::Op(ref name, ..) => name.clone(),
&ClauseType::Named(ref name, ..) => name.clone(), &ClauseType::Named(ref name, ..) => name.clone(),
@@ -882,7 +908,7 @@ impl ClauseType {
.unwrap_or_else(|| { .unwrap_or_else(|| {
if let Some(spec) = spec { if let Some(spec) = spec {
ClauseType::Op(name, spec, CodeIndex::default()) ClauseType::Op(name, spec, CodeIndex::default())
} else if name.as_str() == "call" { } else if name.as_str() == "$call" {
ClauseType::CallN ClauseType::CallN
} else { } else {
ClauseType::Named(name, arity, CodeIndex::default()) ClauseType::Named(name, arity, CodeIndex::default())

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 => {}
}
} }
} }
} }
@@ -755,5 +711,21 @@ impl PredicateSkeleton {
clauses: self.clauses, clauses: self.clauses,
} }
} }
*/ */
pub fn target_pos_of_clause_clause_loc(
&self,
clause_clause_loc: usize,
clause_assert_margin: usize,
) -> usize {
let search_result = self.clause_clause_locs[0..clause_assert_margin]
.binary_search_by(|loc| clause_clause_loc.cmp(&loc));
search_result.unwrap_or_else(|_| {
self.clause_clause_locs[clause_assert_margin..]
.binary_search_by(|loc| loc.cmp(&clause_clause_loc))
.unwrap()
+ clause_assert_margin
})
}
} }

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)));

View File

@@ -4,9 +4,10 @@
abolish/1, asserta/1, assertz/1, abolish/1, asserta/1, assertz/1,
at_end_of_stream/0, at_end_of_stream/1, at_end_of_stream/0, at_end_of_stream/1,
atom_chars/2, atom_codes/2, atom_concat/3, atom_chars/2, atom_codes/2, atom_concat/3,
atom_length/2, bagof/3, catch/3, char_code/2, atom_length/2, bagof/3, call/1, call/2, call/3,
clause/2, close/1, close/2, current_input/1, call/4, call/5, call/6, call/7, call/8, call/9,
current_output/1, current_op/3, catch/3, char_code/2, clause/2, close/1, close/2,
current_input/1, current_output/1, current_op/3,
current_predicate/1, current_prolog_flag/2, current_predicate/1, current_prolog_flag/2,
fail/0, false/0, findall/3, findall/4, fail/0, false/0, findall/3, findall/4,
flush_output/0, flush_output/1, get_byte/1, flush_output/0, flush_output/1, get_byte/1,
@@ -38,6 +39,30 @@ true.
false :- '$fail'. false :- '$fail'.
% These are stub versions of call/{1-9} defined for bootstrapping.
% Once Scryer is bootstrapped, each is replaced with a version that
% uses expand_goal to pass the expanded goal along to '$call'.
call(G) :- '$call'(G).
call(G, A) :- '$call'(G, A).
call(G, A, B) :- '$call'(G, A, B).
call(G, A, B, C) :- '$call'(G, A, B, C).
call(G, A, B, C, D) :- '$call'(G, A, B, C, D).
call(G, A, B, C, D, E) :- '$call'(G, A, B, C, D, E).
call(G, A, B, C, D, E, F) :- '$call'(G, A, B, C, D, E, F).
call(G, A, B, C, D, E, F, G) :- '$call'(G, A, B, C, D, E, F, G).
call(G, A, B, C, D, E, F, G, H) :- '$call'(G, A, B, C, D, E, F, G, H).
Module : Predicate :- Module : Predicate :-
( atom(Module) -> ( atom(Module) ->
'$module_call'(Module, Predicate) '$module_call'(Module, Predicate)
@@ -209,6 +234,8 @@ G1 -> G2 :-
). ).
:-non_counted_backtracking call_or_cut/3.
call_or_cut(G, B, ErrorPI) :- call_or_cut(G, B, ErrorPI) :-
( '$call_with_default_policy'(var(G)) -> ( '$call_with_default_policy'(var(G)) ->
throw(error(instantiation_error, ErrorPI)) throw(error(instantiation_error, ErrorPI))
@@ -216,55 +243,71 @@ call_or_cut(G, B, ErrorPI) :-
). ).
call_or_cut(!, B) :- :- non_counted_backtracking call_or_cut/2.
call_or_cut(M:G, B) :-
!,
( nonvar(G),
'$call_with_default_policy'(call_or_cut_interp(G, B)) ->
true
; call(M:G)
).
call_or_cut(G, B) :-
( '$call_with_default_policy'(call_or_cut_interp(G, B)) ->
true
; call(G)
).
:- non_counted_backtracking call_or_cut_interp/2.
call_or_cut_interp(!, B) :-
'$set_cp_by_default'(B). '$set_cp_by_default'(B).
call_or_cut((G1, G2), B) :- call_or_cut_interp((G1, G2), B) :-
!,
'$call_with_default_policy'(','(G1, G2, B)). '$call_with_default_policy'(','(G1, G2, B)).
call_or_cut((G1 ; G2), B) :- call_or_cut_interp((G1 ; G2), B) :-
!,
'$call_with_default_policy'(';'(G1, G2, B)). '$call_with_default_policy'(';'(G1, G2, B)).
call_or_cut((G1 -> G2), B) :- call_or_cut_interp((G1 -> G2), B) :-
!,
'$call_with_default_policy'(->(G1, G2, B)). '$call_with_default_policy'(->(G1, G2, B)).
call_or_cut(G, _) :-
'$call_with_default_policy'(G).
:- non_counted_backtracking (',')/3. :- non_counted_backtracking (',')/3.
','((G1, G2), G3, B) :-
','(M:G1, G2, B) :-
!, !,
'$call_with_default_policy'(','(G1, G2, B)), ( nonvar(G1),
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)). '$call_with_default_policy'(',-interp'(G1, G2, B)) ->
','((G1; G2), G3, B) :- true
!, ; call(M:G1),
'$call_with_default_policy'(';'(G1, G2, B)), '$call_with_default_policy'(call_or_cut(G2, B, (',')/2))
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)). ).
','((G1 -> G2), G3, B) :-
!,
'$call_with_default_policy'(->(G1, G2, B)),
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
','(G1, G2, B) :- ','(G1, G2, B) :-
'$call_with_default_policy'(call_or_cut(G1, B, (',')/2)), '$call_with_default_policy'(call_or_cut(G1, B, (',')/2)),
'$call_with_default_policy'(call_or_cut(G2, B, (',')/2)). '$call_with_default_policy'(call_or_cut(G2, B, (',')/2)).
:- non_counted_backtracking (',-interp')/3.
',-interp'((G1, G2), G3, B) :-
'$call_with_default_policy'(','(G1, G2, B)),
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
',-interp'((G1; G2), G3, B) :-
'$call_with_default_policy'(';'(G1, G2, B)),
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
',-interp'((G1 -> G2), G3, B) :-
'$call_with_default_policy'(->(G1, G2, B)),
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
:- non_counted_backtracking (;)/3. :- non_counted_backtracking (;)/3.
';'((G1, G2), G3, B) :-
';'(M:G1, G2, B) :-
!, !,
( '$call_with_default_policy'(','(G1, G2, B)) ( nonvar(G1),
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2)) '$call_with_default_policy'(';-interp'(G1, G2, B)) ->
). true
';'((G1; G2), G3, B) :- ; call(M:G1)
!, ; '$call_with_default_policy'(call_or_cut(G2, B, (;)/2))
( '$call_with_default_policy'(';'(G1, G2, B))
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
).
';'((G1 -> G2), G3, B) :-
!,
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2)) ->
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
). ).
';'(G1, G2, B) :- ';'(G1, G2, B) :-
( '$call_with_default_policy'(call_or_cut(G1, B, (;)/2)) ( '$call_with_default_policy'(call_or_cut(G1, B, (;)/2))
@@ -272,26 +315,54 @@ call_or_cut(G, _) :-
). ).
:- non_counted_backtracking ';-interp'/3.
';-interp'((G1, G2), G3, B) :-
( '$call_with_default_policy'(','(G1, G2, B))
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
).
';-interp'((G1; G2), G3, B) :-
( '$call_with_default_policy'(';'(G1, G2, B))
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
).
';-interp'((G1 -> G2), G3, B) :-
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2)) ->
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
).
:- non_counted_backtracking (->)/3. :- non_counted_backtracking (->)/3.
->((G1, G2), G3, B) :-
->(M:G1, G2, B) :-
!, !,
( nonvar(G1),
'$call_with_default_policy'('->-interp'(G1, G2, B)) ->
true
; call(M:G1) ->
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
).
->(G1, G2, B) :-
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2)) ->
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
).
:- non_counted_backtracking '->-interp'/3.
'->-interp'((G1, G2), G3, B) :-
( '$call_with_default_policy'(','(G1, G2, B)) -> ( '$call_with_default_policy'(','(G1, G2, B)) ->
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2)) '$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
). ).
->((G1 ; G2), G3, B) :- '->-interp'((G1 ; G2), G3, B) :-
!,
( '$call_with_default_policy'(';'(G1, G2, B)) -> ( '$call_with_default_policy'(';'(G1, G2, B)) ->
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2)) '$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
). ).
->((G1 -> G2), G3, B) :- '->-interp'((G1 -> G2), G3, B) :-
!,
( '$call_with_default_policy'(->(G1, G2, B)) -> ( '$call_with_default_policy'(->(G1, G2, B)) ->
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2)) '$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
). ).
->(G1, G2, B) :-
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2))
-> '$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
).
% univ. % univ.
@@ -640,8 +711,11 @@ iterate_variants([V-Solution|GroupSolutions], V, Solution) :-
iterate_variants([_|GroupSolutions], Ws, Solution) :- iterate_variants([_|GroupSolutions], Ws, Solution) :-
iterate_variants(GroupSolutions, Ws, Solution). iterate_variants(GroupSolutions, Ws, Solution).
rightmost_power(Term, FinalTerm, Xs) :- rightmost_power(Term, FinalTerm, Xs) :-
( Term = X ^ Y ( ( Term = X ^ Y
; Term = _ : X ^ Y
)
-> ( var(Y) -> FinalTerm = Y, Xs = [X] -> ( var(Y) -> FinalTerm = Y, Xs = [X]
; Xs = [X | Xss], rightmost_power(Y, FinalTerm, Xss) ; Xs = [X | Xss], rightmost_power(Y, FinalTerm, Xss)
) )
@@ -649,11 +723,11 @@ rightmost_power(Term, FinalTerm, Xs) :-
). ).
% :- meta_predicate findall_with_existential(?, 0, ?, ?, ?).
findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses) :- findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses) :-
( nonvar(Goal), ( nonvar(Goal),
Goal = _ ^ _ -> ( Goal = _ ^ _
; Goal = _ : (_ ^ _)
) ->
rightmost_power(Goal, Goal1, ExistentialVars0), rightmost_power(Goal, Goal1, ExistentialVars0),
term_variables(ExistentialVars0, ExistentialVars), term_variables(ExistentialVars0, ExistentialVars),
sort(Witnesses0, Witnesses1), sort(Witnesses0, Witnesses1),
@@ -714,13 +788,16 @@ setof(Template, Goal, Solution) :-
). ).
'$module_clause'(H, B, Module) :- '$module_clause'(H, B, Module) :-
( var(H) -> throw(error(instantiation_error, clause/2)) ( var(H) ->
throw(error(instantiation_error, clause/2))
; functor(H, Name, Arity) -> ; functor(H, Name, Arity) ->
( Name == '.' -> ( Name == '.' ->
throw(error(type_error(callable, H), clause/2)) throw(error(type_error(callable, H), clause/2))
; '$no_such_predicate'(Module, H) ->
'$fail'
; '$head_is_dynamic'(Module, H) -> ; '$head_is_dynamic'(Module, H) ->
'$clause_body_is_valid'(B), '$clause_body_is_valid'(B),
Module:'$clause'(H, B) %%TODO: how do we show this exists? Module:'$clause'(H, B)
; throw(error(permission_error(access, private_procedure, Name/Arity), ; throw(error(permission_error(access, private_procedure, Name/Arity),
clause/2)) clause/2))
) )
@@ -728,8 +805,6 @@ setof(Template, Goal, Solution) :-
). ).
:- dynamic('$clause'/2).
clause(H, B) :- clause(H, B) :-
( var(H) -> ( var(H) ->
throw(error(instantiation_error, clause/2)) throw(error(instantiation_error, clause/2))
@@ -753,24 +828,19 @@ clause(H, B) :-
; throw(error(type_error(callable, H), clause/2)) ; throw(error(type_error(callable, H), clause/2))
). ).
call_module_asserta(Head, Body, Name, Arity, Module) :- call_asserta(Head, Body, Name, Arity, Module) :-
'$clause_body_is_valid'(Body), '$clause_body_is_valid'(Body),
functor(VarHead, Name, Arity), functor(_, Name, Arity),
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses), '$asserta'(Head, Body, Name, Arity, Module).
'$module_asserta'((Head :- Body), Clauses, Name, Arity, Module).
call_asserta(Head, Body, Name, Arity) :-
'$clause_body_is_valid'(Body),
functor(VarHead, Name, Arity),
'$asserta'(Head, Body, Name, Arity).
module_asserta_clause(Head, Body, Module) :- module_asserta_clause(Head, Body, Module) :-
( var(Head) -> throw(error(instantiation_error, asserta/1)) ( var(Head) ->
throw(error(instantiation_error, asserta/1))
; functor(Head, Name, Arity), ; functor(Head, Name, Arity),
atom(Name), atom(Name),
Name \== '.' -> Name \== '.' ->
( '$module_head_is_dynamic'(Head, Module) -> ( '$head_is_dynamic'(Module, Head) ->
call_module_asserta(Head, Body, Name, Arity, Module) call_asserta(Head, Body, Name, Arity, Module)
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1)) ; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
) )
; throw(error(type_error(callable, Head), asserta/1)) ; throw(error(type_error(callable, Head), asserta/1))
@@ -787,9 +857,9 @@ asserta_clause(Head, Body) :-
arg(2, Head, F), arg(2, Head, F),
module_asserta_clause(F, Body, Module) module_asserta_clause(F, Body, Module)
; '$no_such_predicate'(user, Head) -> ; '$no_such_predicate'(user, Head) ->
call_asserta(Head, Body, Name, Arity) call_asserta(Head, Body, Name, Arity, user)
; '$head_is_dynamic'(user, Head) -> ; '$head_is_dynamic'(user, Head) ->
call_asserta(Head, Body, Name, Arity) call_asserta(Head, Body, Name, Arity, user)
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1)) ; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
) )
; throw(error(type_error(callable, Head), asserta/1)) ; throw(error(type_error(callable, Head), asserta/1))
@@ -798,36 +868,33 @@ asserta_clause(Head, Body) :-
asserta(Clause) :- asserta(Clause) :-
( Clause \= (_ :- _) -> ( Clause \= (_ :- _) ->
Head = Clause, Head = Clause,
Body = true, asserta_clause(Head, Body) Body = true,
asserta_clause(Head, Body)
; Clause = (Head :- Body) -> ; Clause = (Head :- Body) ->
asserta_clause(Head, Body) asserta_clause(Head, Body)
). ).
% NOT MODIFIED.
call_module_assertz(Head, Body, Name, Arity, Module) :-
'$clause_body_is_valid'(Body),
functor(VarHead, Name, Arity),
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses),
'$module_assertz'((Head :- Body), Clauses, Name, Arity, Module).
module_assertz_clause(Head, Body, Module) :- module_assertz_clause(Head, Body, Module) :-
( var(Head) -> ( var(Head) ->
throw(error(instantiation_error, assertz/1)) throw(error(instantiation_error, assertz/1))
; functor(Head, Name, Arity), ; functor(Head, Name, Arity),
atom(Name), atom(Name),
Name \== '.' -> Name \== '.' ->
( '$head_is_dynamic'(Module, Head) -> ( '$no_such_predicate'(Module, Head) ->
call_module_assertz(Head, Body, Name, Arity, Module) call_assertz(Head, Body, Name, Arity, Module)
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1)) ; '$head_is_dynamic'(Module, Head) ->
call_assertz(Head, Body, Name, Arity, Module)
; throw(error(permission_error(modify, static_procedure, Name/Arity),
assertz/1))
) )
; throw(error(type_error(callable, Head), assertz/1)) ; throw(error(type_error(callable, Head), assertz/1))
). ).
% MODIFIED.
call_assertz(Head, Body, Name, Arity) :- call_assertz(Head, Body, Name, Arity, Module) :-
'$clause_body_is_valid'(Body), '$clause_body_is_valid'(Body),
functor(VarHead, Name, Arity), functor(_, Name, Arity),
'$assertz'(Head, Body, Name, Arity). '$assertz'(Head, Body, Name, Arity, Module).
assertz_clause(Head, Body) :- assertz_clause(Head, Body) :-
( var(Head) -> ( var(Head) ->
@@ -835,16 +902,17 @@ assertz_clause(Head, Body) :-
; functor(Head, Name, Arity), ; functor(Head, Name, Arity),
atom(Name), atom(Name),
Name \== '.' -> Name \== '.' ->
( Name == (:), ( Name == (:),
Arity =:= 2 -> Arity =:= 2 ->
arg(1, Head, Module), arg(1, Head, Module),
arg(2, Head, F), arg(2, Head, F),
module_assertz_clause(F, Body, Module) module_assertz_clause(F, Body, Module)
; '$no_such_predicate'(user, Head) -> ; '$no_such_predicate'(user, Head) ->
call_assertz(Head, Body, Name, Arity) call_assertz(Head, Body, Name, Arity, user)
; '$head_is_dynamic'(user, Head) -> ; '$head_is_dynamic'(user, Head) ->
call_assertz(Head, Body, Name, Arity) call_assertz(Head, Body, Name, Arity, user)
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1)) ; throw(error(permission_error(modify, static_procedure, Name/Arity),
assertz/1))
) )
; throw(error(type_error(callable, Head), assertz/1)) ; throw(error(type_error(callable, Head), assertz/1))
). ).
@@ -861,18 +929,18 @@ assertz(Clause) :-
module_retract_clauses([Clause|Clauses0], Head, Body, Name, Arity, Module) :- module_retract_clauses([Clause|Clauses0], Head, Body, Name, Arity, Module) :-
functor(VarHead, Name, Arity), functor(VarHead, Name, Arity),
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses1), findall((VarHead :- VarBody), Module:'$clause'(VarHead, VarBody), Clauses1),
first_match_index(Clauses1, (Head :- Body), 0, N), first_match_index(Clauses1, (Head :- Body), 0, N),
( Clauses0 == [] -> ! ( Clauses0 == [] -> !
; true ; true
), ),
'$module_retract_clause'(Name, Arity, N, Clauses1, Module). '$retract_clause'(Name, Arity, N, Module).
module_retract_clauses([_|Clauses0], Head, Body, Name, Arity, Module) :- module_retract_clauses([_|Clauses0], Head, Body, Name, Arity, Module) :-
module_retract_clauses(Clauses0, Head, Body, Name, Arity, Module). module_retract_clauses(Clauses0, Head, Body, Name, Arity, Module).
call_module_retract(Head, Body, Name, Arity, Module) :- call_module_retract(Head, Body, Name, Arity, Module) :-
findall((Head :- Body), builtins:clause(Module:Head, Body), Clauses), findall((Head :- Body), Module:'$clause'(Head, Body), Clauses),
module_retract_clauses(Clauses, Head, Body, Name, Arity, Module). module_retract_clauses(Clauses, Head, Body, Name, Arity, Module).
retract_module_clause(Head, Body, Module) :- retract_module_clause(Head, Body, Module) :-
@@ -881,9 +949,12 @@ retract_module_clause(Head, Body, Module) :-
; functor(Head, Name, Arity), ; functor(Head, Name, Arity),
atom(Name), atom(Name),
Name \== '.' -> Name \== '.' ->
( '$module_head_is_dynamic'(Head, Module) -> ( '$head_is_dynamic'(Module, Head) ->
call_module_retract(Head, Body, Name, Arity, Module) ( Module == user ->
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1)) call_retract(Head, Body, Name, Arity)
; call_module_retract(Head, Body, Name, Arity, Module)
)
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
) )
; throw(error(type_error(callable, Head), retract/1)) ; throw(error(type_error(callable, Head), retract/1))
). ).
@@ -904,7 +975,7 @@ retract_clauses([Clause | Clauses0], Head, Body, Name, Arity) :-
( Clauses0 == [] -> ! ( Clauses0 == [] -> !
; true ; true
), ),
'$retract_clause'(Name, Arity, N). '$retract_clause'(Name, Arity, N, user).
retract_clauses([_ | Clauses0], Head, Body, Name, Arity) :- retract_clauses([_ | Clauses0], Head, Body, Name, Arity) :-
retract_clauses(Clauses0, Head, Body, Name, Arity). retract_clauses(Clauses0, Head, Body, Name, Arity).
@@ -919,16 +990,16 @@ retract_clause(Head, Body) :-
; functor(Head, Name, Arity), ; functor(Head, Name, Arity),
atom(Name), atom(Name),
Name \== '.' -> Name \== '.' ->
( Name == (:), ( Name == (:),
Arity =:= 2 -> Arity =:= 2 ->
arg(1, Head, Module), arg(1, Head, Module),
arg(2, Head, F), arg(2, Head, F),
retract_module_clause(F, Body, Module) retract_module_clause(F, Body, Module)
; '$head_is_dynamic'(user, Head) -> ; '$head_is_dynamic'(user, Head) ->
call_retract(Head, Body, Name, Arity) call_retract(Head, Body, Name, Arity)
; '$no_such_predicate'(user, Head) -> ; '$no_such_predicate'(user, Head) ->
'$fail' '$fail'
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1)) ; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
) )
; throw(error(type_error(callable, Head), retract/1)) ; throw(error(type_error(callable, Head), retract/1))
). ).
@@ -950,21 +1021,21 @@ module_abolish(Pred, Module) :-
( var(Name) -> ( var(Name) ->
throw(error(instantiation_error, abolish/1)) throw(error(instantiation_error, abolish/1))
; integer(Arity) -> ; integer(Arity) ->
( \+ atom(Name) -> ( \+ atom(Name) ->
throw(error(type_error(atom, Name), abolish/1)) throw(error(type_error(atom, Name), abolish/1))
; Arity < 0 -> ; Arity < 0 ->
throw(error(domain_error(not_less_than_zero, Arity), abolish/1)) throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
; max_arity(N), Arity > N -> ; max_arity(N), Arity > N ->
throw(error(representation_error(max_arity), abolish/1)) throw(error(representation_error(max_arity), abolish/1))
; functor(Head, Name, Arity) -> ; functor(Head, Name, Arity) ->
( '$module_head_is_dynamic'(Head, Module) -> ( '$head_is_dynamic'(Module, Head) ->
'$abolish_module_clause'(Name, Arity, Module) '$abolish_clause'(Module, Name, Arity)
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1)) ; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
) )
) )
; throw(error(type_error(integer, Arity), abolish/1)) ; throw(error(type_error(integer, Arity), abolish/1))
) )
; throw(error(type_error(predicate_indicator, Module:Pred), abolish/1)) ; throw(error(type_error(predicate_indicator, Module:Pred), abolish/1))
). ).
abolish(Pred) :- abolish(Pred) :-
@@ -978,17 +1049,19 @@ abolish(Pred) :-
; var(Arity) -> ; var(Arity) ->
throw(error(instantiation_error, abolish/1)) throw(error(instantiation_error, abolish/1))
; integer(Arity) -> ; integer(Arity) ->
( \+ atom(Name) -> ( \+ atom(Name) ->
throw(error(type_error(atom, Name), abolish/1)) throw(error(type_error(atom, Name), abolish/1))
; Arity < 0 -> ; Arity < 0 ->
throw(error(domain_error(not_less_than_zero, Arity), abolish/1)) throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
; max_arity(N), Arity > N -> ; max_arity(N), Arity > N ->
throw(error(representation_error(max_arity), abolish/1)) throw(error(representation_error(max_arity), abolish/1))
; functor(Head, Name, Arity) -> ; functor(Head, Name, Arity) ->
( '$no_such_predicate'(Head) -> true ( '$no_such_predicate'(user, Head) ->
; '$head_is_dynamic'(Head) -> '$abolish_clause'(Name, Arity) true
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1)) ; '$head_is_dynamic'(user, Head) ->
) '$abolish_clause'(user, Name, Arity)
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
)
) )
; throw(error(type_error(integer, Arity), abolish/1)) ; throw(error(type_error(integer, Arity), abolish/1))
) )

View File

@@ -3068,12 +3068,10 @@ is_false(var(X)) :- nonvar(X).
:- dynamic(goal_expansion/1). :- dynamic(goal_expansion/1).
% goal expansion is disabled for now, until #445 is resolved user:goal_expansion(Goal0, Goal) :-
% \+ goal_expansion(false),
% user:goal_expansion(Goal0, Goal) :- clpz_expandable(Goal0),
% \+ goal_expansion(false), clpz_expansion(Goal0, Goal).
% clpz_expandable(Goal0),
% clpz_expansion(Goal0, Goal).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@@ -125,3 +125,5 @@
:- meta_predicate call(61, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?). :- meta_predicate call(61, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
:- meta_predicate call(62, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?). :- meta_predicate call(62, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
:- meta_predicate call(63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?). :- meta_predicate call(63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
:- meta_predicate call(64, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
:- meta_predicate call(65, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).

View File

@@ -15,7 +15,7 @@ parse_socket_options_(Option, OptionPair) :-
parse_socket_options(Options, OptionValues, Stub) :- parse_socket_options(Options, OptionValues, Stub) :-
DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, tls-false, type-text], DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, tls-false, type-text],
builtins:parse_options_list(Options, parse_socket_options_, DefaultOptions, OptionValues, Stub). builtins:parse_options_list(Options, sockets:parse_socket_options_, DefaultOptions, OptionValues, Stub).
socket_client_open(Addr, Stream, Options) :- socket_client_open(Addr, Stream, Options) :-
( var(Addr) -> ( var(Addr) ->

View File

@@ -18,14 +18,14 @@
'$print_message_and_fail'(Error, Culprit) :- '$print_message_and_fail'(Error, Culprit) :-
% writeq(error(Error, Culprit)), % writeq(error(Error, Culprit)),
% nl, % nl,
'$fail'. '$fail'.
expand_term(Term, ExpandedTerm) :- expand_term(Term, ExpandedTerm) :-
( catch(user:term_expansion(Term, ExpandedTerm0), ( catch('$call'(user:term_expansion(Term, ExpandedTerm0)),
E, E,
loader:'$print_message_and_fail'(E, user:term_expansion)) -> '$call'(loader:'$print_message_and_fail'(E, user:term_expansion))) ->
( var(ExpandedTerm0) -> ( var(ExpandedTerm0) ->
error:instantiation_error(term_expansion/2) error:instantiation_error(term_expansion/2)
; ExpandedTerm0 = [_|_] -> ; ExpandedTerm0 = [_|_] ->
@@ -35,7 +35,6 @@ expand_term(Term, ExpandedTerm) :-
; Term = ExpandedTerm ; Term = ExpandedTerm
). ).
term_expansion_list([], ExpandedTerms, ExpandedTerms). term_expansion_list([], ExpandedTerms, ExpandedTerms).
term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :- term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
expand_term(Term, ExpandedTerm0), expand_term(Term, ExpandedTerm0),
@@ -50,9 +49,9 @@ term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
goal_expansion(Goal, Module, ExpandedGoal) :- goal_expansion(Goal, Module, ExpandedGoal) :-
( catch(Module:goal_expansion(Goal, ExpandedGoal0), ( catch('$call'(Module:goal_expansion(Goal, ExpandedGoal0)),
E, E,
loader:'$print_message_and_fail'(E, Module:goal_expansion)) -> '$call'(loader:'$print_message_and_fail'(E, Module:goal_expansion))) ->
( var(ExpandedGoal0) -> ( var(ExpandedGoal0) ->
error:instantiation_error(goal_expansion/2) error:instantiation_error(goal_expansion/2)
; goal_expansion(ExpandedGoal0, Module, ExpandedGoal) ; goal_expansion(ExpandedGoal0, Module, ExpandedGoal)
@@ -74,6 +73,16 @@ unload_evacuable(Evacuable) :-
'$pop_load_state_payload'(Evacuable), '$pop_load_state_payload'(Evacuable),
'$pop_load_context'. '$pop_load_context'.
run_initialization_goals :-
prolog_load_context(module, Module),
( predicate_property(Module:'$initialization_goals'(_), dynamic) ->
findall(Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals),
( maplist(Module:call, Goals) ->
true
; true %% initialization goals can fail without thwarting the load.
)
; true
).
file_load(Stream, Path) :- file_load(Stream, Path) :-
file_load(Stream, Path, _). file_load(Stream, Path, _).
@@ -83,6 +92,7 @@ file_load(Stream, Path, Evacuable) :-
catch(loader:load_loop(Stream, Evacuable), catch(loader:load_loop(Stream, Evacuable),
E, E,
(loader:unload_evacuable(Evacuable), throw(E))), (loader:unload_evacuable(Evacuable), throw(E))),
run_initialization_goals,
'$pop_load_context'. '$pop_load_context'.
@@ -91,6 +101,7 @@ load(Stream) :-
catch(loader:load_loop(Stream, Evacuable), catch(loader:load_loop(Stream, Evacuable),
E, E,
(loader:unload_evacuable(Evacuable), throw(E))), (loader:unload_evacuable(Evacuable), throw(E))),
run_initialization_goals,
'$pop_load_context'. '$pop_load_context'.
load_loop(Stream, Evacuable) :- load_loop(Stream, Evacuable) :-
@@ -195,8 +206,7 @@ compile_dispatch_or_clause(Term, Evacuable, VNs) :-
compile_dispatch((:- Declaration), Evacuable, _VNs) :- compile_dispatch((:- Declaration), Evacuable, _VNs) :-
( var(Declaration) -> ( var(Declaration) ->
instantiation_error(load/1) instantiation_error(load/1)
; ; compile_declaration(Declaration, Evacuable)
compile_declaration(Declaration, Evacuable)
). ).
compile_dispatch(term_expansion(Term, Terms), Evacuable, VNs) :- compile_dispatch(term_expansion(Term, Terms), Evacuable, VNs) :-
'$add_term_expansion_clause'(term_expansion(Term, Terms), Evacuable, VNs). '$add_term_expansion_clause'(term_expansion(Term, Terms), Evacuable, VNs).
@@ -224,13 +234,13 @@ compile_declaration(use_module(Module, Exports), Evacuable) :-
( Exports == [] -> ( Exports == [] ->
'$remove_module_exports'(Module, Evacuable) % TODO: implement this. '$remove_module_exports'(Module, Evacuable) % TODO: implement this.
; ;
use_module(Module, Exports, Evacuable) use_module(Module, Exports, Evacuable)
). ).
compile_declaration(module(Module, Exports), Evacuable) :- compile_declaration(module(Module, Exports), Evacuable) :-
( atom(Module) -> ( atom(Module) ->
'$declare_module'(Module, Exports, Evacuable) '$declare_module'(Module, Exports, Evacuable)
; ;
type_error(atom, Module, load/1) type_error(atom, Module, load/1)
). ).
compile_declaration(dynamic(Name/Arity), Evacuable) :- compile_declaration(dynamic(Name/Arity), Evacuable) :-
must_be(atom, Name), must_be(atom, Name),
@@ -238,9 +248,8 @@ compile_declaration(dynamic(Name/Arity), Evacuable) :-
'$add_dynamic_predicate'(Name, Arity, Evacuable). '$add_dynamic_predicate'(Name, Arity, Evacuable).
compile_declaration(initialization(Goal), Evacuable) :- compile_declaration(initialization(Goal), Evacuable) :-
prolog_load_context(module, Module), prolog_load_context(module, Module),
'$compile_pending_predicates'(Evacuable), assertz(Module:'$initialization_goals'(Goal)).
expand_goal(call(Goal), Module, call(ExpandedGoal)),
call(ExpandedGoal).
compile_clause(Clause, Evacuable, VNs) :- compile_clause(Clause, Evacuable, VNs) :-
@@ -290,45 +299,64 @@ use_module(Module, Exports) :-
'$push_load_state_payload'(Evacuable), '$push_load_state_payload'(Evacuable),
( Exports == [] -> ( Exports == [] ->
'$remove_module_exports'(Module, Evacuable) '$remove_module_exports'(Module, Evacuable)
; ; use_module(Module, Exports, Evacuable)
use_module(Module, Exports, Evacuable)
). ).
%% If use_module is invoked in an existing load context, use its %% If use_module is invoked in an existing load context, use its
%% directory. Otherwise, use the relative path of Path. %% directory. Otherwise, use the relative path of Path.
load_context_path(Module, Path) :- load_context_path(Module, Path) :-
( prolog_load_context(directory, CurrentDir) -> ( prolog_load_context(directory, CurrentDir) ->
atom_concat(CurrentDir, Path, Module) % Rust's Path module never ends a directory path with '/', so
; % add one here.
Module = Path atom_concat(CurrentDir, '/', CurrentDirSlashed),
atom_concat(CurrentDirSlashed, Module, Path)
; Module = Path
). ).
path_atom(Dir/File, Path) :-
must_be(atom, File),
!,
path_atom(Dir, DirPath),
foldl(builtins:atom_concat, ['/', DirPath], File, Path).
path_atom(Path, Path) :-
must_be(atom, Path).
% Try to open the file with the Path name as given; if that fails,
% append '.pl' and try again.
open_file(Path, Stream) :-
( atom_concat(_, '.pl', Path) ->
open(Path, read, Stream)
; catch(open(Path, read, Stream),
error(existence_error(source_sink, Path), _),
( atom_concat(Path, '.pl', ExtendedPath),
open(ExtendedPath, read, Stream) )
)
).
use_module(Module, Exports, Evacuable) :- use_module(Module, Exports, Evacuable) :-
( var(Module) -> ( var(Module) ->
instantiation_error(load/1) instantiation_error(load/1)
; Module = library(Library) -> ; Module = library(Library) ->
( atom(Library) -> ( path_atom(Library, LibraryPath) ->
( '$load_compiled_library'(Library, Evacuable) -> %% TODO: What about Exports? ( '$load_compiled_library'(LibraryPath, Evacuable) -> %% TODO: What about Exports?
true true
; ; '$load_library_as_stream'(LibraryPath, Stream, Path),
'$load_library_as_stream'(Library, Stream, Path),
file_load(Stream, Path, Subevacuable), file_load(Stream, Path, Subevacuable),
'$use_module'(Evacuable, Subevacuable, Exports) '$use_module'(Evacuable, Subevacuable, Exports)
) )
; var(Library) -> ; var(Library) ->
instantiation_error(load/1) instantiation_error(load/1)
; ; type_error(atom, Library, load/1)
type_error(atom, Library, load/1) )
; ( path_atom(Module, ModulePath) ->
load_context_path(ModulePath, Path),
open_file(Path, Stream),
file_load(Stream, Path, Subevacuable),
'$use_module'(Evacuable, Subevacuable, Exports)
; type_error(atom, Library, load/1)
) )
; atom(Module) ->
load_context_path(Module, Path),
open(Path, read, Stream),
file_load(Stream, Path, Subevacuable),
'$use_module'(Evacuable, Subevacuable, Exports)
;
type_error(atom, Library, load/1)
). ).
@@ -337,6 +365,13 @@ check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm)
'$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm). '$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
check_predicate_property(built_in, _, Name, Arity, built_in) :- check_predicate_property(built_in, _, Name, Arity, built_in) :-
'$cpp_built_in_property'(Name, Arity). '$cpp_built_in_property'(Name, Arity).
check_predicate_property(dynamic, Module, Name, Arity, dynamic) :-
'$cpp_dynamic_property'(Module, Name, Arity).
check_predicate_property(multifile, Module, Name, Arity, multifile) :-
'$cpp_multifile_property'(Module, Name, Arity).
check_predicate_property(discontiguous, Module, Name, Arity, multifile) :-
'$cpp_discontiguous_property'(Module, Name, Arity).
extract_predicate_property(Property, PropertyType) :- extract_predicate_property(Property, PropertyType) :-
@@ -345,35 +380,47 @@ extract_predicate_property(Property, PropertyType) :-
; functor(Property, PropertyType, _) ; functor(Property, PropertyType, _)
). ).
load_context(Module) :-
( prolog_load_context(module, Module) ->
true
; Module = user
).
predicate_property(Callable, Property) :- predicate_property(Callable, Property) :-
( var(Callable) -> ( var(Callable) ->
instantiation_error(load/1) instantiation_error(load/1)
; Callable =.. [(:), Module, Callable0], ; functor(Callable, (:), 2), % Callable =.. [(:), Module, Callable0],
arg(1, Callable, Module),
arg(2, Callable, Callable0),
atom(Module) -> atom(Module) ->
functor(Callable0, Name, Arity), functor(Callable0, Name, Arity),
extract_predicate_property(Property, PropertyType), ( atom(Name),
check_predicate_property(PropertyType, Module, Name, Arity, Property) Name \== [] ->
extract_predicate_property(Property, PropertyType),
check_predicate_property(PropertyType, Module, Name, Arity, Property)
; type_error(callable, Callable0, predicate_property/2)
)
; functor(Callable, Name, Arity), ; functor(Callable, Name, Arity),
extract_predicate_property(Property, PropertyType), ( atom(Name),
( prolog_load_context(module, Module) -> Name \== [] ->
true extract_predicate_property(Property, PropertyType),
; Module = user load_context(Module),
), check_predicate_property(PropertyType, Module, Name, Arity, Property)
check_predicate_property(PropertyType, Module, Name, Arity, Property) ; type_error(callable, Callable, predicate_property/2)
)
). ).
strip_module_(M0, G0, M1, G1) :- strip_module(M0, G0, M1, G1) :-
( nonvar(G0), ( nonvar(G0),
G0 = (MG1:G2) -> G0 = (MG1:G2) ->
strip_module_(MG1, G2, M1, G1) strip_module(MG1, G2, M1, G1)
; M0 = M1, ; M0 = M1,
G0 = G1 G0 = G1
). ).
strip_module(Goal, M, G) :- strip_module(Goal, M, G) :-
strip_module_(_, Goal, M, G). strip_module(_, Goal, M, G).
expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :- expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
@@ -498,3 +545,710 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
; Goals1 =.. [Functor, Goals0, Hole] ; Goals1 =.. [Functor, Goals0, Hole]
) )
). ).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% call/{1-64} with dynamic goal expansion.
%
% The program used to generate the call/N predicates:
%
%
% :- use_module(library(between)).
% :- use_module(library(error)).
% :- use_module(library(lists)).
% :- use_module(library(format)).
%
% call_form_generator(N) :-
% length(Args, N),
% CallHead =.. [call, G | Args],
% N1 is N + 1,
% Form = (CallHead :- ( var(G) ->
% instantiation_error(call/N1)
% ; call_clause(G, Args, N1, G0) ->
% '$call'(G0)
% ; type_error(callable, G, call/N1)
% )),
% portray_clause(Form).
%
% generate_call_forms :-
% between(1, 64, N),
% call_form_generator(N),
% nl,
% false.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
call_clause(M:G1, G0) :-
functor(G1, F, _),
atom(F),
atom(M),
F \== [],
!,
expand_goal(M:G1, M, G0).
% The '$call' functor is an escape hatch from goal expansion. So far,
% it is used only to avoid infinite recursion into expand_goal/3.
call_clause('$call'(G), G0) :-
( var(G),
instantiation_error(call/1)
; G = M:G1,
!,
functor(G1, F, _),
atom(F),
atom(M),
F \== [],
G0 = M:G1
; !,
functor(G, F, _),
atom(F),
F \== [],
load_context(M),
G0 = M:G
).
call_clause(G, G0) :-
functor(G, F, _),
atom(F),
F \== [],
load_context(M),
expand_goal(M:G, M, G0).
call(G) :-
( var(G) ->
instantiation_error(call/1)
; call_clause(G, G0) ->
'$call'(G0)
; type_error(callable, G, call/1)
).
call_clause(M:G1, Args, _, G0) :-
atom(M),
G1 =.. [F | As],
atom(F),
F \== [],
!,
append(As, Args, As1),
G2 =.. [F | As1],
expand_goal(M:G2, M, G0).
call_clause('$call'(G1), Args, N, G0) :-
( var(G1),
instantiation_error(call/N)
; G1 = M:G2,
!,
atom(M),
G2 =.. [F | As],
atom(F),
F \== [],
append(As, Args, As1),
G3 =.. [F | As1],
G0 = M:G3
; !,
G1 =.. [F | As],
atom(F),
F \== [],
load_context(M),
append(As, Args, As1),
G2 =.. [F | As1],
G0 = M:G2
).
call_clause(G, Args, _, G0) :-
G =.. [F | As],
atom(F),
F \== [],
load_context(M),
append(As, Args, As1),
G2 =.. [F | As1],
expand_goal(M:G2, M, G0).
call(A,B) :-
( var(A) ->
instantiation_error(call/2)
; ( call_clause(A,[B],2,C) ->
'$call'(C)
; type_error(callable,A,call/2)
)
).
call(A,B,C) :-
( var(A) ->
instantiation_error(call/3)
; ( call_clause(A,[B,C],3,D) ->
'$call'(D)
; type_error(callable,A,call/3)
)
).
call(A,B,C,D) :-
( var(A) ->
instantiation_error(call/4)
; ( call_clause(A,[B,C,D],4,E) ->
'$call'(E)
; type_error(callable,A,call/4)
)
).
call(A,B,C,D,E) :-
( var(A) ->
instantiation_error(call/5)
; ( call_clause(A,[B,C,D,E],5,F) ->
'$call'(F)
; type_error(callable,A,call/5)
)
).
call(A,B,C,D,E,F) :-
( var(A) ->
instantiation_error(call/6)
; ( call_clause(A,[B,C,D,E,F],6,G) ->
'$call'(G)
; type_error(callable,A,call/6)
)
).
call(A,B,C,D,E,F,G) :-
( var(A) ->
instantiation_error(call/7)
; ( call_clause(A,[B,C,D,E,F,G],7,H) ->
'$call'(H)
; type_error(callable,A,call/7)
)
).
call(A,B,C,D,E,F,G,H) :-
( var(A) ->
instantiation_error(call/8)
; ( call_clause(A,[B,C,D,E,F,G,H],8,I) ->
'$call'(I)
; type_error(callable,A,call/8)
)
).
call(A,B,C,D,E,F,G,H,I) :-
( var(A) ->
instantiation_error(call/9)
; ( call_clause(A,[B,C,D,E,F,G,H,I],9,J) ->
'$call'(J)
; type_error(callable,A,call/9)
)
).
call(A,B,C,D,E,F,G,H,I,J) :-
( var(A) ->
instantiation_error(call/10)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J],10,K) ->
'$call'(K)
; type_error(callable,A,call/10)
)
).
call(A,B,C,D,E,F,G,H,I,J,K) :-
( var(A) ->
instantiation_error(call/11)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K],11,L) ->
'$call'(L)
; type_error(callable,A,call/11)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L) :-
( var(A) ->
instantiation_error(call/12)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L],12,M) ->
'$call'(M)
; type_error(callable,A,call/12)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
( var(A) ->
instantiation_error(call/13)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M],13,N) ->
'$call'(N)
; type_error(callable,A,call/13)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
( var(A) ->
instantiation_error(call/14)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N],14,O) ->
'$call'(O)
; type_error(callable,A,call/14)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
( var(A) ->
instantiation_error(call/15)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O],15,P) ->
'$call'(P)
; type_error(callable,A,call/15)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
( var(A) ->
instantiation_error(call/16)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P],16,Q) ->
'$call'(Q)
; type_error(callable,A,call/16)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
( var(A) ->
instantiation_error(call/17)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q],17,R) ->
'$call'(R)
; type_error(callable,A,call/17)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
( var(A) ->
instantiation_error(call/18)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R],18,S) ->
'$call'(S)
; type_error(callable,A,call/18)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
( var(A) ->
instantiation_error(call/19)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S],19,T) ->
'$call'(T)
; type_error(callable,A,call/19)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
( var(A) ->
instantiation_error(call/20)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T],20,U) ->
'$call'(U)
; type_error(callable,A,call/20)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
( var(A) ->
instantiation_error(call/21)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U],21,V) ->
'$call'(V)
; type_error(callable,A,call/21)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
( var(A) ->
instantiation_error(call/22)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V],22,W) ->
'$call'(W)
; type_error(callable,A,call/22)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
( var(A) ->
instantiation_error(call/23)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W],23,X) ->
'$call'(X)
; type_error(callable,A,call/23)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
( var(A) ->
instantiation_error(call/24)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X],24,Y) ->
'$call'(Y)
; type_error(callable,A,call/24)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :-
( var(A) ->
instantiation_error(call/25)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y],25,Z) ->
'$call'(Z)
; type_error(callable,A,call/25)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :-
( var(A) ->
instantiation_error(call/26)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z],26,A1) ->
'$call'(A1)
; type_error(callable,A,call/26)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :-
( var(A) ->
instantiation_error(call/27)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1],27,B1) ->
'$call'(B1)
; type_error(callable,A,call/27)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :-
( var(A) ->
instantiation_error(call/28)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1],28,C1) ->
'$call'(C1)
; type_error(callable,A,call/28)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :-
( var(A) ->
instantiation_error(call/29)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1],29,D1) ->
'$call'(D1)
; type_error(callable,A,call/29)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :-
( var(A) ->
instantiation_error(call/30)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1],30,E1) ->
'$call'(E1)
; type_error(callable,A,call/30)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :-
( var(A) ->
instantiation_error(call/31)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1],31,F1) ->
'$call'(F1)
; type_error(callable,A,call/31)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :-
( var(A) ->
instantiation_error(call/32)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1],32,G1) ->
'$call'(G1)
; type_error(callable,A,call/32)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :-
( var(A) ->
instantiation_error(call/33)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1],33,H1) ->
'$call'(H1)
; type_error(callable,A,call/33)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :-
( var(A) ->
instantiation_error(call/34)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1],34,I1) ->
'$call'(I1)
; type_error(callable,A,call/34)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
( var(A) ->
instantiation_error(call/35)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1],35,J1) ->
'$call'(J1)
; type_error(callable,A,call/35)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
( var(A) ->
instantiation_error(call/36)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1],36,K1) ->
'$call'(K1)
; type_error(callable,A,call/36)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
( var(A) ->
instantiation_error(call/37)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1],37,L1) ->
'$call'(L1)
; type_error(callable,A,call/37)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
( var(A) ->
instantiation_error(call/38)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1],38,M1) ->
'$call'(M1)
; type_error(callable,A,call/38)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
( var(A) ->
instantiation_error(call/39)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1],39,N1) ->
'$call'(N1)
; type_error(callable,A,call/39)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
( var(A) ->
instantiation_error(call/40)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1],40,O1) ->
'$call'(O1)
; type_error(callable,A,call/40)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
( var(A) ->
instantiation_error(call/41)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1],41,P1) ->
'$call'(P1)
; type_error(callable,A,call/41)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
( var(A) ->
instantiation_error(call/42)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1],42,Q1) ->
'$call'(Q1)
; type_error(callable,A,call/42)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
( var(A) ->
instantiation_error(call/43)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1],43,R1) ->
'$call'(R1)
; type_error(callable,A,call/43)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
( var(A) ->
instantiation_error(call/44)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1],44,S1) ->
'$call'(S1)
; type_error(callable,A,call/44)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
( var(A) ->
instantiation_error(call/45)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1],45,T1) ->
'$call'(T1)
; type_error(callable,A,call/45)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
( var(A) ->
instantiation_error(call/46)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1],46,U1) ->
'$call'(U1)
; type_error(callable,A,call/46)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
( var(A) ->
instantiation_error(call/47)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1],47,V1) ->
'$call'(V1)
; type_error(callable,A,call/47)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
( var(A) ->
instantiation_error(call/48)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1],48,W1) ->
'$call'(W1)
; type_error(callable,A,call/48)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
( var(A) ->
instantiation_error(call/49)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1],49,X1) ->
'$call'(X1)
; type_error(callable,A,call/49)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
( var(A) ->
instantiation_error(call/50)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1],50,Y1) ->
'$call'(Y1)
; type_error(callable,A,call/50)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
( var(A) ->
instantiation_error(call/51)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1],51,Z1) ->
'$call'(Z1)
; type_error(callable,A,call/51)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
( var(A) ->
instantiation_error(call/52)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1],52,A2) ->
'$call'(A2)
; type_error(callable,A,call/52)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
( var(A) ->
instantiation_error(call/53)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2],53,B2) ->
'$call'(B2)
; type_error(callable,A,call/53)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
( var(A) ->
instantiation_error(call/54)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2],54,C2) ->
'$call'(C2)
; type_error(callable,A,call/54)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
( var(A) ->
instantiation_error(call/55)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2],55,D2) ->
'$call'(D2)
; type_error(callable,A,call/55)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
( var(A) ->
instantiation_error(call/56)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2],56,E2) ->
'$call'(E2)
; type_error(callable,A,call/56)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
( var(A) ->
instantiation_error(call/57)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2],57,F2) ->
'$call'(F2)
; type_error(callable,A,call/57)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
( var(A) ->
instantiation_error(call/58)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2],58,G2) ->
'$call'(G2)
; type_error(callable,A,call/58)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
( var(A) ->
instantiation_error(call/59)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2],59,H2) ->
'$call'(H2)
; type_error(callable,A,call/59)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
( var(A) ->
instantiation_error(call/60)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2],60,I2) ->
'$call'(I2)
; type_error(callable,A,call/60)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
( var(A) ->
instantiation_error(call/61)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2],61,J2) ->
'$call'(J2)
; type_error(callable,A,call/61)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
( var(A) ->
instantiation_error(call/62)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2],62,K2) ->
'$call'(K2)
; type_error(callable,A,call/62)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
( var(A) ->
instantiation_error(call/63)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2],63,L2) ->
'$call'(L2)
; type_error(callable,A,call/63)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
( var(A) ->
instantiation_error(call/64)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2],64,M2) ->
'$call'(M2)
; type_error(callable,A,call/64)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
( var(A) ->
instantiation_error(call/65)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2],65,N2) ->
'$call'(N2)
; type_error(callable,A,call/65)
)
).
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
( var(A) ->
instantiation_error(call/65)
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2],65,N2) ->
'$call'(N2)
; type_error(callable,A,call/65)
)
).

File diff suppressed because it is too large Load Diff

View File

@@ -51,7 +51,6 @@ call_goals_0([Module-GoalList | GoalLists]) :-
call_goals_0([]). call_goals_0([]).
call_goals_1([Goal | Goals], Module) :- call_goals_1([Goal | Goals], Module) :-
expand_goal(Goal, Module, Goal1), % TODO: remove this when goal expansions are added to call/N. call(Module:Goal),
call(Module:Goal1),
call_goals_1(Goals, Module). call_goals_1(Goals, Module).
call_goals_1([], _). call_goals_1([], _).

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,17 +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,56 +87,52 @@ 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,
code_dir: &mut CodeDir, code_dir: &mut CodeDir,
op_dir: &mut OpDir, op_dir: &mut OpDir,
meta_predicates: &mut MetaPredicateDir, meta_predicates: &mut MetaPredicateDir,
) { ) -> Result<(), SessionError> {
for export in imported_module.module_decl.exports.iter() { for export in imported_module.module_decl.exports.iter() {
match export { match export {
ModuleExport::PredicateKey((ref name, arity)) => { ModuleExport::PredicateKey((ref name, arity)) => {
@@ -162,19 +156,19 @@ fn import_module_exports(
src_code_index.get(), src_code_index.get(),
); );
} else { } else {
unreachable!() return Err(SessionError::ModuleDoesNotContainExport(
imported_module.module_decl.name.clone(),
(name.clone(), *arity),
));
} }
} }
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,
);
} }
} }
} }
Ok(())
} }
fn import_module_exports_into_module( fn import_module_exports_into_module(
@@ -185,8 +179,8 @@ 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,
) { ) -> Result<(), SessionError> {
for export in imported_module.module_decl.exports.iter() { for export in imported_module.module_decl.exports.iter() {
match export { match export {
ModuleExport::PredicateKey((ref name, arity)) => { ModuleExport::PredicateKey((ref name, arity)) => {
@@ -210,7 +204,10 @@ fn import_module_exports_into_module(
src_code_index.get(), src_code_index.get(),
); );
} else { } else {
unreachable!() return Err(SessionError::ModuleDoesNotContainExport(
imported_module.module_decl.name.clone(),
(name.clone(), *arity),
));
} }
} }
ModuleExport::OpDecl(ref op_decl) => { ModuleExport::OpDecl(ref op_decl) => {
@@ -225,8 +222,9 @@ fn import_module_exports_into_module(
} }
} }
} }
}
Ok(())
}
fn import_qualified_module_exports( fn import_qualified_module_exports(
retraction_info: &mut RetractionInfo, retraction_info: &mut RetractionInfo,
@@ -235,7 +233,7 @@ fn import_qualified_module_exports(
exports: &IndexSet<ModuleExport>, exports: &IndexSet<ModuleExport>,
code_dir: &mut CodeDir, code_dir: &mut CodeDir,
op_dir: &mut OpDir, op_dir: &mut OpDir,
) { ) -> Result<(), SessionError> {
for export in imported_module.module_decl.exports.iter() { for export in imported_module.module_decl.exports.iter() {
if !exports.contains(export) { if !exports.contains(export) {
continue; continue;
@@ -259,19 +257,19 @@ fn import_qualified_module_exports(
src_code_index.get(), src_code_index.get(),
); );
} else { } else {
unreachable!() return Err(SessionError::ModuleDoesNotContainExport(
imported_module.module_decl.name.clone(),
(name.clone(), *arity),
));
} }
} }
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,
);
} }
} }
} }
Ok(())
} }
fn import_qualified_module_exports_into_module( fn import_qualified_module_exports_into_module(
@@ -283,7 +281,7 @@ fn import_qualified_module_exports_into_module(
op_dir: &mut OpDir, op_dir: &mut OpDir,
wam_op_dir: &mut OpDir, wam_op_dir: &mut OpDir,
module_op_exports: &mut ModuleOpExports, module_op_exports: &mut ModuleOpExports,
) { ) -> Result<(), SessionError> {
for export in imported_module.module_decl.exports.iter() { for export in imported_module.module_decl.exports.iter() {
if !exports.contains(export) { if !exports.contains(export) {
continue; continue;
@@ -307,7 +305,10 @@ fn import_qualified_module_exports_into_module(
src_code_index.get(), src_code_index.get(),
); );
} else { } else {
unreachable!() return Err(SessionError::ModuleDoesNotContainExport(
imported_module.module_decl.name.clone(),
(name.clone(), *arity),
));
} }
} }
ModuleExport::OpDecl(ref op_decl) => { ModuleExport::OpDecl(ref op_decl) => {
@@ -322,33 +323,34 @@ fn import_qualified_module_exports_into_module(
} }
} }
} }
Ok(())
} }
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 +367,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 +396,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 +430,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 +459,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 +489,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 +504,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,27 +528,11 @@ impl<'a> LoadState<'a> {
ClauseType::Op(name, fixity, idx) ClauseType::Op(name, fixity, idx)
} }
ct => { ct => ct,
ct
}
} }
} }
#[inline] pub(super) fn add_meta_predicate_record(
pub(super)
fn module_name(&self) -> ClauseName {
match self.compilation_target {
CompilationTarget::User => {
clause_name!("user")
}
CompilationTarget::Module(ref module_name) => {
module_name.clone()
}
}
}
pub(super)
fn add_meta_predicate_record(
&mut self, &mut self,
module_name: ClauseName, module_name: ClauseName,
name: ClauseName, name: ClauseName,
@@ -553,20 +543,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,
); ));
} }
} }
} }
@@ -577,15 +573,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,
)
); );
} }
} }
@@ -601,15 +597,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);
} }
@@ -632,36 +627,33 @@ impl<'a> LoadState<'a> {
code_dir, code_dir,
op_dir, op_dir,
meta_predicates, meta_predicates,
); ).unwrap();
} }
} }
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,
@@ -689,8 +681,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 => {
@@ -701,7 +692,7 @@ impl<'a> LoadState<'a> {
&mut self.wam.indices.code_dir, &mut self.wam.indices.code_dir,
&mut self.wam.indices.op_dir, &mut self.wam.indices.op_dir,
&mut self.wam.indices.meta_predicates, &mut self.wam.indices.meta_predicates,
); )?;
} }
CompilationTarget::Module(ref defining_module_name) => { CompilationTarget::Module(ref defining_module_name) => {
match self.wam.indices.modules.get_mut(defining_module_name) { match self.wam.indices.modules.get_mut(defining_module_name) {
@@ -715,7 +706,7 @@ impl<'a> LoadState<'a> {
&mut target_module.meta_predicates, &mut target_module.meta_predicates,
&mut self.wam.indices.op_dir, &mut self.wam.indices.op_dir,
&mut self.module_op_exports, &mut self.module_op_exports,
); )?;
} }
None => { None => {
// we find ourselves here because we're trying to import // we find ourselves here because we're trying to import
@@ -730,7 +721,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,
)))
} }
} }
@@ -749,7 +742,7 @@ impl<'a> LoadState<'a> {
&exports, &exports,
&mut self.wam.indices.code_dir, &mut self.wam.indices.code_dir,
&mut self.wam.indices.op_dir, &mut self.wam.indices.op_dir,
); )?;
} }
CompilationTarget::Module(ref defining_module_name) => { CompilationTarget::Module(ref defining_module_name) => {
match self.wam.indices.modules.get_mut(defining_module_name) { match self.wam.indices.modules.get_mut(defining_module_name) {
@@ -763,7 +756,7 @@ impl<'a> LoadState<'a> {
&mut target_module.op_dir, &mut target_module.op_dir,
&mut self.wam.indices.op_dir, &mut self.wam.indices.op_dir,
&mut self.module_op_exports, &mut self.module_op_exports,
); )?;
} }
None => { None => {
// we find ourselves here because we're trying to import // we find ourselves here because we're trying to import
@@ -778,41 +771,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)?;
@@ -833,43 +826,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)?;
@@ -897,12 +886,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,6 +1,8 @@
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::PredicateKey;
use crate::machine::heap::*; use crate::machine::heap::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::machine_state::*; use crate::machine::machine_state::*;
@@ -23,74 +25,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 +91,7 @@ impl PermissionError for Addr {
MachineError { MachineError {
stub, stub,
location: None, location: None,
from: ErrorProvenance::Received from: ErrorProvenance::Received,
} }
} }
} }
@@ -120,22 +107,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 +130,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 +141,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 +150,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 +160,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 +170,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 +193,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 +202,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 +220,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 +244,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 +253,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 +264,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 +289,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 +303,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,13 +316,10 @@ 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))
// } // }
/*
SessionError::ModuleDoesNotContainExport(..) => { SessionError::ModuleDoesNotContainExport(..) => {
Self::permission_error( Self::permission_error(
h, h,
@@ -384,47 +328,32 @@ impl MachineError {
functor!("module_does_not_contain_claimed_export"), functor!("module_does_not_contain_claimed_export"),
) )
} }
*/ SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
SessionError::ModuleCannotImportSelf(module_name) => { h,
Self::permission_error( Permission::Modify,
h, "module",
Permission::Modify, functor!("module_cannot_import_self", [clause_name(module_name)]),
"module", ),
functor!("module_cannot_import_self", [clause_name(module_name)]), SessionError::NamelessEntry => Self::permission_error(
) h,
} Permission::Create,
SessionError::NamelessEntry => { "static_procedure",
Self::permission_error( functor!("nameless_procedure"),
h, ),
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 +363,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 +372,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,63 +439,46 @@ 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"),
} }
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Permission { pub enum Permission {
// Access, Access,
Create, Create,
InputStream, InputStream,
Modify, Modify,
@@ -584,7 +491,7 @@ impl Permission {
#[inline] #[inline]
pub fn as_str(self) -> &'static str { pub fn as_str(self) -> &'static str {
match self { match self {
// Permission::Access => "access", Permission::Access => "access",
Permission::Create => "create", Permission::Create => "create",
Permission::InputStream => "input", Permission::InputStream => "input",
Permission::Modify => "modify", Permission::Modify => "modify",
@@ -715,16 +622,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 +640,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 +674,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 +702,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 +722,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 +730,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 +773,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;
@@ -906,7 +804,7 @@ pub enum SessionError {
// CannotOverwriteImport(ClauseName), // CannotOverwriteImport(ClauseName),
ExistenceError(ExistenceError), ExistenceError(ExistenceError),
// InvalidFileName(ClauseName), // InvalidFileName(ClauseName),
// ModuleDoesNotContainExport(ClauseName, PredicateKey), ModuleDoesNotContainExport(ClauseName, PredicateKey),
ModuleCannotImportSelf(ClauseName), ModuleCannotImportSelf(ClauseName),
NamelessEntry, NamelessEntry,
OpIsInfixAndPostFix(ClauseName), OpIsInfixAndPostFix(ClauseName),

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,
} }
} }
@@ -505,7 +420,6 @@ pub enum REPLCodePtr {
AddDynamicPredicate, AddDynamicPredicate,
AddGoalExpansionClause, AddGoalExpansionClause,
AddTermExpansionClause, AddTermExpansionClause,
BuiltInProperty,
ClauseToEvacuable, ClauseToEvacuable,
ConcludeLoad, ConcludeLoad,
DeclareModule, DeclareModule,
@@ -520,11 +434,15 @@ pub enum REPLCodePtr {
PushLoadContext, PushLoadContext,
PushLoadStatePayload, PushLoadStatePayload,
UseModule, UseModule,
BuiltInProperty,
MetaPredicateProperty, MetaPredicateProperty,
CompilePendingPredicates, MultifileProperty,
UserAsserta, DiscontiguousProperty,
UserAssertz, DynamicProperty,
UserRetract, AbolishClause,
Asserta,
Assertz,
Retract,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@@ -533,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.
} }
@@ -541,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,
} }
} }
@@ -563,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,
_ => {} _ => {}
@@ -576,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,
@@ -585,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"));
@@ -655,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)
} }
@@ -690,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),
} }
} }
} }
@@ -706,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)),
} }
} }
} }
@@ -720,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) {
@@ -746,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)
} }
@@ -781,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>;
@@ -821,29 +720,43 @@ impl Default for IndexStore {
} }
impl IndexStore { impl IndexStore {
pub fn get_predicate_skeleton( pub fn get_predicate_skeleton_mut(
&mut self, &mut self,
compilation_target: &CompilationTarget, compilation_target: &CompilationTarget,
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
}
} }
} }
} },
}
}
pub fn get_predicate_skeleton(
&self,
compilation_target: &CompilationTarget,
key: &PredicateKey,
) -> Option<&PredicateSkeleton> {
match (key.0.as_str(), key.1) {
("term_expansion", 2) => self.extensible_predicates.get(key),
_ => match compilation_target {
CompilationTarget::User => self.extensible_predicates.get(key),
CompilationTarget::Module(ref module_name) => {
if let Some(module) = self.modules.get(module_name) {
module.extensible_predicates.get(key)
} else {
None
}
}
},
} }
} }
@@ -855,19 +768,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);
}
} }
} }
} },
} }
} }
@@ -880,15 +791,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| {
@@ -899,9 +804,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
}
} }
}) })
} }
@@ -914,44 +817,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
}
}
}
} }
} }
@@ -960,8 +851,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");
@@ -993,10 +883,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),
} }
} }
} }
@@ -1009,7 +897,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
@@ -1369,7 +1367,6 @@ fn cut_body(machine_st: &mut MachineState, addr: &Addr) -> bool {
&Addr::CutPoint(b0) | &Addr::Usize(b0) => { &Addr::CutPoint(b0) | &Addr::Usize(b0) => {
if b > b0 { if b > b0 {
machine_st.b = b0; machine_st.b = b0;
machine_st.tidy_trail();
} }
} }
_ => { _ => {
@@ -1457,7 +1454,6 @@ impl CutPolicy for SCCCutPolicy {
Addr::Usize(b0) | Addr::CutPoint(b0) => { Addr::Usize(b0) | Addr::CutPoint(b0) => {
if b > b0 { if b > b0 {
machine_st.b = b0; machine_st.b = b0;
machine_st.tidy_trail();
} }
} }
_ => { _ => {

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;
@@ -119,39 +123,6 @@ include!(concat!(env!("OUT_DIR"), "/libraries.rs"));
impl Machine { impl Machine {
/* /*
fn compile_special_forms(&mut self)
{
let verify_attrs_src = ListingSource::User;
match compile_special_form(
self,
Stream::from(VERIFY_ATTRS),
verify_attrs_src,
)
{
Ok(p) => {
self.machine_st.attr_var_init.verify_attrs_loc = p;
}
Err(_) =>
panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
}
let project_attrs_src = ListingSource::User;
match compile_special_form(
self,
Stream::from(PROJECT_ATTRS),
project_attrs_src,
)
{
Ok(p) => {
self.machine_st.attr_var_init.project_attrs_loc = p;
}
Err(e) =>
panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS: {}", e),
}
}
fn compile_scryerrc(&mut self) { fn compile_scryerrc(&mut self) {
let mut path = match dirs_next::home_dir() { let mut path = match dirs_next::home_dir() {
Some(path) => path, Some(path) => path,
@@ -177,13 +148,7 @@ impl Machine {
compile_user_module(self, file_src, rc_src); compile_user_module(self, file_src, rc_src);
} }
} }
*/ */
#[cfg(test)]
pub fn reset(&mut self) {
self.current_input_stream = readline::input_stream();
self.policies.cut_policy = Box::new(DefaultCutPolicy {});
self.machine_st.reset();
}
fn run_module_predicate(&mut self, module_name: ClauseName, key: PredicateKey) { fn run_module_predicate(&mut self, module_name: ClauseName, key: PredicateKey) {
if let Some(module) = self.indices.modules.get(&module_name) { if let Some(module) = self.indices.modules.get(&module_name) {
@@ -201,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));
} }
@@ -245,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");
@@ -257,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)) {
@@ -289,15 +245,66 @@ impl Machine {
self.machine_st[temp_v!(1)] = list_addr; self.machine_st[temp_v!(1)] = list_addr;
// WAS: self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("$repl"), 1));
// self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("$repl"), 1));
self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("repl"), 0));
} }
pub fn new(user_input: Stream, user_output: Stream) -> Self fn configure_modules(&mut self) {
{ fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
use crate::ref_thread_local::RefThreadLocal; for arity in 1..66 {
let key = (clause_name!("call"), arity);
match loader.code_dir.get(&key) {
Some(src_code_index) => {
let target_code_index = target_module
.code_dir
.entry(key.clone())
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
target_code_index.set(src_code_index.get());
}
None => {
unreachable!();
}
}
}
}
if let Some(loader) = self.indices.modules.swap_remove(&clause_name!("loader")) {
if let Some(builtins) = self.indices.modules.get_mut(&clause_name!("builtins")) {
// Import loader's exports into the builtins module so they will be
// implicitly included in every further module.
load_module(
&mut builtins.code_dir,
&mut builtins.op_dir,
&mut builtins.meta_predicates,
&CompilationTarget::Module(clause_name!("builtins")),
&loader,
);
for export in &loader.module_decl.exports {
builtins.module_decl.exports.push(export.clone());
}
for arity in 10..66 {
builtins
.module_decl
.exports
.push(ModuleExport::PredicateKey((clause_name!("call"), arity)));
}
}
for (_, target_module) in self.indices.modules.iter_mut() {
update_call_n_indices(&loader, target_module);
}
self.indices.modules.insert(clause_name!("loader"), loader);
} else {
unreachable!()
}
}
pub fn new(user_input: Stream, user_output: Stream) -> Self {
use ref_thread_local::RefThreadLocal;
let mut wam = Machine { let mut wam = Machine {
machine_st: MachineState::new(), machine_st: MachineState::new(),
@@ -322,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(
@@ -350,38 +356,20 @@ 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();
if let Some(loader) = wam.indices.modules.swap_remove(&clause_name!("loader")) { wam.configure_modules();
if let Some(builtins) = wam.indices.modules.get_mut(&clause_name!("builtins")) {
// Import loader's exports into the builtins module so they will be
// implicitly included every further module.
load_module(
&mut builtins.code_dir,
&mut builtins.op_dir,
&mut builtins.meta_predicates,
&CompilationTarget::Module(clause_name!("builtins")),
&loader,
);
for export in &loader.module_decl.exports {
builtins.module_decl.exports.push(export.clone());
}
}
if let Some(loader) = wam.indices.modules.get(&clause_name!("loader")) {
load_module( load_module(
&mut wam.indices.code_dir, &mut wam.indices.code_dir,
&mut wam.indices.op_dir, &mut wam.indices.op_dir,
&mut wam.indices.meta_predicates, &mut wam.indices.meta_predicates,
&CompilationTarget::User, &CompilationTarget::User,
&loader, loader,
); );
wam.indices.modules.insert(clause_name!("loader"), loader);
} else { } else {
unreachable!() unreachable!()
} }
@@ -396,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) {
@@ -487,25 +469,33 @@ impl Machine {
REPLCodePtr::BuiltInProperty => { REPLCodePtr::BuiltInProperty => {
self.builtin_property(); self.builtin_property();
} }
REPLCodePtr::CompilePendingPredicates => { REPLCodePtr::MultifileProperty => {
self.compile_pending_predicates(); self.multifile_property();
} }
REPLCodePtr::UserAssertz => { REPLCodePtr::DiscontiguousProperty => {
self.compile_user_assert(AppendOrPrepend::Append); self.discontiguous_property();
} }
REPLCodePtr::UserAsserta => { REPLCodePtr::DynamicProperty => {
self.compile_user_assert(AppendOrPrepend::Prepend); self.dynamic_property();
} }
REPLCodePtr::UserRetract => { REPLCodePtr::Assertz => {
self.retract_user_clause(); self.compile_assert(AppendOrPrepend::Append);
}
REPLCodePtr::Asserta => {
self.compile_assert(AppendOrPrepend::Prepend);
}
REPLCodePtr::Retract => {
self.retract_clause();
}
REPLCodePtr::AbolishClause => {
self.abolish_clause();
} }
} }
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,
@@ -523,23 +513,6 @@ impl Machine {
self.machine_st.backtrack(); self.machine_st.backtrack();
} }
} }
/*
CodePtr::DynamicTransaction(_trans_type, _p) => {
// self.code_repo.cached_query is about to be overwritten by the term expander,
// so hold onto it locally and restore it after the compiler has finished.
self.machine_st.fail = false;
/*
let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]);
// self.dynamic_transaction(trans_type, p);
self.code_repo.cached_query = cached_query;
if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
break;
}
*/
}
*/
_ => { _ => {
break; break;
} }
@@ -559,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;
@@ -620,44 +589,23 @@ impl MachineState {
} }
fn backtrack(&mut self) { fn backtrack(&mut self) {
// if self.b > 0 {
let b = self.b; let b = self.b;
self.b0 = self.stack.index_or_frame(b).prelude.b0; self.b0 = self.stack.index_or_frame(b).prelude.b0;
self.p = CodePtr::Local(self.stack.index_or_frame(b).prelude.bp); self.p = CodePtr::Local(self.stack.index_or_frame(b).prelude.bp);
/*
if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.p {
self.fail = p == 0;
} else {
*/
self.fail = false; self.fail = false;
// }
/*} else {
self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
}*/
} }
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;
} }
/* _ => {}
CodePtr::DynamicTransaction(..) => {
// prevent use of dynamic transactions from
// succeeding in expansions. self.fail will be toggled
// back to false later.
self.fail = true;
return false;
}
*/
_ => {
}
} }
true true
@@ -721,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.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, 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 {
""
}
} }
} }
@@ -46,7 +50,11 @@ pub mod readline {
impl ReadlineStream { impl ReadlineStream {
#[inline] #[inline]
pub fn new(pending_input: String) -> Self { pub fn new(pending_input: String) -> Self {
let mut rl = Editor::<()>::new(); let config = Config::builder()
.check_cursor_position(true)
.build();
let mut rl = Editor::<()>::with_config(config); //Editor::<()>::new();
if let Some(mut path) = dirs_next::home_dir() { if let Some(mut path) = dirs_next::home_dir() {
path.push(HISTORY_FILE); path.push(HISTORY_FILE);
if path.exists() { if path.exists() {
@@ -57,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]
@@ -85,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))
}
} }
} }
@@ -117,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"));
}
_ => {}
},
} }
} }
} }
@@ -144,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"));
}
_ => {}
},
} }
} }
} }
@@ -167,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
}
} }
} }
} }
@@ -210,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)
} }
@@ -242,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));
@@ -254,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)
}
} }
} }
@@ -286,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();
@@ -355,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::*;

View File

@@ -1,9 +1,5 @@
:- module('$toplevel', [argv/1, :- module('$toplevel', [argv/1,
copy_term/3, copy_term/3]).
predicate_property/2,
prolog_load_context/2]).
:- use_module(library(loader)).
:- use_module(library(charsio)). :- use_module(library(charsio)).
:- use_module(library(iso_ext)). :- use_module(library(iso_ext)).
@@ -18,15 +14,15 @@
'$repl'([_|Args0]) :- '$repl'([_|Args0]) :-
\+ argv(_), \+ argv(_),
( append(Args1, ["--"|Args2], Args0) -> ( append(Args1, ["--"|Args2], Args0) ->
asserta(argv(Args2)), asserta('$toplevel':argv(Args2)),
Args = Args1 Args = Args1
; asserta(argv([])), ; asserta('$toplevel':argv([])),
Args = Args0 Args = Args0
), ),
delegate_task(Args, []), delegate_task(Args, []),
repl. repl.
'$repl'(_) :- '$repl'(_) :-
( \+ argv(_) -> asserta(argv([])) ( \+ argv(_) -> asserta('$toplevel':argv([]))
; true ; true
), ),
repl. repl.
@@ -41,7 +37,8 @@ delegate_task([Arg0|Args], Goals0) :-
; member(Arg0, ["-v", "--version"]) -> print_version ; member(Arg0, ["-v", "--version"]) -> print_version
; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0) ; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0)
; atom_chars(Mod, Arg0), ; atom_chars(Mod, Arg0),
catch(use_module(Mod), E, print_exception(E)) catch(use_module(Mod), E, print_exception(E)),
nl
), ),
delegate_task(Args, Goals0). delegate_task(Args, Goals0).
@@ -126,7 +123,7 @@ instruction_match(Term, VarList) :-
( Item == user -> ( Item == user ->
catch(load(user_input), E, print_exception_with_check(E)) catch(load(user_input), E, print_exception_with_check(E))
; ;
consult(Item) submit_query_and_print_results(consult(Item), [])
) )
; ;
catch(type_error(atom, Item, repl/0), catch(type_error(atom, Item, repl/0),

View File

@@ -26,14 +26,14 @@ impl fmt::Display for REPLCodePtr {
write!(f, "REPLCodePtr::AddGoalExpansionClause"), write!(f, "REPLCodePtr::AddGoalExpansionClause"),
REPLCodePtr::AddTermExpansionClause => REPLCodePtr::AddTermExpansionClause =>
write!(f, "REPLCodePtr::AddTermExpansionClause"), write!(f, "REPLCodePtr::AddTermExpansionClause"),
REPLCodePtr::BuiltInProperty => REPLCodePtr::AbolishClause =>
write!(f, "REPLCodePtr::BuiltInProperty"), write!(f, "REPLCodePtr::AbolishClause"),
REPLCodePtr::UserAssertz => REPLCodePtr::Assertz =>
write!(f, "REPLCodePtr::UserAssertz"), write!(f, "REPLCodePtr::Assertz"),
REPLCodePtr::UserAsserta => REPLCodePtr::Asserta =>
write!(f, "REPLCodePtr::UserAsserta"), write!(f, "REPLCodePtr::Asserta"),
REPLCodePtr::UserRetract => REPLCodePtr::Retract =>
write!(f, "REPLCodePtr::UserRetract"), write!(f, "REPLCodePtr::Retract"),
REPLCodePtr::ClauseToEvacuable => REPLCodePtr::ClauseToEvacuable =>
write!(f, "REPLCodePtr::ClauseToEvacuable"), write!(f, "REPLCodePtr::ClauseToEvacuable"),
REPLCodePtr::ConcludeLoad => REPLCodePtr::ConcludeLoad =>
@@ -64,8 +64,14 @@ impl fmt::Display for REPLCodePtr {
write!(f, "REPLCodePtr::UseModule"), write!(f, "REPLCodePtr::UseModule"),
REPLCodePtr::MetaPredicateProperty => REPLCodePtr::MetaPredicateProperty =>
write!(f, "REPLCodePtr::MetaPredicateProperty"), write!(f, "REPLCodePtr::MetaPredicateProperty"),
REPLCodePtr::CompilePendingPredicates => REPLCodePtr::BuiltInProperty =>
write!(f, "REPLCodePtr::CompilePendingPredicates"), write!(f, "REPLCodePtr::BuiltInProperty"),
REPLCodePtr::DynamicProperty =>
write!(f, "REPLCodePtr::DynamicProperty"),
REPLCodePtr::MultifileProperty =>
write!(f, "REPLCodePtr::MultifileProperty"),
REPLCodePtr::DiscontiguousProperty =>
write!(f, "REPLCodePtr::DiscontiguousProperty"),
} }
} }
} }
@@ -371,15 +377,15 @@ impl fmt::Display for SessionError {
// &SessionError::InvalidFileName(ref filename) => { // &SessionError::InvalidFileName(ref filename) => {
// write!(f, "filename {} is invalid", filename) // write!(f, "filename {} is invalid", filename)
// } // }
// &SessionError::ModuleDoesNotContainExport(ref module, ref key) => { &SessionError::ModuleDoesNotContainExport(ref module, ref key) => {
// write!( write!(
// f, f,
// "module {} does not contain claimed export {}/{}", "module {} does not contain claimed export {}/{}",
// module, module,
// key.0, key.0,
// key.1, key.1,
// ) )
// } }
&SessionError::OpIsInfixAndPostFix(_) => { &SessionError::OpIsInfixAndPostFix(_) => {
write!(f, "cannot define an op to be both postfix and infix.") write!(f, "cannot define an op to be both postfix and infix.")
} }