Merge branch 'rebis-dev' of https://github.com/mthom/scryer-prolog into rebis-dev
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -878,7 +878,7 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prolog_parser_rebis"
|
||||
name = "prolog_parser"
|
||||
version = "0.8.68"
|
||||
dependencies = [
|
||||
"lexical",
|
||||
@@ -1221,7 +1221,7 @@ dependencies = [
|
||||
"num-rug-adapter",
|
||||
"openssl",
|
||||
"ordered-float",
|
||||
"prolog_parser_rebis",
|
||||
"prolog_parser",
|
||||
"ref_thread_local",
|
||||
"ring",
|
||||
"ripemd160",
|
||||
|
||||
@@ -18,8 +18,8 @@ members = ["crates/prolog_parser"]
|
||||
indexmap = "1.0.2"
|
||||
|
||||
[features]
|
||||
default = ["rug", "prolog_parser_rebis/rug"]
|
||||
num = ["num-rug-adapter", "prolog_parser_rebis/num"]
|
||||
default = ["rug", "prolog_parser/rug"]
|
||||
num = ["num-rug-adapter", "prolog_parser/num"]
|
||||
|
||||
[dependencies]
|
||||
cpu-time = "1.0.0"
|
||||
@@ -35,7 +35,7 @@ libc = "0.2.62"
|
||||
nix = "0.15.0"
|
||||
num-rug-adapter = { optional = true, version = "0.1.4" }
|
||||
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"
|
||||
rug = { version = "1.4.0", optional = true }
|
||||
rustyline = "7.0.0"
|
||||
|
||||
10
build.rs
10
build.rs
@@ -1,5 +1,3 @@
|
||||
extern crate indexmap;
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
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()) {
|
||||
if entry.is_dir() {
|
||||
if let Some(file_name) = entry.file_name() {
|
||||
let new_prefix =
|
||||
prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||
let new_prefix = prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||
find_prolog_files(libraries, &new_prefix, &entry);
|
||||
}
|
||||
} else if entry.is_file() {
|
||||
let ext = std::ffi::OsStr::new("pl");
|
||||
if entry.extension() == Some(ext) {
|
||||
let contain =
|
||||
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||
let contain = String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||
let name = entry.file_stem().unwrap().to_str().unwrap();
|
||||
|
||||
let line = format!(
|
||||
@@ -47,7 +43,7 @@ fn main() {
|
||||
|
||||
libraries
|
||||
.write_all(
|
||||
b"ref_thread_local! {
|
||||
b"ref_thread_local::ref_thread_local! {
|
||||
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
||||
let mut m = IndexMap::new();\n",
|
||||
)
|
||||
|
||||
2
crates/prolog_parser/Cargo.lock
generated
2
crates/prolog_parser/Cargo.lock
generated
@@ -148,7 +148,7 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prolog_parser_rebis"
|
||||
name = "prolog_parser"
|
||||
version = "0.8.68"
|
||||
dependencies = [
|
||||
"lexical",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
[package]
|
||||
name = "prolog_parser_rebis"
|
||||
name = "prolog_parser"
|
||||
version = "0.8.68"
|
||||
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."
|
||||
license = "BSD-3-Clause"
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use rug::{Integer, Rational};
|
||||
use crate::rug::{Integer, Rational};
|
||||
use crate::tabled_rc::*;
|
||||
use ordered_float::*;
|
||||
use tabled_rc::*;
|
||||
|
||||
use put_back_n::*;
|
||||
use crate::put_back_n::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp::Ordering;
|
||||
@@ -27,112 +27,150 @@ pub const MAX_ARITY: usize = 1023;
|
||||
pub const XFX: u32 = 0x0001;
|
||||
pub const XFY: u32 = 0x0002;
|
||||
pub const YFX: u32 = 0x0004;
|
||||
pub const XF: u32 = 0x0010;
|
||||
pub const YF: u32 = 0x0020;
|
||||
pub const FX: u32 = 0x0040;
|
||||
pub const FY: u32 = 0x0080;
|
||||
pub const XF: u32 = 0x0010;
|
||||
pub const YF: u32 = 0x0020;
|
||||
pub const FX: u32 = 0x0040;
|
||||
pub const FY: u32 = 0x0080;
|
||||
pub const DELIMITER: u32 = 0x0100;
|
||||
pub const TERM: u32 = 0x1000;
|
||||
pub const TERM: u32 = 0x1000;
|
||||
pub const LTERM: u32 = 0x3000;
|
||||
|
||||
pub const NEGATIVE_SIGN: u32 = 0x0200;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! clause_name {
|
||||
($name: expr, $tbl: expr) => (
|
||||
ClauseName::User(TabledRc::new($name, $tbl.clone()))
|
||||
) ;
|
||||
($name: expr) => (
|
||||
ClauseName::BuiltIn($name)
|
||||
)
|
||||
($name: expr, $tbl: expr) => {
|
||||
$crate::ast::ClauseName::User($crate::tabled_rc::TabledRc::new($name, $tbl.clone()))
|
||||
};
|
||||
($name: expr) => {
|
||||
$crate::ast::ClauseName::BuiltIn($name)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! atom {
|
||||
($e:expr, $tbl:expr) => (
|
||||
Constant::Atom(ClauseName::User(tabled_rc!($e, $tbl)), None)
|
||||
);
|
||||
($e:expr) => (
|
||||
Constant::Atom(clause_name!($e), None)
|
||||
)
|
||||
($e:expr, $tbl:expr) => {
|
||||
$crate::ast::Constant::Atom(
|
||||
$crate::ast::ClauseName::User($crate::tabled_rc!($e, $tbl)),
|
||||
None,
|
||||
)
|
||||
};
|
||||
($e:expr) => {
|
||||
$crate::ast::Constant::Atom($crate::clause_name!($e), None)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! rc_atom {
|
||||
($e:expr) => (
|
||||
($e:expr) => {
|
||||
Rc::new(String::from($e))
|
||||
)
|
||||
};
|
||||
}
|
||||
macro_rules! is_term {
|
||||
($x:expr) => ( ($x & TERM) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::TERM) != 0
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! is_lterm {
|
||||
($x:expr) => ( ($x & LTERM) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::LTERM) != 0
|
||||
};
|
||||
}
|
||||
|
||||
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 {
|
||||
($x:expr) => ( ($x & NEGATIVE_SIGN) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::NEGATIVE_SIGN) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_prefix {
|
||||
($x:expr) => ( $x & (FX | FY) != 0 )
|
||||
($x:expr) => {
|
||||
$x & ($crate::ast::FX | $crate::ast::FY) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_postfix {
|
||||
($x:expr) => ( $x & (XF | YF) != 0 )
|
||||
($x:expr) => {
|
||||
$x & ($crate::ast::XF | $crate::ast::YF) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
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_rules! is_xfx {
|
||||
($x:expr) => ( ($x & XFX) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::XFX) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_xfy {
|
||||
($x:expr) => ( ($x & XFY) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::XFY) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_yfx {
|
||||
($x:expr) => ( ($x & YFX) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::YFX) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_yf {
|
||||
($x:expr) => ( ($x & YF) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::YF) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_xf {
|
||||
($x:expr) => ( ($x & XF) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::XF) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! is_fx {
|
||||
($x:expr) => ( ($x & FX) != 0 )
|
||||
($x:expr) => {
|
||||
($x & $crate::ast::FX) != 0
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
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)]
|
||||
pub enum RegType {
|
||||
Perm(usize),
|
||||
Temp(usize)
|
||||
Temp(usize),
|
||||
}
|
||||
|
||||
impl Default for RegType {
|
||||
@@ -144,23 +182,20 @@ impl Default for RegType {
|
||||
impl RegType {
|
||||
pub fn reg_num(self) -> usize {
|
||||
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 {
|
||||
match self {
|
||||
RegType::Perm(_) => true,
|
||||
_ => false
|
||||
}
|
||||
matches!(self, RegType::Perm(_))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RegType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&RegType::Perm(val) => write!(f, "Y{}", val),
|
||||
&RegType::Temp(val) => write!(f, "X{}", val)
|
||||
RegType::Perm(val) => write!(f, "Y{}", val),
|
||||
RegType::Temp(val) => write!(f, "X{}", val),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,13 +203,13 @@ impl fmt::Display for RegType {
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum VarReg {
|
||||
ArgAndNorm(RegType, usize),
|
||||
Norm(RegType)
|
||||
Norm(RegType),
|
||||
}
|
||||
|
||||
impl VarReg {
|
||||
pub fn norm(self) -> RegType {
|
||||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
|
||||
&VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
|
||||
&VarReg::ArgAndNorm(RegType::Perm(reg), arg) =>
|
||||
write!(f, "Y{} A{}", reg, arg),
|
||||
&VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
|
||||
write!(f, "X{} A{}", reg, arg)
|
||||
VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
|
||||
VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
|
||||
VarReg::ArgAndNorm(RegType::Perm(reg), arg) => write!(f, "Y{} 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_rules! temp_v {
|
||||
($x:expr) => (
|
||||
RegType::Temp($x)
|
||||
)
|
||||
($x:expr) => {
|
||||
$crate::ast::RegType::Temp($x)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! perm_v {
|
||||
($x:expr) => (
|
||||
RegType::Perm($x)
|
||||
)
|
||||
($x:expr) => {
|
||||
$crate::ast::RegType::Perm($x)
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum GenContext {
|
||||
Head, Mid(usize), Last(usize) // Mid & Last: chunk_num
|
||||
Head,
|
||||
Mid(usize),
|
||||
Last(usize), // Mid & Last: chunk_num
|
||||
}
|
||||
|
||||
impl GenContext {
|
||||
pub fn chunk_num(self) -> usize {
|
||||
match self {
|
||||
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)]
|
||||
pub struct MachineFlags {
|
||||
pub double_quotes: DoubleQuotes
|
||||
pub double_quotes: DoubleQuotes,
|
||||
}
|
||||
|
||||
impl Default for MachineFlags {
|
||||
fn default() -> Self {
|
||||
MachineFlags { double_quotes: DoubleQuotes::default() }
|
||||
MachineFlags {
|
||||
double_quotes: DoubleQuotes::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DoubleQuotes {
|
||||
Atom, Chars, Codes
|
||||
Atom,
|
||||
Chars,
|
||||
Codes,
|
||||
}
|
||||
|
||||
impl DoubleQuotes {
|
||||
pub fn is_chars(self) -> bool {
|
||||
if let DoubleQuotes::Chars = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(self, DoubleQuotes::Chars)
|
||||
}
|
||||
|
||||
pub fn is_atom(self) -> bool {
|
||||
if let DoubleQuotes::Atom = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(self, DoubleQuotes::Atom)
|
||||
}
|
||||
|
||||
pub fn is_codes(self) -> bool {
|
||||
if let DoubleQuotes::Codes = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(self, DoubleQuotes::Codes)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,10 +323,10 @@ impl Default for DoubleQuotes {
|
||||
pub fn default_op_dir() -> OpDir {
|
||||
let mut op_dir = OpDir::new();
|
||||
|
||||
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::In), OpDirValue::new(XFY, 1000));
|
||||
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::In), OpDirValue::new(XFY, 1000));
|
||||
|
||||
op_dir
|
||||
}
|
||||
@@ -307,7 +334,7 @@ pub fn default_op_dir() -> OpDir {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ArithmeticError {
|
||||
NonEvaluableFunctor(Constant, usize),
|
||||
UninstantiatedVar
|
||||
UninstantiatedVar,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -321,47 +348,35 @@ pub enum ParserError {
|
||||
MissingQuote(usize, usize),
|
||||
NonPrologChar(usize, usize),
|
||||
ParseBigInt(usize, usize),
|
||||
Utf8Error(usize, usize)
|
||||
Utf8Error(usize, usize),
|
||||
}
|
||||
|
||||
impl ParserError {
|
||||
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||
match self {
|
||||
&ParserError::BackQuotedString(line_num, col_num)
|
||||
| &ParserError::UnexpectedChar(_, line_num, col_num)
|
||||
| &ParserError::IncompleteReduction(line_num, col_num)
|
||||
| &ParserError::MissingQuote(line_num, col_num)
|
||||
| &ParserError::NonPrologChar(line_num, col_num)
|
||||
| &ParserError::ParseBigInt(line_num, col_num)
|
||||
| &ParserError::Utf8Error(line_num, col_num) =>
|
||||
Some((line_num, col_num)),
|
||||
_ =>
|
||||
None
|
||||
| &ParserError::UnexpectedChar(_, line_num, col_num)
|
||||
| &ParserError::IncompleteReduction(line_num, col_num)
|
||||
| &ParserError::MissingQuote(line_num, col_num)
|
||||
| &ParserError::NonPrologChar(line_num, col_num)
|
||||
| &ParserError::ParseBigInt(line_num, col_num)
|
||||
| &ParserError::Utf8Error(line_num, col_num) => Some((line_num, col_num)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
&ParserError::BackQuotedString(..) =>
|
||||
"back_quoted_string",
|
||||
&ParserError::UnexpectedChar(..) =>
|
||||
"unexpected_char",
|
||||
&ParserError::UnexpectedEOF =>
|
||||
"unexpected_end_of_file",
|
||||
&ParserError::IncompleteReduction(..) =>
|
||||
"incomplete_reduction",
|
||||
&ParserError::InvalidSingleQuotedCharacter(..) =>
|
||||
"invalid_single_quoted_character",
|
||||
&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",
|
||||
ParserError::BackQuotedString(..) => "back_quoted_string",
|
||||
ParserError::UnexpectedChar(..) => "unexpected_char",
|
||||
ParserError::UnexpectedEOF => "unexpected_end_of_file",
|
||||
ParserError::IncompleteReduction(..) => "incomplete_reduction",
|
||||
ParserError::InvalidSingleQuotedCharacter(..) => "invalid_single_quoted_character",
|
||||
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)]
|
||||
pub struct CompositeOpDir<'a, 'b> {
|
||||
pub primary_op_dir: Option<&'b OpDir>,
|
||||
pub secondary_op_dir: &'a OpDir,
|
||||
}
|
||||
|
||||
impl<'a, 'b> CompositeOpDir<'a, 'b>
|
||||
{
|
||||
impl<'a, 'b> CompositeOpDir<'a, 'b> {
|
||||
#[inline]
|
||||
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]
|
||||
pub(crate)
|
||||
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))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
pub(crate) 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))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
entry.or_else(move || self.secondary_op_dir.get(&(name, fixity)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||
pub enum Fixity {
|
||||
In, Post, Pre
|
||||
In,
|
||||
Post,
|
||||
Pre,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
@@ -496,28 +510,21 @@ pub enum Constant {
|
||||
impl fmt::Display for Constant {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&Constant::Atom(ref atom, _) =>
|
||||
Constant::Atom(ref atom, _) => {
|
||||
if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) {
|
||||
write!(f, "'{}'", atom.as_str())
|
||||
} else {
|
||||
write!(f, "{}", atom.as_str())
|
||||
},
|
||||
&Constant::Char(c) =>
|
||||
write!(f, "'{}'", c as u32),
|
||||
&Constant::EmptyList =>
|
||||
write!(f, "[]"),
|
||||
&Constant::Fixnum(n) =>
|
||||
write!(f, "{}", n),
|
||||
&Constant::Integer(ref n) =>
|
||||
write!(f, "{}", n),
|
||||
&Constant::Rational(ref n) =>
|
||||
write!(f, "{}", n),
|
||||
&Constant::Float(ref n) =>
|
||||
write!(f, "{}", n),
|
||||
&Constant::String(ref s) =>
|
||||
write!(f, "\"{}\"", &s),
|
||||
&Constant::Usize(integer) =>
|
||||
write!(f, "u{}", integer),
|
||||
}
|
||||
}
|
||||
Constant::Char(c) => write!(f, "'{}'", *c as u32),
|
||||
Constant::EmptyList => write!(f, "[]"),
|
||||
Constant::Fixnum(n) => write!(f, "{}", n),
|
||||
Constant::Integer(ref n) => write!(f, "{}", n),
|
||||
Constant::Rational(ref n) => 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 {
|
||||
match (self, other) {
|
||||
(&Constant::Atom(ref atom, _), &Constant::Char(c))
|
||||
| (&Constant::Char(c), &Constant::Atom(ref atom, _)) => {
|
||||
atom.is_char() && Some(c) == atom.as_str().chars().next()
|
||||
},
|
||||
(&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) =>
|
||||
a1.as_str() == a2.as_str(),
|
||||
(&Constant::Char(c1), &Constant::Char(c2)) =>
|
||||
c1 == c2,
|
||||
(&Constant::Fixnum(n1), &Constant::Fixnum(n2)) =>
|
||||
n1 == n2,
|
||||
(&Constant::Fixnum(n1), &Constant::Integer(ref n2)) |
|
||||
(&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => {
|
||||
| (&Constant::Char(c), &Constant::Atom(ref atom, _)) => {
|
||||
atom.is_char() && atom.as_str().starts_with(c)
|
||||
}
|
||||
(&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) => a1.as_str() == a2.as_str(),
|
||||
(&Constant::Char(c1), &Constant::Char(c2)) => c1 == c2,
|
||||
(&Constant::Fixnum(n1), &Constant::Fixnum(n2)) => n1 == n2,
|
||||
(&Constant::Fixnum(n1), &Constant::Integer(ref n2))
|
||||
| (&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => {
|
||||
if let Some(n2) = n2.to_isize() {
|
||||
n1 == n2
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
(&Constant::Integer(ref n1), &Constant::Integer(ref n2)) =>
|
||||
n1 == n2,
|
||||
(&Constant::Rational(ref n1), &Constant::Rational(ref n2)) =>
|
||||
n1 == n2,
|
||||
(&Constant::Float(ref n1), &Constant::Float(ref n2)) =>
|
||||
n1 == n2,
|
||||
(&Constant::String(ref s1), &Constant::String(ref s2)) => {
|
||||
&s1 == &s2
|
||||
}
|
||||
(&Constant::EmptyList, &Constant::EmptyList) =>
|
||||
true,
|
||||
(&Constant::Usize(u1), &Constant::Usize(u2)) =>
|
||||
u1 == u2,
|
||||
_ => false
|
||||
(&Constant::Integer(ref n1), &Constant::Integer(ref n2)) => n1 == n2,
|
||||
(&Constant::Rational(ref n1), &Constant::Rational(ref n2)) => n1 == n2,
|
||||
(&Constant::Float(ref n1), &Constant::Float(ref n2)) => n1 == n2,
|
||||
(&Constant::String(ref s1), &Constant::String(ref s2)) => 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 Constant {
|
||||
pub fn to_atom(self) -> Option<ClauseName> {
|
||||
pub fn to_atom(&self) -> Option<ClauseName> {
|
||||
match self {
|
||||
Constant::Atom(a, _) => Some(a.defrock_brackets()),
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -575,7 +572,7 @@ impl Constant {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ClauseName {
|
||||
BuiltIn(&'static str),
|
||||
User(TabledRc<Atom>)
|
||||
User(TabledRc<Atom>),
|
||||
}
|
||||
|
||||
impl fmt::Display for ClauseName {
|
||||
@@ -620,20 +617,22 @@ impl ClauseName {
|
||||
#[inline]
|
||||
pub fn owning_module(&self) -> Self {
|
||||
match self {
|
||||
&ClauseName::User(ref name) => {
|
||||
ClauseName::User(ref name) => {
|
||||
let module = name.owning_module();
|
||||
ClauseName::User(TabledRc { atom: module.clone(),
|
||||
table: TabledData::new(module) })
|
||||
},
|
||||
_ => clause_name!("user")
|
||||
ClauseName::User(TabledRc {
|
||||
atom: module.clone(),
|
||||
table: TabledData::new(module),
|
||||
})
|
||||
}
|
||||
_ => clause_name!("user"),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_rc(&self) -> Rc<String> {
|
||||
match self {
|
||||
&ClauseName::BuiltIn(s) => Rc::new(s.to_string()),
|
||||
&ClauseName::User(ref rc) => rc.inner()
|
||||
ClauseName::BuiltIn(s) => Rc::new(s.to_string()),
|
||||
ClauseName::User(ref rc) => rc.inner(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,52 +659,46 @@ impl ClauseName {
|
||||
pub fn has_table_of(&self, other: &ClauseName) -> bool {
|
||||
match self {
|
||||
ClauseName::BuiltIn(_) => {
|
||||
if let ClauseName::BuiltIn(_) = other {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
ClauseName::User(ref name) => {
|
||||
other.has_table(&name.table)
|
||||
matches!(other, ClauseName::BuiltIn(_))
|
||||
}
|
||||
ClauseName::User(ref name) => other.has_table(&name.table),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
&ClauseName::BuiltIn(s) => s,
|
||||
&ClauseName::User(ref name) => name.as_ref()
|
||||
ClauseName::BuiltIn(s) => s,
|
||||
ClauseName::User(ref name) => name.as_ref(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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 {
|
||||
if s.starts_with('(') && s.ends_with(')') {
|
||||
&s[1 .. s.len() - 1]
|
||||
&s[1..s.len() - 1]
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
match self {
|
||||
ClauseName::BuiltIn(s) =>
|
||||
ClauseName::BuiltIn(defrock_brackets(s)),
|
||||
ClauseName::User(s) =>
|
||||
ClauseName::BuiltIn(s) => ClauseName::BuiltIn(defrock_brackets(s)),
|
||||
ClauseName::User(s) => {
|
||||
ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for ClauseName {
|
||||
#[inline]
|
||||
fn as_ref(self: &Self) -> &str {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
@@ -713,41 +706,45 @@ impl AsRef<str> for ClauseName {
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Term {
|
||||
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>),
|
||||
Constant(Cell<RegType>, Constant),
|
||||
Var(Cell<VarReg>, Rc<Var>)
|
||||
Var(Cell<VarReg>, Rc<Var>),
|
||||
}
|
||||
|
||||
impl Term {
|
||||
pub fn shared_op_desc(&self) -> Option<SharedOpDesc> {
|
||||
match self {
|
||||
&Term::Clause(_, _, _, ref spec) => spec.clone(),
|
||||
&Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(),
|
||||
_ => None
|
||||
Term::Clause(_, _, _, ref spec) => spec.clone(),
|
||||
Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_constant(self) -> Option<Constant> {
|
||||
pub fn into_constant(self) -> Option<Constant> {
|
||||
match self {
|
||||
Term::Constant(_, c) => Some(c),
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn first_arg(&self) -> Option<&Term> {
|
||||
match self {
|
||||
&Term::Clause(_, _, ref terms, _) =>
|
||||
terms.first().map(|bt| bt.as_ref()),
|
||||
_ => None
|
||||
Term::Clause(_, _, ref terms, _) => terms.first().map(|bt| bt.as_ref()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, new_name: ClauseName) {
|
||||
match self {
|
||||
Term::Constant(_, Constant::Atom(ref mut atom, _))
|
||||
| Term::Clause(_, ref mut atom, ..) => {
|
||||
*atom = new_name;
|
||||
| Term::Clause(_, ref mut atom, ..) => {
|
||||
*atom = new_name;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@@ -755,22 +752,23 @@ impl Term {
|
||||
|
||||
pub fn name(&self) -> Option<ClauseName> {
|
||||
match self {
|
||||
&Term::Constant(_, Constant::Atom(ref atom, _))
|
||||
| &Term::Clause(_, ref atom, ..) => Some(atom.clone()),
|
||||
_ => None
|
||||
&Term::Constant(_, Constant::Atom(ref atom, _)) | &Term::Clause(_, ref atom, ..) => {
|
||||
Some(atom.clone())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
|
||||
_ => 0
|
||||
Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
let snd = *subterms.pop().unwrap();
|
||||
let fst = *subterms.pop().unwrap();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::lexical::parse_lossy;
|
||||
use crate::ordered_float::*;
|
||||
use crate::rug::Integer;
|
||||
use lexical::parse_lossy;
|
||||
use ordered_float::*;
|
||||
|
||||
use ast::*;
|
||||
use tabled_rc::*;
|
||||
use crate::ast::*;
|
||||
use crate::tabled_rc::*;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
@@ -11,13 +11,13 @@ use std::io::Read;
|
||||
use std::rc::Rc;
|
||||
|
||||
macro_rules! is_not_eof {
|
||||
($c:expr) => (
|
||||
($c:expr) => {
|
||||
match $c {
|
||||
Ok(c) => c,
|
||||
Err(ParserError::UnexpectedEOF) => return Ok(true),
|
||||
Err(e) => return Err(e)
|
||||
Err($crate::ast::ParserError::UnexpectedEOF) => return Ok(true),
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! consume_chars_with {
|
||||
@@ -26,27 +26,27 @@ macro_rules! consume_chars_with {
|
||||
match $e {
|
||||
Ok(Some(c)) => $token.push(c),
|
||||
Ok(None) => continue,
|
||||
Err(ParserError::UnexpectedChar(..)) => break,
|
||||
Err(e) => return Err(e)
|
||||
Err($crate::ast::ParserError::UnexpectedChar(..)) => break,
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Token {
|
||||
Constant(Constant),
|
||||
Var(Rc<Atom>),
|
||||
Open, // '('
|
||||
OpenCT, // '('
|
||||
Close, // ')'
|
||||
OpenList, // '['
|
||||
CloseList, // ']'
|
||||
OpenCurly, // '{'
|
||||
CloseCurly, // '}'
|
||||
Open, // '('
|
||||
OpenCT, // '('
|
||||
Close, // ')'
|
||||
OpenList, // '['
|
||||
CloseList, // ']'
|
||||
OpenCurly, // '{'
|
||||
CloseCurly, // '}'
|
||||
HeadTailSeparator, // '|'
|
||||
Comma, // ','
|
||||
End
|
||||
Comma, // ','
|
||||
End,
|
||||
}
|
||||
|
||||
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) flags: MachineFlags,
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Lexer")
|
||||
.field("atom_tbl", &self.atom_tbl)
|
||||
.field("reader", &"&'a mut ParsingStream<R>") // Hacky solution.
|
||||
.field("line_num", &self.line_num)
|
||||
.field("col_num", &self.col_num)
|
||||
.finish()
|
||||
.field("atom_tbl", &self.atom_tbl)
|
||||
.field("reader", &"&'a mut ParsingStream<R>") // Hacky solution.
|
||||
.field("line_num", &self.line_num)
|
||||
.field("col_num", &self.col_num)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,13 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
flags: MachineFlags,
|
||||
src: &'a mut ParsingStream<R>,
|
||||
) -> 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) {
|
||||
@@ -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 {
|
||||
if self.reader.peek().is_none() || new_line_char!(self.skip_char()?) {
|
||||
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()?) {
|
||||
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()?) {
|
||||
let c = self.skip_char()?;
|
||||
|
||||
if new_line_char!(self.lookahead_char()?) {
|
||||
self.skip_char()?;
|
||||
return Ok(None)
|
||||
return Ok(None);
|
||||
} else {
|
||||
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()? {
|
||||
'a' => '\u{07}', // UTF-8 alert
|
||||
'b' => '\u{08}', // UTF-8 backspace
|
||||
@@ -309,20 +311,18 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
't' => '\t',
|
||||
'n' => '\n',
|
||||
'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()?;
|
||||
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)
|
||||
}
|
||||
|
||||
fn get_hexadecimal_escape_sequence(&mut self) -> Result<char, ParserError>
|
||||
{
|
||||
fn get_hexadecimal_escape_sequence(&mut self) -> Result<char, ParserError> {
|
||||
self.skip_char()?;
|
||||
let c = self.lookahead_char()?;
|
||||
|
||||
@@ -354,12 +354,13 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
|
||||
if backslash_char!(c) {
|
||||
self.skip_char()?;
|
||||
u32::from_str_radix(&token, radix)
|
||||
.map_or_else(
|
||||
|_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)),
|
||||
|n| char::try_from(n)
|
||||
u32::from_str_radix(&token, radix).map_or_else(
|
||||
|_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)),
|
||||
|n| {
|
||||
char::try_from(n)
|
||||
.map_err(|_| ParserError::Utf8Error(self.line_num, self.col_num))
|
||||
)
|
||||
},
|
||||
)
|
||||
} else {
|
||||
// on failure, restore the token characters and backslash.
|
||||
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)))
|
||||
.or_else(|_| {
|
||||
Integer::from_str_radix(&token, 16)
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||
})
|
||||
} else {
|
||||
self.return_char('x');
|
||||
@@ -449,11 +447,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
Integer::from_str_radix(&token, 8)
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||
})
|
||||
} else {
|
||||
self.return_char('o');
|
||||
@@ -475,11 +470,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
Integer::from_str_radix(&token, 2)
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||
})
|
||||
} else {
|
||||
self.return_char('b');
|
||||
@@ -525,18 +517,20 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
if single_quote_char!(self.lookahead_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() {
|
||||
return Ok(Token::Constant(Constant::Char(c)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(ParserError::InvalidSingleQuotedCharacter(self.lookahead_char()?))
|
||||
return Err(ParserError::InvalidSingleQuotedCharacter(
|
||||
self.lookahead_char()?,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
match self.get_back_quoted_string() {
|
||||
Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)),
|
||||
Err(e) => return Err(e)
|
||||
Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)),
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,12 +569,10 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||
})
|
||||
} else if decimal_digit_char!(self.lookahead_char()?) {
|
||||
token.push('.');
|
||||
@@ -599,7 +591,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
|
||||
let c = match self.lookahead_char() {
|
||||
Err(_) => return Ok(self.vacate_with_float(token)),
|
||||
Ok(c) => c
|
||||
Ok(c) => c,
|
||||
};
|
||||
|
||||
if !sign_char!(c) && !decimal_digit_char!(c) {
|
||||
@@ -613,8 +605,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
Err(_) => {
|
||||
self.return_char(token.pop().unwrap());
|
||||
return Ok(self.vacate_with_float(token));
|
||||
},
|
||||
Ok(c) => c
|
||||
}
|
||||
Ok(c) => c,
|
||||
};
|
||||
|
||||
if !decimal_digit_char!(c) {
|
||||
@@ -645,70 +637,65 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if token.starts_with('0') && token.len() == 1 {
|
||||
if c == 'x' {
|
||||
self.hexadecimal_constant()
|
||||
.or_else(|e| {
|
||||
if let ParserError::ParseBigInt(..) = e {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
})
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
self.hexadecimal_constant().or_else(|e| {
|
||||
if let ParserError::ParseBigInt(..) = e {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| {
|
||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
} else if c == 'o' {
|
||||
self.octal_constant()
|
||||
.or_else(|e| {
|
||||
if let ParserError::ParseBigInt(..) = e {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
})
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
self.octal_constant().or_else(|e| {
|
||||
if let ParserError::ParseBigInt(..) = e {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| {
|
||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
} else if c == 'b' {
|
||||
self.binary_constant()
|
||||
.or_else(|e| {
|
||||
if let ParserError::ParseBigInt(..) = e {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
})
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
self.binary_constant().or_else(|e| {
|
||||
if let ParserError::ParseBigInt(..) = e {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| {
|
||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
} else if single_quote_char!(c) {
|
||||
self.skip_char()?;
|
||||
|
||||
@@ -726,45 +713,39 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
}
|
||||
|
||||
self.get_single_quoted_char()
|
||||
.and_then(|c| {
|
||||
Ok(Token::Constant(Constant::Fixnum(c as isize)))
|
||||
})
|
||||
.map(|c| Token::Constant(Constant::Fixnum(c as isize)))
|
||||
.or_else(|_| {
|
||||
self.return_char(c);
|
||||
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| {
|
||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||
})
|
||||
}
|
||||
} else {
|
||||
isize::from_str_radix(&token, 10)
|
||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||
.or_else(|_| {
|
||||
token.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(
|
||||
self.line_num,
|
||||
self.col_num,
|
||||
))
|
||||
token
|
||||
.parse::<Integer>()
|
||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||
.map_err(|_| ParserError::ParseBigInt(self.line_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) => {
|
||||
self.skip_char()?;
|
||||
layout_inserted = true;
|
||||
},
|
||||
}
|
||||
Ok(c) if end_line_comment_char!(c) => {
|
||||
self.single_line_comment()?;
|
||||
layout_inserted = true;
|
||||
},
|
||||
Ok(c) if comment_1_char!(c) =>
|
||||
}
|
||||
Ok(c) if comment_1_char!(c) => {
|
||||
if self.bracketed_comment()? {
|
||||
layout_inserted = true;
|
||||
} else {
|
||||
more_layout = false;
|
||||
},
|
||||
_ => more_layout = false
|
||||
}
|
||||
}
|
||||
_ => more_layout = false,
|
||||
};
|
||||
|
||||
if !more_layout {
|
||||
@@ -825,8 +807,11 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
|
||||
if c == '(' {
|
||||
self.skip_char()?;
|
||||
return Ok(if layout_inserted { Token::Open }
|
||||
else { Token::OpenCT });
|
||||
return Ok(if layout_inserted {
|
||||
Token::Open
|
||||
} else {
|
||||
Token::OpenCT
|
||||
});
|
||||
}
|
||||
|
||||
if c == '.' {
|
||||
@@ -839,7 +824,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
}
|
||||
|
||||
return Ok(Token::End);
|
||||
},
|
||||
}
|
||||
Err(ParserError::UnexpectedEOF) => {
|
||||
return Ok(Token::End);
|
||||
}
|
||||
@@ -891,8 +876,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
||||
}
|
||||
|
||||
self.name_token(c)
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
extern crate lexical;
|
||||
extern crate ordered_float;
|
||||
#[cfg(feature = "rug")]
|
||||
extern crate rug;
|
||||
#[cfg(feature = "num-rug-adapter")]
|
||||
extern crate num_rug_adapter as rug;
|
||||
extern crate unicode_reader;
|
||||
use num_rug_adapter as rug;
|
||||
#[cfg(feature = "rug")]
|
||||
use rug;
|
||||
|
||||
#[macro_use] pub mod tabled_rc;
|
||||
#[macro_use] pub mod ast;
|
||||
#[macro_use] pub mod macros;
|
||||
#[macro_use]
|
||||
pub mod tabled_rc;
|
||||
#[macro_use]
|
||||
pub mod ast;
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
pub mod parser;
|
||||
pub mod put_back_n;
|
||||
|
||||
|
||||
@@ -1,187 +1,246 @@
|
||||
#[macro_export]
|
||||
macro_rules! char_class {
|
||||
($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_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_rules! space_char {
|
||||
($c: expr) => ($c == ' ')
|
||||
($c: expr) => {
|
||||
$c == ' '
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
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_rules! symbolic_hexadecimal_char {
|
||||
($c: expr) => ($c == 'x')
|
||||
($c: expr) => {
|
||||
$c == 'x'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! octal_digit_char {
|
||||
($c: expr) => ($c >= '0' && $c <= '7')
|
||||
($c: expr) => {
|
||||
('0'..='7').contains(&$c)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! binary_digit_char {
|
||||
($c: expr) => ($c >= '0' && $c <= '1')
|
||||
($c: expr) => {
|
||||
$c >= '0' && $c <= '1'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! hexadecimal_digit_char {
|
||||
($c: expr) => ($c >= '0' && $c <= '9' ||
|
||||
$c >= 'A' && $c <= 'F' ||
|
||||
$c >= 'a' && $c <= 'f')
|
||||
($c: expr) => {
|
||||
('0'..='9').contains(&$c) || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! exponent_char {
|
||||
($c: expr) => ($c == 'e' || $c == 'E')
|
||||
($c: expr) => {
|
||||
$c == 'e' || $c == 'E'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! sign_char {
|
||||
($c: expr) => ($c == '-' || $c == '+')
|
||||
($c: expr) => {
|
||||
$c == '-' || $c == '+'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! new_line_char {
|
||||
($c: expr) => ($c == '\n')
|
||||
($c: expr) => {
|
||||
$c == '\n'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! end_line_comment_char {
|
||||
($c: expr) => ($c == '%')
|
||||
($c: expr) => {
|
||||
$c == '%'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! comment_1_char {
|
||||
($c: expr) => ($c == '/')
|
||||
($c: expr) => {
|
||||
$c == '/'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! comment_2_char {
|
||||
($c: expr) => ($c == '*')
|
||||
($c: expr) => {
|
||||
$c == '*'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! capital_letter_char {
|
||||
($c: expr) => ($c >= 'A' && $c <= 'Z')
|
||||
($c: expr) => {
|
||||
('A'..='Z').contains(&$c)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! small_letter_char {
|
||||
($c: expr) => ($c >= 'a' && $c <= 'z')
|
||||
($c: expr) => {
|
||||
('a'..='z').contains(&$c)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! variable_indicator_char {
|
||||
($c: expr) => ($c == '_')
|
||||
($c: expr) => {
|
||||
$c == '_'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! graphic_char {
|
||||
($c: expr) => (char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':',
|
||||
($c: expr) => ($crate::char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':',
|
||||
'<', '=', '>', '?', '@', '^', '~']))
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
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_rules! alpha_char {
|
||||
($c: expr) =>
|
||||
(match $c {
|
||||
'a' ..= 'z' => true,
|
||||
'A' ..= 'Z' => true,
|
||||
($c: expr) => {
|
||||
match $c {
|
||||
'a'..='z' => true,
|
||||
'A'..='Z' => true,
|
||||
'_' => true,
|
||||
'\u{00A0}' ..= '\u{00BF}' => true,
|
||||
'\u{00C0}' ..= '\u{00D6}' => true,
|
||||
'\u{00D8}' ..= '\u{00F6}' => true,
|
||||
'\u{00F8}' ..= '\u{00FF}' => true,
|
||||
'\u{0100}' ..= '\u{017F}' => true, // Latin Extended-A
|
||||
'\u{0180}' ..= '\u{024F}' => true, // Latin Extended-B
|
||||
'\u{0250}' ..= '\u{02AF}' => true, // IPA Extensions
|
||||
'\u{02B0}' ..= '\u{02FF}' => true, // Spacing Modifier Letters
|
||||
'\u{0300}' ..= '\u{036F}' => true, // Combining Diacritical Marks
|
||||
'\u{0370}' ..= '\u{03FF}' => true, // Greek/Coptic
|
||||
'\u{0400}' ..= '\u{04FF}' => true, // Cyrillic
|
||||
'\u{0500}' ..= '\u{052F}' => true, // Cyrillic Supplement
|
||||
'\u{0530}' ..= '\u{058F}' => true, // Armenian
|
||||
'\u{0590}' ..= '\u{05FF}' => true, // Hebrew
|
||||
'\u{0600}' ..= '\u{06FF}' => true, // Arabic
|
||||
'\u{0700}' ..= '\u{074F}' => true, // Syriac
|
||||
_ => false
|
||||
})
|
||||
'\u{00A0}'..='\u{00BF}' => true,
|
||||
'\u{00C0}'..='\u{00D6}' => true,
|
||||
'\u{00D8}'..='\u{00F6}' => true,
|
||||
'\u{00F8}'..='\u{00FF}' => true,
|
||||
'\u{0100}'..='\u{017F}' => true, // Latin Extended-A
|
||||
'\u{0180}'..='\u{024F}' => true, // Latin Extended-B
|
||||
'\u{0250}'..='\u{02AF}' => true, // IPA Extensions
|
||||
'\u{02B0}'..='\u{02FF}' => true, // Spacing Modifier Letters
|
||||
'\u{0300}'..='\u{036F}' => true, // Combining Diacritical Marks
|
||||
'\u{0370}'..='\u{03FF}' => true, // Greek/Coptic
|
||||
'\u{0400}'..='\u{04FF}' => true, // Cyrillic
|
||||
'\u{0500}'..='\u{052F}' => true, // Cyrillic Supplement
|
||||
'\u{0530}'..='\u{058F}' => true, // Armenian
|
||||
'\u{0590}'..='\u{05FF}' => true, // Hebrew
|
||||
'\u{0600}'..='\u{06FF}' => true, // Arabic
|
||||
'\u{0700}'..='\u{074F}' => true, // Syriac
|
||||
_ => false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! decimal_digit_char {
|
||||
($c: expr) => ($c >= '0' && $c <= '9')
|
||||
($c: expr) => {
|
||||
('0'..='9').contains(&$c)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! decimal_point_char {
|
||||
($c: expr) => ($c == '.')
|
||||
($c: expr) => {
|
||||
$c == '.'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
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_rules! cut_char {
|
||||
($c: expr) => ($c == '!')
|
||||
($c: expr) => {
|
||||
$c == '!'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! semicolon_char {
|
||||
($c: expr) => ($c == ';')
|
||||
($c: expr) => {
|
||||
$c == ';'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! backslash_char {
|
||||
($c: expr) => ($c == '\\')
|
||||
($c: expr) => {
|
||||
$c == '\\'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! single_quote_char {
|
||||
($c: expr) => ($c == '\'')
|
||||
($c: expr) => {
|
||||
$c == '\''
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! double_quote_char {
|
||||
($c: expr) => ($c == '"')
|
||||
($c: expr) => {
|
||||
$c == '"'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! back_quote_char {
|
||||
($c: expr) => ($c == '`')
|
||||
($c: expr) => {
|
||||
$c == '`'
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! meta_char {
|
||||
($c: expr) => ( char_class!($c, ['\\', '\'', '"', '`']) )
|
||||
($c: expr) => {
|
||||
$crate::char_class!($c, ['\\', '\'', '"', '`'])
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! solo_char {
|
||||
($c: expr) => ( char_class!($c, ['!', '(', ')', ',', ';', '[', ']',
|
||||
'{', '}', '|', '%']) )
|
||||
($c: expr) => {
|
||||
$crate::char_class!($c, ['!', '(', ')', ',', ';', '[', ']', '{', '}', '|', '%'])
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! prolog_char {
|
||||
($c: expr) => (graphic_char!($c) || alpha_numeric_char!($c) || solo_char!($c) ||
|
||||
layout_char!($c) || meta_char!($c))
|
||||
($c: expr) => {
|
||||
$crate::graphic_char!($c)
|
||||
|| $crate::alpha_numeric_char!($c)
|
||||
|| $crate::solo_char!($c)
|
||||
|| $crate::layout_char!($c)
|
||||
|| $crate::meta_char!($c)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use ast::*;
|
||||
use lexer::*;
|
||||
use tabled_rc::*;
|
||||
use crate::ast::*;
|
||||
use crate::lexer::*;
|
||||
use crate::tabled_rc::*;
|
||||
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use rug::ops::NegAssign;
|
||||
use crate::rug::ops::NegAssign;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::io::Read;
|
||||
@@ -16,25 +16,30 @@ enum TokenType {
|
||||
Term,
|
||||
Open,
|
||||
OpenCT,
|
||||
OpenList, // '['
|
||||
OpenCurly, // '{'
|
||||
OpenList, // '['
|
||||
OpenCurly, // '{'
|
||||
HeadTailSeparator, // '|'
|
||||
Comma, // ','
|
||||
Comma, // ','
|
||||
Close,
|
||||
CloseList, // ']'
|
||||
CloseCurly, // '}'
|
||||
End
|
||||
CloseList, // ']'
|
||||
CloseCurly, // '}'
|
||||
End,
|
||||
}
|
||||
|
||||
impl TokenType {
|
||||
fn is_sep(self) -> bool {
|
||||
match self {
|
||||
TokenType::HeadTailSeparator | TokenType::OpenCT | TokenType::Open |
|
||||
TokenType::Close | TokenType::OpenList | TokenType::CloseList |
|
||||
TokenType::OpenCurly | TokenType::CloseCurly | TokenType::Comma
|
||||
=> true,
|
||||
_ => false
|
||||
}
|
||||
matches!(
|
||||
self,
|
||||
TokenType::HeadTailSeparator
|
||||
| TokenType::OpenCT
|
||||
| TokenType::Open
|
||||
| TokenType::Close
|
||||
| TokenType::OpenList
|
||||
| TokenType::CloseList
|
||||
| TokenType::OpenCurly
|
||||
| TokenType::CloseCurly
|
||||
| TokenType::Comma
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +47,14 @@ impl TokenType {
|
||||
struct TokenDesc {
|
||||
tt: TokenType,
|
||||
priority: usize,
|
||||
spec: u32
|
||||
spec: u32,
|
||||
}
|
||||
|
||||
pub
|
||||
fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> Option<SharedOpDesc>
|
||||
{
|
||||
pub fn get_clause_spec(
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
op_dir: &CompositeOpDir,
|
||||
) -> Option<SharedOpDesc> {
|
||||
match arity {
|
||||
1 => {
|
||||
/* 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) {
|
||||
return Some(cell.clone());
|
||||
}
|
||||
},
|
||||
2 =>
|
||||
}
|
||||
2 => {
|
||||
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::In) {
|
||||
return Some(cell.clone());
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc>
|
||||
{
|
||||
let mut op_desc = OpDesc { pre: 0, inf: 0, post: 0, spec: 0 };
|
||||
pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc> {
|
||||
let mut op_desc = OpDesc {
|
||||
pre: 0,
|
||||
inf: 0,
|
||||
post: 0,
|
||||
spec: 0,
|
||||
};
|
||||
|
||||
if let Some(OpDirValue(cell)) = op_dir.get(name.clone(), Fixity::Pre) {
|
||||
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
|
||||
&& is_term!(d3.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
|
||||
}
|
||||
|
||||
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
|
||||
&& ((is_term!(d3.spec) && d3.priority < d2.priority)
|
||||
|| (is_lterm!(d3.spec) && d3.priority == d2.priority))
|
||||
&& ((is_term!(d3.spec) && d3.priority < d2.priority)
|
||||
|| (is_lterm!(d3.spec) && d3.priority == d2.priority))
|
||||
&& is_term!(d1.spec)
|
||||
&& 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
|
||||
&& is_term!(d3.spec)
|
||||
&& d3.priority < d2.priority
|
||||
@@ -139,49 +147,35 @@ fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b
|
||||
&& 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;
|
||||
(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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
fn sep_to_atom(tt: TokenType) -> Option<ClauseName>
|
||||
{
|
||||
fn sep_to_atom(tt: TokenType) -> Option<ClauseName> {
|
||||
match tt {
|
||||
TokenType::Open | TokenType::OpenCT =>
|
||||
Some(clause_name!("(")),
|
||||
TokenType::Close =>
|
||||
Some(clause_name!(")")),
|
||||
TokenType::OpenList =>
|
||||
Some(clause_name!("[")),
|
||||
TokenType::CloseList =>
|
||||
Some(clause_name!("]")),
|
||||
TokenType::OpenCurly =>
|
||||
Some(clause_name!("{")),
|
||||
TokenType::CloseCurly =>
|
||||
Some(clause_name!("}")),
|
||||
TokenType::HeadTailSeparator =>
|
||||
Some(clause_name!("|")),
|
||||
TokenType::Comma =>
|
||||
Some(clause_name!(",")),
|
||||
TokenType::End =>
|
||||
Some(clause_name!(".")),
|
||||
_ => None
|
||||
TokenType::Open | TokenType::OpenCT => Some(clause_name!("(")),
|
||||
TokenType::Close => Some(clause_name!(")")),
|
||||
TokenType::OpenList => Some(clause_name!("[")),
|
||||
TokenType::CloseList => Some(clause_name!("]")),
|
||||
TokenType::OpenCurly => Some(clause_name!("{")),
|
||||
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 inf: usize,
|
||||
pub post: usize,
|
||||
pub spec: Specifier
|
||||
pub spec: Specifier,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -201,8 +195,7 @@ pub struct Parser<'a, R: Read> {
|
||||
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![];
|
||||
|
||||
loop {
|
||||
@@ -227,10 +220,12 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
atom_tbl: TabledData<Atom>,
|
||||
flags: MachineFlags,
|
||||
) -> Self {
|
||||
Parser { lexer: Lexer::new(atom_tbl, flags, stream),
|
||||
tokens: vec![],
|
||||
stack: Vec::new(),
|
||||
terms: Vec::new() }
|
||||
Parser {
|
||||
lexer: Lexer::new(atom_tbl, flags, stream),
|
||||
tokens: vec![],
|
||||
stack: Vec::new(),
|
||||
terms: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -255,50 +250,46 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
|
||||
fn get_term_name(&mut self, td: TokenDesc) -> Option<(ClauseName, Option<SharedOpDesc>)> {
|
||||
match td.tt {
|
||||
TokenType::HeadTailSeparator => {
|
||||
Some((clause_name!("|"), Some(SharedOpDesc::new(td.priority, td.spec))))
|
||||
}
|
||||
TokenType::Comma => {
|
||||
Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY))))
|
||||
}
|
||||
TokenType::Term => {
|
||||
match self.terms.pop() {
|
||||
Some(Term::Constant(_, Constant::Atom(atom, spec))) =>
|
||||
Some((atom, spec)),
|
||||
Some(term) => {
|
||||
self.terms.push(term);
|
||||
None
|
||||
},
|
||||
_ => None
|
||||
TokenType::HeadTailSeparator => Some((
|
||||
clause_name!("|"),
|
||||
Some(SharedOpDesc::new(td.priority, td.spec)),
|
||||
)),
|
||||
TokenType::Comma => Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY)))),
|
||||
TokenType::Term => match self.terms.pop() {
|
||||
Some(Term::Constant(_, Constant::Atom(atom, spec))) => Some((atom, spec)),
|
||||
Some(term) => {
|
||||
self.terms.push(term);
|
||||
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((name, shared_op_desc)) = self.get_term_name(td) {
|
||||
if let Some(arg1) = self.terms.pop() {
|
||||
let term = Term::Clause(Cell::default(),
|
||||
name,
|
||||
vec![Box::new(arg1), Box::new(arg2)],
|
||||
shared_op_desc);
|
||||
let term = Term::Clause(
|
||||
Cell::default(),
|
||||
name,
|
||||
vec![Box::new(arg1), Box::new(arg2)],
|
||||
shared_op_desc,
|
||||
);
|
||||
|
||||
self.terms.push(term);
|
||||
self.stack.push(TokenDesc { tt: TokenType::Term,
|
||||
priority: td.priority,
|
||||
spec });
|
||||
self.stack.push(TokenDesc {
|
||||
tt: TokenType::Term,
|
||||
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 name) = self.terms.pop() {
|
||||
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 {
|
||||
let term = Term::Clause(Cell::default(), name, vec![Box::new(arg1)],
|
||||
shared_op_desc);
|
||||
let term =
|
||||
Term::Clause(Cell::default(), name, vec![Box::new(arg1)], shared_op_desc);
|
||||
|
||||
self.terms.push(term);
|
||||
self.stack.push(TokenDesc { tt: TokenType::Term,
|
||||
priority: td.priority,
|
||||
spec });
|
||||
self.stack.push(TokenDesc {
|
||||
tt: TokenType::Term,
|
||||
priority: td.priority,
|
||||
spec,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn promote_atom_op(&mut self, atom: ClauseName, priority: usize, assoc: u32,
|
||||
op_dir_val: Option<&OpDirValue>)
|
||||
{
|
||||
fn promote_atom_op(
|
||||
&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());
|
||||
|
||||
self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, spec)));
|
||||
self.stack.push(TokenDesc { tt: TokenType::Term, priority, spec: assoc });
|
||||
self.terms
|
||||
.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 {
|
||||
Token::Constant(Constant::String(s))
|
||||
if self.lexer.flags.double_quotes.is_codes() => {
|
||||
let mut list = Term::Constant(Cell::default(), Constant::EmptyList);
|
||||
Token::Constant(Constant::String(s)) if self.lexer.flags.double_quotes.is_codes() => {
|
||||
let mut list = Term::Constant(Cell::default(), Constant::EmptyList);
|
||||
|
||||
for c in s.chars().rev() {
|
||||
list = Term::Cons(
|
||||
for c in s.chars().rev() {
|
||||
list = Term::Cons(
|
||||
Cell::default(),
|
||||
Box::new(Term::Constant(
|
||||
Cell::default(),
|
||||
Box::new(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Fixnum(c as isize),
|
||||
)),
|
||||
Box::new(list),
|
||||
);
|
||||
}
|
||||
|
||||
self.terms.push(list);
|
||||
TokenType::Term
|
||||
Constant::Fixnum(c as isize),
|
||||
)),
|
||||
Box::new(list),
|
||||
);
|
||||
}
|
||||
|
||||
self.terms.push(list);
|
||||
TokenType::Term
|
||||
}
|
||||
Token::Constant(c) => {
|
||||
self.terms.push(Term::Constant(Cell::default(), c));
|
||||
TokenType::Term
|
||||
},
|
||||
}
|
||||
Token::Var(v) => {
|
||||
if v.trim() == "_" {
|
||||
self.terms.push(Term::AnonVar);
|
||||
@@ -360,7 +360,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
}
|
||||
|
||||
TokenType::Term
|
||||
},
|
||||
}
|
||||
Token::Comma => TokenType::Comma,
|
||||
Token::Open => TokenType::Open,
|
||||
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(desc2) = 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);
|
||||
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);
|
||||
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);
|
||||
continue;
|
||||
} 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;
|
||||
|
||||
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 {
|
||||
return None;
|
||||
} 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
|
||||
}
|
||||
|
||||
fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool
|
||||
{
|
||||
fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool {
|
||||
if self.stack.is_empty() {
|
||||
return false;
|
||||
}
|
||||
@@ -464,7 +458,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
|
||||
let arity = match self.compute_arity_in_brackets() {
|
||||
Some(arity) => arity,
|
||||
None => return false
|
||||
None => return false,
|
||||
};
|
||||
|
||||
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() {
|
||||
self.stack.truncate(stack_len + 1);
|
||||
|
||||
let mut subterms: Vec<_> = self.terms.drain(idx ..)
|
||||
.map(|t| Box::new(t))
|
||||
.collect();
|
||||
let mut subterms: Vec<_> = self.terms.drain(idx..).map(Box::new).collect();
|
||||
|
||||
if let Some(name) = self.terms.pop().and_then(|t| self.atomize_term(&t)) {
|
||||
// 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));
|
||||
} else {
|
||||
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,
|
||||
ref mut tt }) = self.stack.last_mut()
|
||||
if let Some(&mut TokenDesc {
|
||||
ref mut priority,
|
||||
ref mut spec,
|
||||
ref mut tt,
|
||||
}) = self.stack.last_mut()
|
||||
{
|
||||
*tt = TokenType::Term;
|
||||
*priority = 0;
|
||||
@@ -523,7 +519,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
}
|
||||
|
||||
pub fn devour_whitespace(&mut self) -> Result<(), ParserError> {
|
||||
self.lexer.scan_for_layout()?;
|
||||
self.lexer.scan_for_layout()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -531,8 +527,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
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() {
|
||||
let op_desc = self.stack[index - 1];
|
||||
|
||||
@@ -548,8 +543,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
self.terms.extend(terms.into_iter());
|
||||
return arity;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,12 +553,12 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
0
|
||||
}
|
||||
|
||||
fn compute_arity_in_list(&self) -> Option<usize>
|
||||
{
|
||||
fn compute_arity_in_list(&self) -> Option<usize> {
|
||||
let mut arity = 0;
|
||||
|
||||
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 {
|
||||
return None;
|
||||
} else if is_term!(desc.spec) || is_op!(desc.spec) {
|
||||
@@ -590,8 +584,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
None
|
||||
}
|
||||
|
||||
fn reduce_list(&mut self) -> Result<bool, ParserError>
|
||||
{
|
||||
fn reduce_list(&mut self) -> Result<bool, ParserError> {
|
||||
if self.stack.is_empty() {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -602,7 +595,8 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
td.tt = TokenType::Term;
|
||||
td.priority = 0;
|
||||
|
||||
self.terms.push(Term::Constant(Cell::default(), Constant::EmptyList));
|
||||
self.terms
|
||||
.push(Term::Constant(Cell::default(), Constant::EmptyList));
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
@@ -611,7 +605,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
|
||||
let mut arity = match self.compute_arity_in_list() {
|
||||
Some(arity) => arity,
|
||||
None => return Ok(false)
|
||||
None => return Ok(false),
|
||||
};
|
||||
|
||||
// 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 {
|
||||
Term::Constant(Cell::default(), Constant::EmptyList)
|
||||
} else {
|
||||
let term =
|
||||
match self.terms.pop() {
|
||||
Some(term) => term,
|
||||
_ => return Err(ParserError::IncompleteReduction(self.lexer.line_num,
|
||||
self.lexer.col_num))
|
||||
};
|
||||
let term = match self.terms.pop() {
|
||||
Some(term) => term,
|
||||
_ => {
|
||||
return Err(ParserError::IncompleteReduction(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
if self.stack[idx].priority > 1000 {
|
||||
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 list = self.terms.drain(idx ..)
|
||||
.rev()
|
||||
.fold(end_term, |acc, t| Term::Cons(Cell::default(),
|
||||
Box::new(t),
|
||||
Box::new(acc)));
|
||||
let list = self.terms.drain(idx..).rev().fold(end_term, |acc, t| {
|
||||
Term::Cons(Cell::default(), Box::new(t), Box::new(acc))
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
Ok(true)
|
||||
@@ -664,8 +663,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
td.priority = 0;
|
||||
td.spec = TERM;
|
||||
|
||||
let term = Term::Constant(Cell::default(),
|
||||
atom!("{}", self.lexer.atom_tbl));
|
||||
let term = Term::Constant(Cell::default(), atom!("{}", self.lexer.atom_tbl));
|
||||
self.terms.push(term);
|
||||
return Ok(true);
|
||||
}
|
||||
@@ -687,17 +685,19 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
|
||||
let term = match self.terms.pop() {
|
||||
Some(term) => term,
|
||||
_ => return Err(ParserError::IncompleteReduction(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
))
|
||||
_ => {
|
||||
return Err(ParserError::IncompleteReduction(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
self.terms.push(Term::Clause(
|
||||
Cell::default(),
|
||||
clause_name!("{}"),
|
||||
vec![Box::new(term)],
|
||||
None
|
||||
None,
|
||||
));
|
||||
|
||||
return Ok(true);
|
||||
@@ -722,35 +722,40 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
|
||||
let idx = self.stack.len() - 2;
|
||||
|
||||
match self.stack.remove(idx) {
|
||||
td =>
|
||||
match td.tt {
|
||||
TokenType::Open | TokenType::OpenCT => {
|
||||
if self.stack[idx].tt == TokenType::Comma {
|
||||
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
|
||||
let td = self.stack.remove(idx);
|
||||
match td.tt {
|
||||
TokenType::Open | TokenType::OpenCT => {
|
||||
if self.stack[idx].tt == TokenType::Comma {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? {
|
||||
// do this when layout hasn't been inserted,
|
||||
// ie. why we don't match on Token::Open.
|
||||
&Token::OpenCT => {
|
||||
Token::OpenCT => {
|
||||
// can't be prefix, so either inf == 0
|
||||
// or post == 0.
|
||||
self.reduce_op(inf + post);
|
||||
@@ -764,7 +769,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
spec & (XFX | XFY | YFX | YF | XF),
|
||||
op_dir_val,
|
||||
);
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
self.reduce_op(inf + post);
|
||||
|
||||
@@ -782,11 +787,21 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
);
|
||||
} else {
|
||||
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 {
|
||||
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)
|
||||
} else { // not an operator.
|
||||
} else {
|
||||
// not an operator.
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn atomize_term(&self, term: &Term) -> Option<ClauseName> {
|
||||
match term {
|
||||
&Term::Constant(_, ref c) => self.atomize_constant(c),
|
||||
_ => None
|
||||
Term::Constant(_, ref c) => self.atomize_constant(c),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn atomize_constant(&self, c: &Constant) -> Option<ClauseName> {
|
||||
match c {
|
||||
&Constant::Atom(ref name, _) => Some(name.clone()),
|
||||
&Constant::Char(c) =>
|
||||
Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
||||
&Constant::EmptyList =>
|
||||
Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
||||
_ => None
|
||||
Constant::Atom(ref name, _) => Some(name.clone()),
|
||||
Constant::Char(c) => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
||||
Constant::EmptyList => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn negate_number<N, Negator, ToConstant>(
|
||||
&mut self,
|
||||
n: N,
|
||||
negator: Negator,
|
||||
constr: ToConstant
|
||||
)
|
||||
where Negator: Fn(N) -> N,
|
||||
ToConstant: Fn(N) -> Constant
|
||||
fn negate_number<N, Negator, ToConstant>(&mut self, n: N, negator: Negator, constr: ToConstant)
|
||||
where
|
||||
Negator: Fn(N) -> N,
|
||||
ToConstant: Fn(N) -> Constant,
|
||||
{
|
||||
if let Some(desc) = self.stack.last().cloned() {
|
||||
if let Some(term) = self.terms.last().cloned() {
|
||||
match term {
|
||||
Term::Constant(_, Constant::Atom(ref name, _))
|
||||
if name.as_str() == "-" && (is_prefix!(desc.spec) || is_negate!(desc.spec)) => {
|
||||
self.stack.pop();
|
||||
self.terms.pop();
|
||||
if name.as_str() == "-"
|
||||
&& (is_prefix!(desc.spec) || is_negate!(desc.spec)) =>
|
||||
{
|
||||
self.stack.pop();
|
||||
self.terms.pop();
|
||||
|
||||
self.shift(Token::Constant(constr(negator(n))), 0, TERM);
|
||||
return;
|
||||
},
|
||||
self.shift(Token::Constant(constr(negator(n))), 0, TERM);
|
||||
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 negate_rc<T: NegAssign>(mut t: Rc<T>) -> Rc<T> {
|
||||
match Rc::get_mut(&mut t) {
|
||||
Some(t) => {
|
||||
t.neg_assign();
|
||||
}
|
||||
None => {
|
||||
}
|
||||
if let Some(t) = Rc::get_mut(&mut t) {
|
||||
t.neg_assign();
|
||||
};
|
||||
|
||||
t
|
||||
}
|
||||
|
||||
match token {
|
||||
Token::Constant(Constant::Fixnum(n)) =>
|
||||
self.negate_number(n, |n| -n, Constant::Fixnum),
|
||||
Token::Constant(Constant::Integer(n)) =>
|
||||
self.negate_number(n, negate_rc, Constant::Integer),
|
||||
Token::Constant(Constant::Rational(n)) =>
|
||||
self.negate_number(n, negate_rc, Constant::Rational),
|
||||
Token::Constant(Constant::Float(n)) =>
|
||||
self.negate_number(
|
||||
n,
|
||||
|n| OrderedFloat(-n.into_inner()),
|
||||
|n| Constant::Float(n)
|
||||
),
|
||||
Token::Constant(c) =>
|
||||
Token::Constant(Constant::Fixnum(n)) => self.negate_number(n, |n| -n, Constant::Fixnum),
|
||||
Token::Constant(Constant::Integer(n)) => {
|
||||
self.negate_number(n, negate_rc, Constant::Integer)
|
||||
}
|
||||
Token::Constant(Constant::Rational(n)) => {
|
||||
self.negate_number(n, negate_rc, Constant::Rational)
|
||||
}
|
||||
Token::Constant(Constant::Float(n)) => {
|
||||
self.negate_number(n, |n| OrderedFloat(-n.into_inner()), Constant::Float)
|
||||
}
|
||||
Token::Constant(c) => {
|
||||
if let Some(name) = self.atomize_constant(&c) {
|
||||
if !self.shift_op(name, op_dir)? {
|
||||
self.shift(Token::Constant(c), 0, TERM);
|
||||
}
|
||||
} else {
|
||||
self.shift(Token::Constant(c), 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::Close =>
|
||||
Token::Close => {
|
||||
if !self.reduce_term(op_dir) {
|
||||
if !self.reduce_brackets() {
|
||||
return Err(ParserError::IncompleteReduction(
|
||||
@@ -903,23 +910,26 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
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()? {
|
||||
return Err(ParserError::IncompleteReduction(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
));
|
||||
},
|
||||
}
|
||||
}
|
||||
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
|
||||
Token::CloseCurly =>
|
||||
Token::CloseCurly => {
|
||||
if !self.reduce_curly()? {
|
||||
return Err(ParserError::IncompleteReduction(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
));
|
||||
},
|
||||
}
|
||||
}
|
||||
Token::HeadTailSeparator => {
|
||||
/* '|' 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
|
||||
@@ -930,23 +940,25 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
|
||||
self.reduce_op(priority);
|
||||
self.shift(Token::HeadTailSeparator, priority, spec);
|
||||
},
|
||||
}
|
||||
Token::Comma => {
|
||||
self.reduce_op(1000);
|
||||
self.shift(Token::Comma, 1000, XFY);
|
||||
},
|
||||
Token::End =>
|
||||
match self.stack.last().map(|t| t.tt) {
|
||||
Some(TokenType::Open)
|
||||
| Some(TokenType::OpenCT)
|
||||
| Some(TokenType::OpenList)
|
||||
| Some(TokenType::OpenCurly)
|
||||
| Some(TokenType::HeadTailSeparator)
|
||||
| Some(TokenType::Comma)
|
||||
=> return Err(ParserError::IncompleteReduction(self.lexer.line_num,
|
||||
self.lexer.col_num)),
|
||||
_ => {}
|
||||
}
|
||||
Token::End => match self.stack.last().map(|t| t.tt) {
|
||||
Some(TokenType::Open)
|
||||
| Some(TokenType::OpenCT)
|
||||
| Some(TokenType::OpenList)
|
||||
| Some(TokenType::OpenCurly)
|
||||
| Some(TokenType::HeadTailSeparator)
|
||||
| Some(TokenType::Comma) => {
|
||||
return Err(ParserError::IncompleteReduction(
|
||||
self.lexer.line_num,
|
||||
self.lexer.col_num,
|
||||
))
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -957,8 +969,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
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)?;
|
||||
|
||||
while let Some(token) = self.tokens.pop() {
|
||||
@@ -968,21 +979,31 @@ impl<'a, R: Read> Parser<'a, R> {
|
||||
self.reduce_op(1400);
|
||||
|
||||
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() {
|
||||
Some(term) => if self.terms.is_empty() {
|
||||
Ok(term)
|
||||
} else {
|
||||
Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num))
|
||||
},
|
||||
_ => Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num))
|
||||
Some(term) => {
|
||||
if self.terms.is_empty() {
|
||||
Ok(term)
|
||||
} else {
|
||||
Err(ParserError::IncompleteReduction(
|
||||
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();
|
||||
|
||||
loop {
|
||||
|
||||
@@ -4,11 +4,11 @@ use std::collections::HashSet;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::rc::{Rc};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct TabledData<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> {
|
||||
@@ -22,14 +22,15 @@ impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> {
|
||||
|
||||
impl<T> Clone for TabledData<T> {
|
||||
fn clone(&self) -> Self {
|
||||
TabledData { table: self.table.clone(),
|
||||
module_name: self.module_name.clone() }
|
||||
TabledData {
|
||||
table: self.table.clone(),
|
||||
module_name: self.module_name.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -39,7 +40,7 @@ impl<T: Hash + Eq> TabledData<T> {
|
||||
pub fn new(module_name: Rc<String>) -> Self {
|
||||
TabledData {
|
||||
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(crate) atom: Rc<T>,
|
||||
pub table: TabledData<T>
|
||||
pub table: TabledData<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.
|
||||
impl<T: Hash + Eq> Clone for TabledRc<T> {
|
||||
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> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
|
||||
{
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.atom.cmp(&other.atom))
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -103,8 +104,8 @@ impl<T: Hash + Eq> Hash for TabledRc<T> {
|
||||
impl<T: Hash + Eq + ToString> TabledRc<T> {
|
||||
pub fn new(atom: T, table: TabledData<T>) -> Self {
|
||||
let atom = match table.borrow_mut().take(&atom) {
|
||||
Some(atom) => atom.clone(),
|
||||
None => Rc::new(atom)
|
||||
Some(atom) => atom,
|
||||
None => Rc::new(atom),
|
||||
};
|
||||
|
||||
table.borrow_mut().insert(atom.clone());
|
||||
@@ -147,7 +148,7 @@ impl<T: Hash + Eq + fmt::Display> fmt::Display for TabledRc<T> {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! tabled_rc {
|
||||
($e:expr, $tbl:expr) => (
|
||||
TabledRc::new(String::from($e), $tbl.clone())
|
||||
)
|
||||
($e:expr, $tbl:expr) => {
|
||||
$crate::tabled_rc::TabledRc::new(String::from($e), $tbl.clone())
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
extern crate prolog_parser_rebis;
|
||||
|
||||
use prolog_parser_rebis::ast::*;
|
||||
use prolog_parser_rebis::lexer::{Lexer, Token};
|
||||
use prolog_parser_rebis::tabled_rc::TabledData;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::lexer::{Lexer, Token};
|
||||
use prolog_parser::tabled_rc::TabledData;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -27,7 +25,7 @@ fn skip_utf8_bom() {
|
||||
let mut lexer = Lexer::new(atom_tbl, flags, &mut stream);
|
||||
match lexer.next_token() {
|
||||
Ok(Token::Constant(Constant::Fixnum(4))) => (),
|
||||
_ => assert!(false)
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +35,6 @@ fn invalid_utf16_bom() {
|
||||
let stream = parsing_stream(bytes);
|
||||
match stream {
|
||||
Err(ParserError::Utf8Error(0, 0)) => (),
|
||||
_ => assert!(false)
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
extern crate prolog_parser_rebis;
|
||||
|
||||
use prolog_parser_rebis::ast::*;
|
||||
use prolog_parser_rebis::lexer::{Lexer, Token};
|
||||
use prolog_parser_rebis::tabled_rc::TabledData;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::lexer::{Lexer, Token};
|
||||
use prolog_parser::tabled_rc::TabledData;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::temp_v;
|
||||
|
||||
use crate::fixtures::*;
|
||||
use crate::forms::*;
|
||||
@@ -14,8 +15,13 @@ pub trait Allocator<'a> {
|
||||
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
||||
where
|
||||
Target: CompilationTarget<'a>;
|
||||
fn mark_non_var<Target>(&mut self, _: Level, _: GenContext, _: &'a Cell<RegType>, _: &mut Vec<Target>)
|
||||
where
|
||||
fn mark_non_var<Target>(
|
||||
&mut self,
|
||||
_: Level,
|
||||
_: GenContext,
|
||||
_: &'a Cell<RegType>,
|
||||
_: &mut Vec<Target>,
|
||||
) where
|
||||
Target: CompilationTarget<'a>;
|
||||
fn mark_reserved_var<Target>(
|
||||
&mut self,
|
||||
@@ -28,8 +34,14 @@ pub trait Allocator<'a> {
|
||||
_: bool,
|
||||
) where
|
||||
Target: CompilationTarget<'a>;
|
||||
fn mark_var<Target>(&mut self, _: Rc<Var>, _: Level, _: &'a Cell<VarReg>, _: GenContext, _: &mut Vec<Target>)
|
||||
where
|
||||
fn mark_var<Target>(
|
||||
&mut self,
|
||||
_: Rc<Var>,
|
||||
_: Level,
|
||||
_: &'a Cell<VarReg>,
|
||||
_: GenContext,
|
||||
_: &mut Vec<Target>,
|
||||
) where
|
||||
Target: CompilationTarget<'a>;
|
||||
|
||||
fn reset(&mut self);
|
||||
@@ -47,7 +59,7 @@ pub trait Allocator<'a> {
|
||||
fn drain_var_data(
|
||||
&mut self,
|
||||
vs: VariableFixtures<'a>,
|
||||
num_of_chunks: usize
|
||||
num_of_chunks: usize,
|
||||
) -> VariableFixtures<'a> {
|
||||
let mut perm_vs = VariableFixtures::new();
|
||||
|
||||
|
||||
@@ -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::fixtures::*;
|
||||
@@ -10,9 +11,9 @@ use crate::machine::heap::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
|
||||
use crate::ordered_float::*;
|
||||
use crate::rug::ops::PowAssign;
|
||||
use crate::rug::{Assign, Integer, Rational};
|
||||
use ordered_float::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp::{max, min, Ordering};
|
||||
@@ -267,9 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
|
||||
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
|
||||
match c {
|
||||
&Constant::Fixnum(n) => self
|
||||
.interm
|
||||
.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
||||
&Constant::Fixnum(n) => self.interm.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
||||
&Constant::Integer(ref n) => self
|
||||
.interm
|
||||
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
|
||||
@@ -326,17 +325,11 @@ impl<'a> ArithmeticEvaluator<'a> {
|
||||
// integer division rounding function -- 9.1.3.1.
|
||||
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
|
||||
match n {
|
||||
&Number::Integer(_) => {
|
||||
RefOrOwned::Borrowed(n)
|
||||
}
|
||||
&Number::Float(OrderedFloat(f)) => {
|
||||
RefOrOwned::Owned(Number::from(
|
||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))
|
||||
))
|
||||
}
|
||||
&Number::Fixnum(n) => {
|
||||
RefOrOwned::Owned(Number::from(n))
|
||||
}
|
||||
&Number::Integer(_) => RefOrOwned::Borrowed(n),
|
||||
&Number::Float(OrderedFloat(f)) => RefOrOwned::Owned(Number::from(
|
||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
|
||||
)),
|
||||
&Number::Fixnum(n) => RefOrOwned::Owned(Number::from(n)),
|
||||
&Number::Rational(ref r) => {
|
||||
let r_ref = r.fract_floor_ref();
|
||||
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::Fixnum(n1), Number::Integer(n2)) |
|
||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Integer(n2))
|
||||
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Integer::from(n1) + &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Rational(n2))
|
||||
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Rational::from(n1) + &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i
|
||||
}
|
||||
(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)?))
|
||||
}
|
||||
(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))
|
||||
}
|
||||
(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)?))
|
||||
}
|
||||
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
|
||||
@@ -474,12 +467,13 @@ impl Neg for Number {
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
match self {
|
||||
Number::Fixnum(n) =>
|
||||
Number::Fixnum(n) => {
|
||||
if let Some(n) = n.checked_neg() {
|
||||
Number::Fixnum(n)
|
||||
} else {
|
||||
Number::from(-Integer::from(n))
|
||||
}
|
||||
}
|
||||
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
|
||||
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
|
||||
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::Fixnum(n1), Number::Integer(n2)) |
|
||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Integer(n2))
|
||||
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Integer::from(n1) * &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Rational(n2))
|
||||
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||
Ok(Number::from(Rational::from(n1) * &*n2))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||
@@ -549,72 +543,50 @@ impl Div<Number> for Number {
|
||||
|
||||
fn div(self, rhs: Number) -> Self::Output {
|
||||
match (self, rhs) {
|
||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_i_to_f(&n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Fixnum(n1), Number::Rational(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::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?)),
|
||||
(Number::Fixnum(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
float_i_to_f(&n2)?,
|
||||
)?)),
|
||||
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_fn_to_f(n2)?,
|
||||
)?)),
|
||||
(Number::Fixnum(n1), Number::Rational(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))) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_fn_to_f(n1)?,
|
||||
n2,
|
||||
)?))
|
||||
Ok(Number::Float(div_f(float_fn_to_f(n1)?, n2)?))
|
||||
}
|
||||
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
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)?,
|
||||
)?))
|
||||
Ok(Number::Float(div_f(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::Float(OrderedFloat(n2))) => {
|
||||
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
|
||||
}
|
||||
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Rational(n2)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_r_to_f(&n2)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Rational(n2), Number::Integer(n1)) => {
|
||||
Ok(Number::Float(div_f(
|
||||
float_r_to_f(&n2)?,
|
||||
float_i_to_f(&n1)?,
|
||||
)?))
|
||||
}
|
||||
(Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||
float_i_to_f(&n1)?,
|
||||
float_r_to_f(&n2)?,
|
||||
)?)),
|
||||
(Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
|
||||
float_r_to_f(&n2)?,
|
||||
float_i_to_f(&n1)?,
|
||||
)?)),
|
||||
(Number::Rational(n1), Number::Float(OrderedFloat(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> {
|
||||
match addr {
|
||||
Addr::Fixnum(n) => {
|
||||
Ok(Number::from(n))
|
||||
}
|
||||
Addr::Float(n) => {
|
||||
Ok(Number::Float(n))
|
||||
}
|
||||
Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||
Addr::Float(n) => Ok(Number::Float(n)),
|
||||
Addr::Usize(n) => {
|
||||
if let Ok(n) = isize::try_from(n) {
|
||||
Ok(Number::from(n))
|
||||
@@ -740,12 +708,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
||||
Ok(Number::from(Integer::from(n)))
|
||||
}
|
||||
}
|
||||
Addr::Con(h) => {
|
||||
Number::try_from(&heap[h])
|
||||
}
|
||||
_ => {
|
||||
Err(())
|
||||
}
|
||||
Addr::Con(h) => Number::try_from(&heap[h]),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -755,35 +719,21 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
|
||||
|
||||
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
|
||||
match value {
|
||||
HeapCellValue::Addr(addr) => {
|
||||
match addr {
|
||||
&Addr::Fixnum(n) => {
|
||||
HeapCellValue::Addr(addr) => match addr {
|
||||
&Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||
&Addr::Float(n) => Ok(Number::Float(n)),
|
||||
&Addr::Usize(n) => {
|
||||
if let Ok(n) = isize::try_from(n) {
|
||||
Ok(Number::from(n))
|
||||
}
|
||||
&Addr::Float(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(())
|
||||
} else {
|
||||
Ok(Number::from(Integer::from(n)))
|
||||
}
|
||||
}
|
||||
}
|
||||
HeapCellValue::Integer(n) => {
|
||||
Ok(Number::Integer(n.clone()))
|
||||
}
|
||||
HeapCellValue::Rational(n) => {
|
||||
Ok(Number::Rational(n.clone()))
|
||||
}
|
||||
_ => {
|
||||
Err(())
|
||||
}
|
||||
_ => Err(()),
|
||||
},
|
||||
HeapCellValue::Integer(n) => Ok(Number::Integer(n.clone())),
|
||||
HeapCellValue::Rational(n) => Ok(Number::Rational(n.clone())),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::machine::machine_indices::*;
|
||||
use crate::rug::rand::RandState;
|
||||
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
use ref_thread_local::{ref_thread_local, RefThreadLocal};
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@@ -150,11 +151,6 @@ impl InlinedClauseType {
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum SystemClauseType {
|
||||
// AbolishClause,
|
||||
// AbolishModuleClause,
|
||||
// AssertDynamicPredicateToBack,
|
||||
// AssertDynamicPredicateToFront,
|
||||
// AtEndOfExpansion,
|
||||
AtomChars,
|
||||
AtomCodes,
|
||||
AtomLength,
|
||||
@@ -189,8 +185,6 @@ pub enum SystemClauseType {
|
||||
DynamicModuleResolution(usize),
|
||||
EnqueueAttributeGoal,
|
||||
EnqueueAttributedVar,
|
||||
// ExpandGoal,
|
||||
// ExpandTerm,
|
||||
FetchGlobalVar,
|
||||
FetchGlobalVarWithOffset,
|
||||
FirstStream,
|
||||
@@ -207,16 +201,13 @@ pub enum SystemClauseType {
|
||||
GetAttrVarQueueDelimiter,
|
||||
GetAttrVarQueueBeyond,
|
||||
GetBValue,
|
||||
// GetClause,
|
||||
GetContinuationChunk,
|
||||
// GetModuleClause,
|
||||
GetNextDBRef,
|
||||
GetNextOpDBRef,
|
||||
IsPartialString,
|
||||
LookupDBRef,
|
||||
LookupOpDBRef,
|
||||
Halt,
|
||||
// ModuleHeadIsDynamic,
|
||||
GetLiftedHeapFromOffset,
|
||||
GetLiftedHeapFromOffsetDiff,
|
||||
GetSCCCleaner,
|
||||
@@ -225,10 +216,7 @@ pub enum SystemClauseType {
|
||||
InstallInferenceCounter,
|
||||
LiftedHeapLength,
|
||||
LoadLibraryAsStream,
|
||||
// ModuleAssertDynamicPredicateToFront,
|
||||
// ModuleAssertDynamicPredicateToBack,
|
||||
ModuleExists,
|
||||
// ModuleRetractClause,
|
||||
NextEP,
|
||||
NoSuchPredicate,
|
||||
NumberToChars,
|
||||
@@ -254,7 +242,6 @@ pub enum SystemClauseType {
|
||||
ResetContinuationMarker,
|
||||
ResetGlobalVarAtKey,
|
||||
ResetGlobalVarAtOffset,
|
||||
// RetractClause,
|
||||
RestoreCutPolicy,
|
||||
SetCutPoint(RegType),
|
||||
SetInput,
|
||||
@@ -324,11 +311,6 @@ pub enum SystemClauseType {
|
||||
impl SystemClauseType {
|
||||
pub fn name(&self) -> ClauseName {
|
||||
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::AtomCodes => clause_name!("$atom_codes"),
|
||||
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
|
||||
@@ -341,7 +323,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
||||
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
|
||||
&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::CurrentInput => clause_name!("$current_input"),
|
||||
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
||||
@@ -356,52 +340,70 @@ impl SystemClauseType {
|
||||
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
||||
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
||||
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) =>
|
||||
clause_name!("$add_dynamic_predicate"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) =>
|
||||
clause_name!("$add_goal_expansion_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) =>
|
||||
clause_name!("$add_term_expansion_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) =>
|
||||
clause_name!("$clause_to_evacuable"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) =>
|
||||
clause_name!("$conclude_load"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) =>
|
||||
clause_name!("$declare_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) =>
|
||||
clause_name!("$load_compiled_library"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) =>
|
||||
clause_name!("$push_load_state_payload"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UserAsserta) =>
|
||||
clause_name!("$asserta"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UserAssertz) =>
|
||||
clause_name!("$assertz"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UserRetract) =>
|
||||
clause_name!("$retract_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) =>
|
||||
clause_name!("$use_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) =>
|
||||
clause_name!("$push_load_context"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) =>
|
||||
clause_name!("$pop_load_context"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) =>
|
||||
clause_name!("$pop_load_state_payload"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) =>
|
||||
clause_name!("$prolog_lc_source"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) =>
|
||||
clause_name!("$prolog_lc_file"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) =>
|
||||
clause_name!("$prolog_lc_dir"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) =>
|
||||
clause_name!("$prolog_lc_module"),
|
||||
&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::CompilePendingPredicates) =>
|
||||
clause_name!("$compile_pending_predicates"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => {
|
||||
clause_name!("$add_dynamic_predicate")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
|
||||
clause_name!("$add_goal_expansion_clause")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
|
||||
clause_name!("$add_term_expansion_clause")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
|
||||
clause_name!("$clause_to_evacuable")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
|
||||
clause_name!("$load_compiled_library")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
|
||||
clause_name!("$push_load_state_payload")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => {
|
||||
clause_name!("$push_load_context")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => {
|
||||
clause_name!("$pop_load_context")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => {
|
||||
clause_name!("$pop_load_state_payload")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => {
|
||||
clause_name!("$prolog_lc_source")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => {
|
||||
clause_name!("$prolog_lc_file")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => {
|
||||
clause_name!("$prolog_lc_dir")
|
||||
}
|
||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => {
|
||||
clause_name!("$prolog_lc_module")
|
||||
}
|
||||
&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::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
||||
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
||||
@@ -410,8 +412,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
||||
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
||||
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
||||
&SystemClauseType::FetchGlobalVarWithOffset =>
|
||||
clause_name!("$fetch_global_var_with_offset"),
|
||||
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||
clause_name!("$fetch_global_var_with_offset")
|
||||
}
|
||||
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
||||
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
||||
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
||||
@@ -437,13 +440,13 @@ impl SystemClauseType {
|
||||
clause_name!("$get_lh_from_offset_diff")
|
||||
}
|
||||
&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::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"),
|
||||
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
|
||||
&SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"),
|
||||
&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::Halt => clause_name!("$halt"),
|
||||
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
|
||||
@@ -468,7 +471,7 @@ impl SystemClauseType {
|
||||
// &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
|
||||
// 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::NextStream => clause_name!("$next_stream"),
|
||||
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
|
||||
@@ -520,7 +523,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
||||
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
||||
&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::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
||||
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
||||
@@ -534,7 +539,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
|
||||
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
|
||||
&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::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
||||
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
||||
@@ -555,7 +562,9 @@ impl SystemClauseType {
|
||||
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
||||
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
||||
&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::LoadHTML => clause_name!("$load_html"),
|
||||
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
||||
@@ -569,21 +578,21 @@ impl SystemClauseType {
|
||||
|
||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||
match (name, arity) {
|
||||
// ("$abolish_clause", 2) => Some(SystemClauseType::AbolishClause),
|
||||
("$add_dynamic_predicate", 3) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate)),
|
||||
("$add_goal_expansion_clause", 4) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)),
|
||||
("$add_term_expansion_clause", 3) =>
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)),
|
||||
// ("$at_end_of_expansion", 0) => Some(SystemClauseType::AtEndOfExpansion),
|
||||
("$abolish_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
||||
("$add_dynamic_predicate", 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
|
||||
}
|
||||
("$add_goal_expansion_clause", 4) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
|
||||
}
|
||||
("$add_term_expansion_clause", 3) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
|
||||
}
|
||||
("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
|
||||
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
|
||||
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
|
||||
// ("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause),
|
||||
("$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),
|
||||
("$char_code", 2) => Some(SystemClauseType::CharCode),
|
||||
("$char_type", 2) => Some(SystemClauseType::CharType),
|
||||
@@ -616,10 +625,10 @@ impl SystemClauseType {
|
||||
("$peek_char", 2) => Some(SystemClauseType::PeekChar),
|
||||
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
||||
("$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_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
||||
("$fetch_global_var_with_offset", 3) => {
|
||||
Some(SystemClauseType::FetchGlobalVarWithOffset)
|
||||
}
|
||||
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
||||
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
||||
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
||||
@@ -628,18 +637,10 @@ impl SystemClauseType {
|
||||
("$points_to_cont_reset_marker", 1) => {
|
||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||
}
|
||||
("$put_byte", 2) => {
|
||||
Some(SystemClauseType::PutByte)
|
||||
}
|
||||
("$put_char", 2) => {
|
||||
Some(SystemClauseType::PutChar)
|
||||
}
|
||||
("$put_chars", 2) => {
|
||||
Some(SystemClauseType::PutChars)
|
||||
}
|
||||
("$put_code", 2) => {
|
||||
Some(SystemClauseType::PutCode)
|
||||
}
|
||||
("$put_byte", 2) => Some(SystemClauseType::PutByte),
|
||||
("$put_char", 2) => Some(SystemClauseType::PutChar),
|
||||
("$put_chars", 2) => Some(SystemClauseType::PutChars),
|
||||
("$put_code", 2) => Some(SystemClauseType::PutCode),
|
||||
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
||||
("$truncate_if_no_lh_growth", 1) => {
|
||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
||||
@@ -649,8 +650,6 @@ impl SystemClauseType {
|
||||
}
|
||||
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
|
||||
("$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_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
||||
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||
@@ -664,8 +663,6 @@ impl SystemClauseType {
|
||||
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
|
||||
("$current_time", 1) => Some(SystemClauseType::CurrentTime),
|
||||
("$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),
|
||||
("$number_to_chars", 2) => Some(SystemClauseType::NumberToChars),
|
||||
("$number_to_codes", 2) => Some(SystemClauseType::NumberToCodes),
|
||||
@@ -700,7 +697,6 @@ impl SystemClauseType {
|
||||
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
|
||||
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
|
||||
("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
|
||||
// ("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
|
||||
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
|
||||
("$set_ball", 1) => Some(SystemClauseType::SetBall),
|
||||
("$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_close", 1) => Some(SystemClauseType::SocketServerClose),
|
||||
("$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_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||
@@ -730,15 +728,21 @@ impl SystemClauseType {
|
||||
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
||||
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
||||
("$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)),
|
||||
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
||||
("$load_compiled_library", 2) => Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary)),
|
||||
("$push_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)),
|
||||
("$asserta", 4) => Some(SystemClauseType::REPL(REPLCodePtr::UserAsserta)),
|
||||
("$assertz", 4) => Some(SystemClauseType::REPL(REPLCodePtr::UserAssertz)),
|
||||
("$retract_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UserRetract)),
|
||||
("$load_compiled_library", 2) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
|
||||
}
|
||||
("$push_load_state_payload", 1) => {
|
||||
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),
|
||||
("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions),
|
||||
("$write_term", 7) => Some(SystemClauseType::WriteTerm),
|
||||
@@ -764,16 +768,38 @@ impl SystemClauseType {
|
||||
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
||||
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
||||
("$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)),
|
||||
("$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_dir", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory)),
|
||||
("$prolog_lc_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule)),
|
||||
("$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)),
|
||||
("$compile_pending_predicates", 1) => Some(SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates)),
|
||||
("$prolog_lc_dir", 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
|
||||
}
|
||||
("$prolog_lc_module", 1) => {
|
||||
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
|
||||
}
|
||||
("$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,
|
||||
}
|
||||
}
|
||||
@@ -852,10 +878,10 @@ impl ClauseType {
|
||||
match self {
|
||||
&ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
|
||||
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
|
||||
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -863,7 +889,7 @@ impl ClauseType {
|
||||
pub fn name(&self) -> ClauseName {
|
||||
match self {
|
||||
&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::Op(ref name, ..) => name.clone(),
|
||||
&ClauseType::Named(ref name, ..) => name.clone(),
|
||||
@@ -882,7 +908,7 @@ impl ClauseType {
|
||||
.unwrap_or_else(|| {
|
||||
if let Some(spec) = spec {
|
||||
ClauseType::Op(name, spec, CodeIndex::default())
|
||||
} else if name.as_str() == "call" {
|
||||
} else if name.as_str() == "$call" {
|
||||
ClauseType::CallN
|
||||
} else {
|
||||
ClauseType::Named(name, arity, CodeIndex::default())
|
||||
|
||||
195
src/codegen.rs
195
src/codegen.rs
@@ -1,6 +1,7 @@
|
||||
/// Code generation to WAM-like instructions.
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::TabledData;
|
||||
use prolog_parser::{perm_v, temp_v};
|
||||
|
||||
use crate::allocator::*;
|
||||
use crate::arithmetic::*;
|
||||
@@ -14,7 +15,7 @@ use crate::targets::*;
|
||||
|
||||
use crate::machine::machine_errors::*;
|
||||
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -66,18 +67,14 @@ impl<'a> ConjunctInfo<'a> {
|
||||
self.has_deep_cut as usize
|
||||
}
|
||||
|
||||
fn mark_unsafe_vars(
|
||||
&self,
|
||||
mut unsafe_var_marker: UnsafeVarMarker,
|
||||
code: &mut Code,
|
||||
) {
|
||||
fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
|
||||
if code.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut code_index = 0;
|
||||
|
||||
for phase in 0 .. {
|
||||
for phase in 0.. {
|
||||
while let Line::Query(ref query_instr) = &code[code_index] {
|
||||
if !unsafe_var_marker.mark_safe_vars(query_instr) {
|
||||
unsafe_var_marker.mark_phase(query_instr, phase);
|
||||
@@ -95,7 +92,7 @@ impl<'a> ConjunctInfo<'a> {
|
||||
|
||||
code_index = 0;
|
||||
|
||||
for phase in 0 .. {
|
||||
for phase in 0.. {
|
||||
while let Line::Query(ref mut query_instr) = &mut code[code_index] {
|
||||
unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
|
||||
code_index += 1;
|
||||
@@ -173,7 +170,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
code: &mut Code,
|
||||
) -> RegType {
|
||||
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() {
|
||||
code.extend(target.into_iter().map(Line::Query));
|
||||
@@ -191,9 +189,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
code: &mut Code,
|
||||
) -> RegType {
|
||||
match self.marker.bindings().get(&name) {
|
||||
Some(&VarData::Temp(_, t, _)) if t != 0 => {
|
||||
RegType::Temp(t)
|
||||
}
|
||||
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
|
||||
Some(&VarData::Perm(p)) if p != 0 => {
|
||||
if let GenContext::Last(_) = term_loc {
|
||||
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)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
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>,
|
||||
) {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
&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()));
|
||||
}
|
||||
&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,
|
||||
iter: Iter,
|
||||
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) => {
|
||||
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() {
|
||||
for (i, chunked_term) in chunked_terms.iter().enumerate() {
|
||||
let term_loc = match chunked_term {
|
||||
&ChunkedTerm::HeadClause(..) =>
|
||||
GenContext::Head,
|
||||
&ChunkedTerm::HeadClause(..) => GenContext::Head,
|
||||
&ChunkedTerm::BodyTerm(_) => {
|
||||
if i < chunked_terms.len() - 1 {
|
||||
GenContext::Mid(chunk_num)
|
||||
@@ -391,8 +387,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
||||
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) => {
|
||||
*last_call = true;
|
||||
}
|
||||
&mut ControlInstruction::Proceed => {
|
||||
}
|
||||
&mut ControlInstruction::Proceed => {}
|
||||
_ => {
|
||||
dealloc_index += 1;
|
||||
}
|
||||
@@ -416,8 +410,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
||||
dealloc_index += 1;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
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 rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
||||
|
||||
let at_1 =
|
||||
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)
|
||||
)
|
||||
} else {
|
||||
at_1.unwrap_or(interm!(1))
|
||||
};
|
||||
let at_1 = 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))
|
||||
} else {
|
||||
at_1.unwrap_or(interm!(1))
|
||||
};
|
||||
|
||||
let at_2 =
|
||||
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)
|
||||
)
|
||||
} else {
|
||||
at_2.unwrap_or(interm!(2))
|
||||
};
|
||||
let at_2 = 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))
|
||||
} else {
|
||||
at_2.unwrap_or(interm!(2))
|
||||
};
|
||||
|
||||
code.append(&mut lcode);
|
||||
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));
|
||||
}
|
||||
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Char(_)) |
|
||||
&Term::Constant(_, Constant::EmptyList) |
|
||||
&Term::Constant(_, Constant::Atom(..)) => {
|
||||
&Term::Constant(_, Constant::Char(_))
|
||||
| &Term::Constant(_, Constant::EmptyList)
|
||||
| &Term::Constant(_, Constant::Atom(..)) => {
|
||||
code.push(succeed!());
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
@@ -528,11 +515,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Float(_)) |
|
||||
&Term::Constant(_, Constant::Rational(_)) |
|
||||
&Term::Constant(_, Constant::Integer(_)) |
|
||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
||||
&Term::Constant(_, Constant::Usize(_)) => {
|
||||
&Term::Constant(_, Constant::Float(_))
|
||||
| &Term::Constant(_, Constant::Rational(_))
|
||||
| &Term::Constant(_, Constant::Integer(_))
|
||||
| &Term::Constant(_, Constant::Fixnum(_))
|
||||
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||
code.push(succeed!());
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
@@ -558,9 +545,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
}
|
||||
},
|
||||
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Integer(_)) |
|
||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
||||
&Term::Constant(_, Constant::Usize(_)) => {
|
||||
&Term::Constant(_, Constant::Integer(_))
|
||||
| &Term::Constant(_, Constant::Fixnum(_))
|
||||
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||
code.push(succeed!());
|
||||
}
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
@@ -615,14 +602,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
&Term::Var(ref vr, ref name) => {
|
||||
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() {
|
||||
code.extend(target.into_iter().map(Line::Query));
|
||||
}
|
||||
}
|
||||
&Term::Constant(_, ref c @ Constant::Integer(_)) |
|
||||
&Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
||||
&Term::Constant(_, ref c @ Constant::Integer(_))
|
||||
| &Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
||||
code.push(Line::Query(put_constant!(
|
||||
Level::Shallow,
|
||||
c.clone(),
|
||||
@@ -655,14 +643,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
}
|
||||
}
|
||||
|
||||
let at =
|
||||
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)
|
||||
)
|
||||
} else {
|
||||
at.unwrap_or(interm!(1))
|
||||
};
|
||||
let at = 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))
|
||||
} else {
|
||||
at.unwrap_or(interm!(1))
|
||||
};
|
||||
|
||||
Ok(if use_default_call_policy {
|
||||
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) => {
|
||||
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
|
||||
}
|
||||
&QueryTerm::UnblockedCut(ref cell) => {
|
||||
self.compile_unblocked_cut(code, cell)
|
||||
}
|
||||
&QueryTerm::BlockedCut => {
|
||||
code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut)
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||
})
|
||||
}
|
||||
&QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
|
||||
&QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
|
||||
Line::Cut(CutInstruction::NeckCut)
|
||||
} else {
|
||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||
}),
|
||||
&QueryTerm::Clause(
|
||||
_,
|
||||
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
||||
ref terms,
|
||||
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, _) => {
|
||||
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.
|
||||
match toc {
|
||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
||||
@@ -786,7 +770,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
if conjunct_info.allocates() {
|
||||
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 {
|
||||
*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);
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
let conjunct_info = self.collect_var_data(iter);
|
||||
/*
|
||||
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
let conjunct_info = self.collect_var_data(iter);
|
||||
|
||||
let mut code = Vec::new();
|
||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||
let mut code = Vec::new();
|
||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
self.compile_seq(iter, &conjunct_info, &mut code, true)?;
|
||||
let iter = ChunkedIterator::from_term_sequence(query);
|
||||
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() {
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
||||
if let Some(query_term) = query.last() {
|
||||
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
||||
}
|
||||
|
||||
Ok(code)
|
||||
}
|
||||
|
||||
Ok(code)
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
fn increment_jmp_by_locs_by(&mut self, incr: usize) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1077,7 +1061,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
|
||||
if skip_stub_try_me_else {
|
||||
// skip the TryMeElse(0) also.
|
||||
self.increment_jmp_by_locs_by(2);
|
||||
self.increment_jmp_by_locs_by(2);
|
||||
} else {
|
||||
self.increment_jmp_by_locs_by(1);
|
||||
}
|
||||
@@ -1105,7 +1089,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
|
||||
for (l, r) in split_pred {
|
||||
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();
|
||||
|
||||
if multi_seq {
|
||||
@@ -1123,11 +1107,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||
if self.is_extensible {
|
||||
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_start_offset + 2 * (segment_is_indexed as usize);
|
||||
clause_index_info.opt_arg_index_key +=
|
||||
clause_start_offset + 1;
|
||||
clause_index_info.opt_arg_index_key += clause_start_offset + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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::fixtures::*;
|
||||
@@ -293,9 +294,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
||||
|
||||
(pr, true)
|
||||
}
|
||||
r => {
|
||||
(r, false)
|
||||
}
|
||||
r => (r, false),
|
||||
};
|
||||
|
||||
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use prolog_parser::ast::*;
|
||||
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
use crate::iterators::*;
|
||||
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::BTreeSet;
|
||||
@@ -83,18 +83,17 @@ impl TempVarData {
|
||||
type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableFixtures<'a>{
|
||||
pub struct VariableFixtures<'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> {
|
||||
pub fn new() -> Self {
|
||||
VariableFixtures {
|
||||
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>) {
|
||||
@@ -262,34 +261,32 @@ impl UnsafeVarMarker {
|
||||
pub fn new() -> Self {
|
||||
UnsafeVarMarker {
|
||||
unsafe_vars: IndexMap::new(),
|
||||
safe_vars: IndexSet::new()
|
||||
safe_vars: IndexSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_safe_vars(safe_vars: IndexSet<RegType>) -> Self {
|
||||
UnsafeVarMarker {
|
||||
unsafe_vars: IndexMap::new(),
|
||||
safe_vars
|
||||
safe_vars,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) -> bool {
|
||||
match query_instr {
|
||||
&QueryInstruction::PutVariable(r @ RegType::Temp(_), _)
|
||||
| &QueryInstruction::SetVariable(r) => {
|
||||
| &QueryInstruction::SetVariable(r) => {
|
||||
self.safe_vars.insert(r);
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mark_phase(&mut self, query_instr: &QueryInstruction, phase: usize) {
|
||||
match query_instr {
|
||||
&QueryInstruction::PutValue(r @ RegType::Perm(_), _)
|
||||
| &QueryInstruction::SetValue(r) => {
|
||||
| &QueryInstruction::SetValue(r) => {
|
||||
let p = self.unsafe_vars.entry(r).or_insert(0);
|
||||
*p = phase;
|
||||
}
|
||||
|
||||
170
src/forms.rs
170
src/forms.rs
@@ -1,13 +1,14 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::parser::OpDesc;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::parser::OpDesc;
|
||||
use prolog_parser::{clause_name, is_infix, is_postfix};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::rug::{Integer, Rational};
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use slice_deque::*;
|
||||
|
||||
@@ -36,7 +37,7 @@ pub enum TopLevel {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum AppendOrPrepend {
|
||||
Append,
|
||||
Prepend
|
||||
Prepend,
|
||||
}
|
||||
|
||||
impl AppendOrPrepend {
|
||||
@@ -115,12 +116,8 @@ impl ListingSource {
|
||||
pub trait ClauseInfo {
|
||||
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
|
||||
match clauses.first() {
|
||||
Some(cl) => {
|
||||
self.name() == cl.name() && self.arity() == cl.arity()
|
||||
}
|
||||
None => {
|
||||
true
|
||||
}
|
||||
Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,38 +137,25 @@ impl ClauseInfo for Term {
|
||||
_ => Some(clause_name!(":-")),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Some(name.clone())
|
||||
}
|
||||
_ => Some(name.clone()),
|
||||
}
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
||||
Some(name.clone())
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Some(name.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
match self {
|
||||
Term::Clause(_, ref name, ref terms, _) =>
|
||||
match name.as_str() {
|
||||
":-" => {
|
||||
match terms.len() {
|
||||
1 => 0,
|
||||
2 => terms[0].arity(),
|
||||
_ => terms.len(),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
terms.len()
|
||||
}
|
||||
Term::Clause(_, ref name, ref terms, _) => match name.as_str() {
|
||||
":-" => match terms.len() {
|
||||
1 => 0,
|
||||
2 => terms[0].arity(),
|
||||
_ => terms.len(),
|
||||
},
|
||||
_ => {
|
||||
0
|
||||
}
|
||||
_ => terms.len(),
|
||||
},
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,23 +173,15 @@ impl ClauseInfo for Rule {
|
||||
impl ClauseInfo for PredicateClause {
|
||||
fn name(&self) -> Option<ClauseName> {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term, ..) => {
|
||||
term.name()
|
||||
}
|
||||
&PredicateClause::Rule(ref rule, ..) => {
|
||||
rule.name()
|
||||
}
|
||||
&PredicateClause::Fact(ref term, ..) => term.name(),
|
||||
&PredicateClause::Rule(ref rule, ..) => rule.name(),
|
||||
}
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term, ..) => {
|
||||
term.arity()
|
||||
}
|
||||
&PredicateClause::Rule(ref rule, ..) => {
|
||||
rule.arity()
|
||||
}
|
||||
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||
&PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,11 +198,9 @@ impl PredicateClause {
|
||||
// TODO: add this to `Term` in `prolog_parser` like `first_arg`.
|
||||
pub fn args(&self) -> Option<&[Box<Term>]> {
|
||||
match *self {
|
||||
PredicateClause::Fact(ref term, ..) => {
|
||||
match term {
|
||||
Term::Clause(_, _, args, _) => Some(&args),
|
||||
_ => None,
|
||||
}
|
||||
PredicateClause::Fact(ref term, ..) => match term {
|
||||
Term::Clause(_, _, args, _) => Some(&args),
|
||||
_ => None,
|
||||
},
|
||||
PredicateClause::Rule(ref rule, ..) => {
|
||||
if rule.head.1.is_empty() {
|
||||
@@ -240,14 +214,11 @@ impl PredicateClause {
|
||||
|
||||
pub fn arity(&self) -> usize {
|
||||
match self {
|
||||
&PredicateClause::Fact(ref term, ..) => {
|
||||
term.arity()
|
||||
}
|
||||
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||
&PredicateClause::Rule(ref rule, ..) => {
|
||||
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
|
||||
match (rule.head.1)[0].as_ref() {
|
||||
&Term::Constant(_, Constant::Atom(..)) => {
|
||||
}
|
||||
&Term::Constant(_, Constant::Atom(..)) => {}
|
||||
_ => {
|
||||
return 2;
|
||||
}
|
||||
@@ -321,7 +292,7 @@ pub enum Declaration {
|
||||
pub struct OpDecl {
|
||||
pub prec: usize,
|
||||
pub spec: Specifier,
|
||||
pub name: ClauseName
|
||||
pub name: ClauseName,
|
||||
}
|
||||
|
||||
impl OpDecl {
|
||||
@@ -345,7 +316,7 @@ impl OpDecl {
|
||||
XFY | XFX | YFX => Fixity::In,
|
||||
XF | YF => Fixity::Post,
|
||||
FX | FY => Fixity::Pre,
|
||||
_ => unreachable!()
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,12 +327,12 @@ impl OpDecl {
|
||||
Some(cell) => {
|
||||
return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
|
||||
}
|
||||
None => {
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
op_dir.insert(key, OpDirValue::new(self.spec, self.prec))
|
||||
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
||||
op_dir
|
||||
.insert(key, OpDirValue::new(self.spec, self.prec))
|
||||
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
||||
}
|
||||
|
||||
pub fn submit(
|
||||
@@ -419,11 +390,7 @@ pub fn fetch_op_spec_from_existing(
|
||||
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
||||
}
|
||||
|
||||
pub fn fetch_op_spec(
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
op_dir: &OpDir,
|
||||
) -> Option<SharedOpDesc> {
|
||||
pub fn fetch_op_spec(name: ClauseName, arity: usize, op_dir: &OpDir) -> Option<SharedOpDesc> {
|
||||
match arity {
|
||||
2 => op_dir
|
||||
.get(&(name, Fixity::In))
|
||||
@@ -451,9 +418,7 @@ pub fn fetch_op_spec(
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,7 +464,6 @@ impl Module {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Number {
|
||||
Float(OrderedFloat<f64>),
|
||||
@@ -559,7 +523,6 @@ impl Into<HeapCellValue> for Number {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Number {
|
||||
#[inline]
|
||||
pub fn is_positive(&self) -> bool {
|
||||
@@ -594,12 +557,13 @@ impl Number {
|
||||
#[inline]
|
||||
pub fn abs(self) -> Self {
|
||||
match self {
|
||||
Number::Fixnum(n) =>
|
||||
Number::Fixnum(n) => {
|
||||
if let Some(n) = n.checked_abs() {
|
||||
Number::from(n)
|
||||
} else {
|
||||
Number::from(Integer::from(n).abs())
|
||||
}
|
||||
}
|
||||
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
|
||||
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
|
||||
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
|
||||
@@ -624,15 +588,13 @@ impl OptArgIndexKey {
|
||||
#[inline]
|
||||
pub fn arg_num(&self) -> usize {
|
||||
match &self {
|
||||
OptArgIndexKey::Constant(arg_num, ..) |
|
||||
OptArgIndexKey::Structure(arg_num, ..) |
|
||||
OptArgIndexKey::List(arg_num, _) => {
|
||||
OptArgIndexKey::Constant(arg_num, ..)
|
||||
| OptArgIndexKey::Structure(arg_num, ..)
|
||||
| OptArgIndexKey::List(arg_num, _) => {
|
||||
// these are always at least 1.
|
||||
*arg_num
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
0
|
||||
}
|
||||
OptArgIndexKey::None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,27 +606,22 @@ impl OptArgIndexKey {
|
||||
#[inline]
|
||||
pub fn switch_on_term_loc(&self) -> Option<usize> {
|
||||
match &self {
|
||||
OptArgIndexKey::Constant(_, loc, ..) |
|
||||
OptArgIndexKey::Structure(_, loc, ..) |
|
||||
OptArgIndexKey::List(_, loc) => {
|
||||
Some(*loc)
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
None
|
||||
}
|
||||
OptArgIndexKey::Constant(_, loc, ..)
|
||||
| OptArgIndexKey::Structure(_, loc, ..)
|
||||
| OptArgIndexKey::List(_, loc) => Some(*loc),
|
||||
OptArgIndexKey::None => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_switch_on_term_loc(&mut self, value: usize) {
|
||||
match self {
|
||||
OptArgIndexKey::Constant(_, ref mut loc, ..) |
|
||||
OptArgIndexKey::Structure(_, ref mut loc, ..) |
|
||||
OptArgIndexKey::List(_, ref mut loc) => {
|
||||
OptArgIndexKey::Constant(_, ref mut loc, ..)
|
||||
| OptArgIndexKey::Structure(_, ref mut loc, ..)
|
||||
| OptArgIndexKey::List(_, ref mut loc) => {
|
||||
*loc = value;
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
}
|
||||
OptArgIndexKey::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -673,13 +630,12 @@ impl AddAssign<usize> for OptArgIndexKey {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, n: usize) {
|
||||
match self {
|
||||
OptArgIndexKey::Constant(_, ref mut o, ..) |
|
||||
OptArgIndexKey::List(_, ref mut o) |
|
||||
OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
||||
OptArgIndexKey::Constant(_, ref mut o, ..)
|
||||
| OptArgIndexKey::List(_, ref mut o)
|
||||
| OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
||||
*o += n;
|
||||
}
|
||||
OptArgIndexKey::None => {
|
||||
}
|
||||
OptArgIndexKey::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -755,5 +711,21 @@ impl PredicateSkeleton {
|
||||
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
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
|
||||
use crate::indexmap::IndexSet;
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::Deref;
|
||||
@@ -29,31 +29,21 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
fn follow_heap(&mut self, h: usize) -> Addr {
|
||||
match &self.machine_st.heap[h] {
|
||||
&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));
|
||||
}
|
||||
|
||||
Addr::Str(h)
|
||||
}
|
||||
&HeapCellValue::Addr(a) => {
|
||||
self.follow(a)
|
||||
}
|
||||
HeapCellValue::PartialString(..) => {
|
||||
self.follow(Addr::PStrLocation(h, 0))
|
||||
}
|
||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(_)
|
||||
| HeapCellValue::Integer(_) | HeapCellValue::Rational(_) => {
|
||||
Addr::Con(h)
|
||||
}
|
||||
HeapCellValue::LoadStatePayload(_) => {
|
||||
Addr::LoadStatePayload(h)
|
||||
}
|
||||
HeapCellValue::Stream(_) => {
|
||||
Addr::Stream(h)
|
||||
}
|
||||
HeapCellValue::TcpListener(_) => {
|
||||
Addr::TcpListener(h)
|
||||
}
|
||||
&HeapCellValue::Addr(a) => self.follow(a),
|
||||
HeapCellValue::PartialString(..) => self.follow(Addr::PStrLocation(h, 0)),
|
||||
HeapCellValue::Atom(..)
|
||||
| HeapCellValue::DBRef(_)
|
||||
| HeapCellValue::Integer(_)
|
||||
| HeapCellValue::Rational(_) => Addr::Con(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
|
||||
}
|
||||
Addr::PStrLocation(h, n) => {
|
||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
||||
if let Some(c) = pstr.range_from(n ..).next() {
|
||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h]
|
||||
{
|
||||
if let Some(c) = pstr.range_from(n..).next() {
|
||||
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 {
|
||||
self.state_stack.push(Addr::HeapCell(h + 1));
|
||||
} else {
|
||||
@@ -95,8 +87,9 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
self.follow_heap(s) // record terms of structure.
|
||||
}
|
||||
Addr::Con(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 &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h]
|
||||
{
|
||||
if let Some(c) = pstr.range_from(0..).next() {
|
||||
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
|
||||
self.state_stack.push(Addr::Char(c));
|
||||
|
||||
@@ -110,9 +103,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
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;
|
||||
|
||||
@@ -178,7 +171,8 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
|
||||
}
|
||||
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
||||
match &self.machine_st.heap[h] {
|
||||
&HeapCellValue::PartialString(..) => {// ref pstr, _) => {
|
||||
&HeapCellValue::PartialString(..) => {
|
||||
// ref pstr, _) => {
|
||||
/*
|
||||
let c = pstr.range_from(n ..).next().unwrap();
|
||||
let next_n = n + c.len_utf8();
|
||||
@@ -215,7 +209,7 @@ impl MachineState {
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
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);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
@@ -341,9 +333,7 @@ impl<'a> Iterator for HCZippedAcyclicIterator<'a>
|
||||
self.first_to_expire = Ordering::Less;
|
||||
None
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::forms::*;
|
||||
@@ -7,14 +13,14 @@ use crate::machine::heap::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::streams::*;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::rug::{Integer, Rational};
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use crate::indexmap::{IndexMap, IndexSet};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::convert::TryFrom;
|
||||
use std::iter::{FromIterator, once};
|
||||
use std::iter::{once, FromIterator};
|
||||
use std::net::{IpAddr, TcpListener};
|
||||
use std::ops::{Range, RangeFrom};
|
||||
use std::rc::Rc;
|
||||
@@ -99,10 +105,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let mut parent_spec = DirectedOp::Left(
|
||||
clause_name!("-"),
|
||||
SharedOpDesc::new(200, FY),
|
||||
);
|
||||
let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
|
||||
|
||||
loop {
|
||||
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
|
||||
'"' if is_quoted => "\\\"".to_string(),
|
||||
'\\' if is_quoted => "\\\\".to_string(),
|
||||
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' =>
|
||||
c.to_string(),
|
||||
'\u{a0}' ..= '\u{d6}' => c.to_string(),
|
||||
'\u{d8}' ..= '\u{f6}' => c.to_string(),
|
||||
'\u{f8}' ..= '\u{74f}' => c.to_string(),
|
||||
'\x20' ..= '\x7e' => c.to_string(),
|
||||
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
|
||||
c.to_string()
|
||||
}
|
||||
'\u{a0}'..='\u{d6}' => c.to_string(),
|
||||
'\u{d8}'..='\u{f6}' => c.to_string(),
|
||||
'\u{f8}'..='\u{74f}' => c.to_string(),
|
||||
'\x20'..='\x7e' => c.to_string(),
|
||||
_ => format!("\\x{:x}\\", c as u32),
|
||||
}
|
||||
}
|
||||
@@ -271,25 +275,13 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
|
||||
#[inline]
|
||||
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
||||
if let Some(ref op) = op {
|
||||
op.is_negative_sign() &&
|
||||
iter.leftmost_leaf_has_property(|addr, heap| {
|
||||
match Number::try_from((addr, heap)) {
|
||||
Ok(Number::Fixnum(n)) => {
|
||||
n > 0
|
||||
}
|
||||
Ok(Number::Float(f)) => {
|
||||
f > OrderedFloat(0f64)
|
||||
}
|
||||
Ok(Number::Integer(n)) => {
|
||||
&*n > &0
|
||||
}
|
||||
Ok(Number::Rational(n)) => {
|
||||
&*n > &0
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
}
|
||||
op.is_negative_sign()
|
||||
&& iter.leftmost_leaf_has_property(|addr, heap| match Number::try_from((addr, heap)) {
|
||||
Ok(Number::Fixnum(n)) => n > 0,
|
||||
Ok(Number::Float(f)) => f > OrderedFloat(0f64),
|
||||
Ok(Number::Integer(n)) => &*n > &0,
|
||||
Ok(Number::Rational(n)) => &*n > &0,
|
||||
_ => false,
|
||||
})
|
||||
} else {
|
||||
false
|
||||
@@ -298,8 +290,8 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
|
||||
|
||||
fn numbervar(n: Integer) -> Var {
|
||||
static CHAR_CODES: [char; 26] = [
|
||||
'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',
|
||||
'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',
|
||||
];
|
||||
|
||||
let i = n.mod_u(26) as usize;
|
||||
@@ -332,9 +324,7 @@ impl MachineState {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,8 +436,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||
pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||
if let Some(c) = iter.next() {
|
||||
if small_letter_char!(c) {
|
||||
iter.all(|c| alpha_numeric_char!(c))
|
||||
@@ -505,37 +494,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
max_depth: 0,
|
||||
}
|
||||
}
|
||||
/*
|
||||
pub fn from_heap_locs(
|
||||
machine_st: &'a MachineState,
|
||||
op_dir: &'a OpDir,
|
||||
output: Outputter,
|
||||
) -> Self {
|
||||
let mut printer = Self::new(machine_st, op_dir, output);
|
||||
/*
|
||||
pub fn from_heap_locs(
|
||||
machine_st: &'a MachineState,
|
||||
op_dir: &'a OpDir,
|
||||
output: Outputter,
|
||||
) -> Self {
|
||||
let mut printer = Self::new(machine_st, op_dir, output);
|
||||
|
||||
printer.toplevel_spec = Some(DirectedOp::Right(
|
||||
clause_name!("="),
|
||||
SharedOpDesc::new(700, XFX),
|
||||
));
|
||||
printer.toplevel_spec = Some(DirectedOp::Right(
|
||||
clause_name!("="),
|
||||
SharedOpDesc::new(700, XFX),
|
||||
));
|
||||
|
||||
printer.heap_locs = reverse_heap_locs(machine_st);
|
||||
printer.heap_locs = reverse_heap_locs(machine_st);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[inline]
|
||||
fn ambiguity_check(&self, atom: &str) -> bool {
|
||||
@@ -555,7 +544,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
iter.stack().pop();
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -579,7 +569,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
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));
|
||||
|
||||
return;
|
||||
@@ -587,7 +578,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
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));
|
||||
} else {
|
||||
match ct.name().as_str() {
|
||||
@@ -602,9 +596,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
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::Atom(clause_name!("...")));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -612,11 +608,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||
let right_directed_op = DirectedOp::Right(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::CompositeRedirect(max_depth, right_directed_op));
|
||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||
max_depth,
|
||||
right_directed_op,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,15 +626,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
mut max_depth: usize,
|
||||
arity: usize,
|
||||
name: ClauseName,
|
||||
) -> bool
|
||||
{
|
||||
) -> bool {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
for _ in 0 .. arity {
|
||||
for _ in 0..arity {
|
||||
iter.stack().pop();
|
||||
}
|
||||
|
||||
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::Atom(name));
|
||||
@@ -644,8 +644,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
|
||||
for _ in 0 .. arity {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
for _ in 0..arity {
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.state_stack.push(TokenOrRedirect::Comma);
|
||||
}
|
||||
|
||||
@@ -662,12 +663,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
iter: &mut HCPreOrderIterator,
|
||||
mut max_depth: usize,
|
||||
name: ClauseName,
|
||||
spec: SharedOpDesc)
|
||||
{
|
||||
spec: SharedOpDesc,
|
||||
) {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
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::Atom(name));
|
||||
|
||||
@@ -676,7 +678,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
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::Atom(name));
|
||||
}
|
||||
@@ -687,14 +690,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
mut max_depth: usize,
|
||||
name: ClauseName,
|
||||
spec: SharedOpDesc,
|
||||
)
|
||||
{
|
||||
) {
|
||||
if self.check_max_depth(&mut max_depth) {
|
||||
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::Atom(clause_name!("...")));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -702,25 +706,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
let left_directed_op = DirectedOp::Left(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::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) {
|
||||
iter.stack().pop();
|
||||
|
||||
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);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
true
|
||||
@@ -795,18 +806,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
|
||||
match addr {
|
||||
Addr::Lis(h) | Addr::Str(h) => {
|
||||
Some(format!("{}", h))
|
||||
}
|
||||
Addr::Lis(h) | Addr::Str(h) => Some(format!("{}", h)),
|
||||
_ => {
|
||||
if let Some(r) = addr.as_var() {
|
||||
match r {
|
||||
Ref::StackCell(fr, sc) => {
|
||||
Some(format!("_s_{}_{}", fr, sc))
|
||||
}
|
||||
Ref::HeapCell(h) | Ref::AttrVar(h) => {
|
||||
Some(format!("_{}", h))
|
||||
}
|
||||
Ref::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
|
||||
Ref::HeapCell(h) | Ref::AttrVar(h) => Some(format!("_{}", h)),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
@@ -818,8 +823,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
|
||||
match addr {
|
||||
&Addr::Lis(l) => {
|
||||
let c1 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l)));
|
||||
let c2 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
|
||||
let c1 = self
|
||||
.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) {
|
||||
self.non_cyclic_terms.insert(c);
|
||||
@@ -830,18 +839,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
&Addr::Str(s) => {
|
||||
let arity =
|
||||
match &self.machine_st.heap[s] {
|
||||
HeapCellValue::NamedStr(arity, ..) => {
|
||||
arity
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
let arity = match &self.machine_st.heap[s] {
|
||||
HeapCellValue::NamedStr(arity, ..) => arity,
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
for i in 1 .. arity + 1 {
|
||||
let c = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
||||
for i in 1..arity + 1 {
|
||||
let c = self
|
||||
.machine_st
|
||||
.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
||||
|
||||
if let Some(c) = functor_location(&c) {
|
||||
self.non_cyclic_terms.insert(c);
|
||||
@@ -856,15 +864,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
self.non_cyclic_terms.insert(c);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_seen(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
) -> Option<Addr> {
|
||||
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<Addr> {
|
||||
iter.stack().last().cloned().and_then(|addr| {
|
||||
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
||||
|
||||
@@ -889,9 +893,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
None => {
|
||||
let offset = match functor_location(&addr) {
|
||||
Some(offset) => {
|
||||
offset
|
||||
}
|
||||
Some(offset) => offset,
|
||||
None => {
|
||||
return iter.next();
|
||||
}
|
||||
@@ -1036,19 +1038,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let rdiv_ct = clause_name!("rdiv");
|
||||
|
||||
let left_directed_op =
|
||||
if spec.prec() > 0 {
|
||||
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let left_directed_op = if spec.prec() > 0 {
|
||||
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let right_directed_op =
|
||||
if spec.prec() > 0 {
|
||||
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let right_directed_op = if spec.prec() > 0 {
|
||||
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if spec.prec() > 0 {
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
@@ -1056,10 +1056,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
left_directed_op,
|
||||
));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Op(
|
||||
rdiv_ct,
|
||||
spec.clone(),
|
||||
));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Op(rdiv_ct, spec.clone()));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
Number::from(r.numer()),
|
||||
@@ -1068,17 +1066,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
} else {
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
Number::from(r.denom()),
|
||||
None,
|
||||
));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Number(Number::from(r.denom()), None));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Comma);
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Number(
|
||||
Number::from(r.numer()),
|
||||
None,
|
||||
));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Number(Number::from(r.numer()), None));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::Open);
|
||||
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)) {
|
||||
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) {
|
||||
self.push_char('"');
|
||||
|
||||
let buf =
|
||||
if max_depth == 0 {
|
||||
String::from_iter(buf.chars().map(|c| {
|
||||
char_to_string(self.quoted, c)
|
||||
}))
|
||||
} else {
|
||||
let mut char_count = 0;
|
||||
let mut buf =
|
||||
String::from_iter(buf.chars().take(max_depth).map(|c| {
|
||||
char_count += 1;
|
||||
char_to_string(self.quoted, c)
|
||||
}));
|
||||
let buf = if max_depth == 0 {
|
||||
String::from_iter(buf.chars().map(|c| char_to_string(self.quoted, c)))
|
||||
} else {
|
||||
let mut char_count = 0;
|
||||
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 {
|
||||
buf += " ...";
|
||||
}
|
||||
if char_count == max_depth {
|
||||
buf += " ...";
|
||||
}
|
||||
|
||||
buf
|
||||
};
|
||||
buf
|
||||
};
|
||||
|
||||
self.append_str(&buf);
|
||||
self.push_char('"');
|
||||
}
|
||||
|
||||
fn print_list_like(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
addr: Addr,
|
||||
mut max_depth: usize,
|
||||
) {
|
||||
fn print_list_like(&mut self, iter: &mut HCPreOrderIterator, addr: Addr, mut max_depth: usize) {
|
||||
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!("...")));
|
||||
return;
|
||||
}
|
||||
|
||||
let mut heap_pstr_iter =
|
||||
self.machine_st.heap_pstr_iter(addr);
|
||||
let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(addr);
|
||||
|
||||
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_iter: Box<dyn Iterator<Item=char>> =
|
||||
if self.max_depth == 0 {
|
||||
Box::new(buf.chars())
|
||||
} else {
|
||||
Box::new(buf.chars().take(max_depth))
|
||||
};
|
||||
let buf_iter: Box<dyn Iterator<Item = char>> = if self.max_depth == 0 {
|
||||
Box::new(buf.chars())
|
||||
} else {
|
||||
Box::new(buf.chars().take(max_depth))
|
||||
};
|
||||
|
||||
let mut byte_len = 0;
|
||||
|
||||
@@ -1207,14 +1190,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
byte_len += c.len_utf8();
|
||||
}
|
||||
|
||||
for _ in 0 .. char_count {
|
||||
for _ in 0..char_count {
|
||||
self.state_stack.push(TokenOrRedirect::Close);
|
||||
}
|
||||
|
||||
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 {
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
iter.stack().push(end_addr);
|
||||
}
|
||||
} else {
|
||||
@@ -1232,15 +1217,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
byte_len += c.len_utf8();
|
||||
}
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new(
|
||||
Cell::new((switch, 0))
|
||||
)));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CloseList(Rc::new(Cell::new((switch, 0)))));
|
||||
|
||||
if self.max_depth > 0 && buf_len > byte_len {
|
||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
} else {
|
||||
self.outputter.truncate(self.outputter.len() - ','.len_utf8());
|
||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
} else {
|
||||
self.outputter
|
||||
.truncate(self.outputter.len() - ','.len_utf8());
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
|
||||
iter.stack().push(end_addr);
|
||||
}
|
||||
@@ -1268,8 +1255,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
let cell = Rc::new(Cell::new((true, 0)));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||
|
||||
return;
|
||||
@@ -1277,11 +1266,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
|
||||
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::FunctorRedirect(max_depth));
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||
}
|
||||
@@ -1298,23 +1290,24 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
max_depth: usize,
|
||||
) {
|
||||
let add_brackets = if !self.ignore_ops {
|
||||
negated_operand || if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||
match heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||
_ => false
|
||||
}
|
||||
}) && needs_bracketing(&spec, op)
|
||||
negated_operand
|
||||
|| if let Some(ref op) = op {
|
||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||
match heap.index_addr(&addr).as_ref() {
|
||||
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||
_ => false,
|
||||
}
|
||||
}) && needs_bracketing(&spec, op)
|
||||
} else {
|
||||
needs_bracketing(&spec, op)
|
||||
}
|
||||
} else {
|
||||
needs_bracketing(&spec, op)
|
||||
is_functor_redirect && spec.prec() >= 1000
|
||||
}
|
||||
} else {
|
||||
is_functor_redirect && spec.prec() >= 1000
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@@ -1344,15 +1337,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
tcp_listener: &TcpListener,
|
||||
max_depth: usize,
|
||||
) {
|
||||
let (ip, port) =
|
||||
if let Some(addr) = tcp_listener.local_addr().ok() {
|
||||
(addr.ip(), Number::from(addr.port() as isize))
|
||||
} else {
|
||||
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
||||
self.state_stack.push(TokenOrRedirect::Atom(disconnected_atom));
|
||||
let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
|
||||
(addr.ip(), Number::from(addr.port() as isize))
|
||||
} else {
|
||||
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(disconnected_atom));
|
||||
|
||||
return;
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) {
|
||||
let atom = self.state_stack.pop().unwrap();
|
||||
@@ -1369,22 +1362,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_stream(
|
||||
&mut self,
|
||||
iter: &mut HCPreOrderIterator,
|
||||
stream: &Stream,
|
||||
max_depth: usize,
|
||||
) {
|
||||
fn print_stream(&mut self, iter: &mut HCPreOrderIterator, stream: &Stream, max_depth: usize) {
|
||||
if let Some(alias) = &stream.options.alias {
|
||||
self.print_atom(alias);
|
||||
} else {
|
||||
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
|
||||
let atom =
|
||||
if stream.is_stdout() || stream.is_stdin() {
|
||||
TokenOrRedirect::Atom(clause_name!("user"))
|
||||
} else {
|
||||
TokenOrRedirect::RawPtr(stream.as_ptr())
|
||||
};
|
||||
let atom = if stream.is_stdout() || stream.is_stdin() {
|
||||
TokenOrRedirect::Atom(clause_name!("user"))
|
||||
} else {
|
||||
TokenOrRedirect::RawPtr(stream.as_ptr())
|
||||
};
|
||||
|
||||
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() {
|
||||
&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 {
|
||||
self.handle_op_as_struct(
|
||||
|
||||
480
src/indexing.rs
480
src/indexing.rs
@@ -1,11 +1,12 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::clause_name;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
|
||||
use crate::forms::*;
|
||||
use crate::instructions::*;
|
||||
|
||||
use crate::indexmap::IndexMap;
|
||||
use crate::rug::Integer;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use slice_deque::{sdeq, SliceDeque};
|
||||
|
||||
@@ -43,14 +44,10 @@ impl OptArgIndexKey {
|
||||
#[inline]
|
||||
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
|
||||
match (self, key_type) {
|
||||
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant) |
|
||||
(OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure) |
|
||||
(OptArgIndexKey::List(..), OptArgIndexKeyType::List) => {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant)
|
||||
| (OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure)
|
||||
| (OptArgIndexKey::List(..), OptArgIndexKeyType::List) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,16 +90,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
indexing_code: &'a mut Vec<IndexingLine>,
|
||||
append_or_prepend: AppendOrPrepend,
|
||||
) -> 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) {
|
||||
let constant_key =
|
||||
search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Constant,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
|
||||
let constant_key = search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Constant,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
|
||||
let mut constants = IndexMap::new();
|
||||
|
||||
@@ -117,7 +118,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
|
||||
if let IndexingCodePtr::Internal(_) = constant_ptr {
|
||||
self.indexing_code.push(IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
IndexingInstruction::SwitchOnConstant(constants),
|
||||
));
|
||||
|
||||
let last_index = self.indexing_code.len() - 1;
|
||||
@@ -126,34 +127,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
self.offset = self.indexing_code.len();
|
||||
|
||||
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)
|
||||
{
|
||||
let third_level_index =
|
||||
if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
fn add_indexed_choice_for_constant(
|
||||
&mut self,
|
||||
external: usize,
|
||||
constant: Constant,
|
||||
index: usize,
|
||||
) {
|
||||
let third_level_index = if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
|
||||
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] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
||||
) => {
|
||||
constants.insert(constant, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
|
||||
constants.insert(
|
||||
constant,
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -164,10 +170,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
fn extend_indexed_choice(&mut self, index: usize) {
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
|
||||
if self.append_or_prepend.is_append() => {
|
||||
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
||||
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
||||
}
|
||||
if self.append_or_prepend.is_append() =>
|
||||
{
|
||||
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
||||
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
||||
}
|
||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => {
|
||||
uncap_choice_seq_with_try(indexed_choice_instrs);
|
||||
indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index));
|
||||
@@ -188,9 +195,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
match *c {
|
||||
IndexingCodePtr::Fail => {
|
||||
*c = IndexingCodePtr::External(index);
|
||||
@@ -203,7 +208,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
*c = IndexingCodePtr::Internal(indexing_code_len);
|
||||
|
||||
self.indexing_code.push(IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
IndexingInstruction::SwitchOnConstant(constants),
|
||||
));
|
||||
|
||||
self.offset = indexing_code_len;
|
||||
@@ -213,12 +218,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||
match constants.get(&overlapping_constant).cloned() {
|
||||
None | Some(IndexingCodePtr::Fail) => {
|
||||
constants.insert(overlapping_constant, IndexingCodePtr::External(index));
|
||||
constants
|
||||
.insert(overlapping_constant, IndexingCodePtr::External(index));
|
||||
}
|
||||
Some(IndexingCodePtr::External(o)) => {
|
||||
self.add_indexed_choice_for_constant(o, overlapping_constant, index);
|
||||
@@ -232,9 +236,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
break;
|
||||
}
|
||||
IndexingLine::IndexedChoice(_) => {
|
||||
self.internalize_constant(
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
self.internalize_constant(IndexingCodePtr::Internal(
|
||||
indexing_code_len - self.offset,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -248,9 +252,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
match *c {
|
||||
IndexingCodePtr::Fail => {
|
||||
*c = IndexingCodePtr::External(index);
|
||||
@@ -265,9 +267,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||
match constants.get(&constant).cloned() {
|
||||
None | Some(IndexingCodePtr::Fail) => {
|
||||
constants.insert(constant, IndexingCodePtr::External(index));
|
||||
@@ -284,9 +284,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
break;
|
||||
}
|
||||
IndexingLine::IndexedChoice(_) => {
|
||||
self.internalize_constant(
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
self.internalize_constant(IndexingCodePtr::Internal(
|
||||
indexing_code_len - self.offset,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -295,13 +295,12 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
||||
let structure_key =
|
||||
search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Structure,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
||||
let structure_key = search_skeleton_for_first_key_type(
|
||||
self.skeleton,
|
||||
OptArgIndexKeyType::Structure,
|
||||
self.append_or_prepend,
|
||||
);
|
||||
|
||||
let mut structures = IndexMap::new();
|
||||
|
||||
@@ -316,7 +315,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
|
||||
if let IndexingCodePtr::Internal(_) = structure_ptr {
|
||||
self.indexing_code.push(IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(structures)
|
||||
IndexingInstruction::SwitchOnStructure(structures),
|
||||
));
|
||||
|
||||
let last_index = self.indexing_code.len() - 1;
|
||||
@@ -325,34 +324,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
self.offset = self.indexing_code.len();
|
||||
|
||||
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)
|
||||
{
|
||||
let third_level_index =
|
||||
if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
fn add_indexed_choice_for_structure(
|
||||
&mut self,
|
||||
external: usize,
|
||||
key: PredicateKey,
|
||||
index: usize,
|
||||
) {
|
||||
let third_level_index = if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(external),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(external)
|
||||
]
|
||||
};
|
||||
|
||||
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] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
||||
) => {
|
||||
structures.insert(key, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||
structures.insert(
|
||||
key,
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -365,26 +369,26 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
match *s {
|
||||
IndexingCodePtr::Fail => {
|
||||
*s = IndexingCodePtr::External(index);
|
||||
break;
|
||||
}
|
||||
IndexingCodePtr::External(o) => {
|
||||
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||
self.internalize_structure(IndexingCodePtr::External(o));
|
||||
}
|
||||
IndexingCodePtr::Internal(o) => {
|
||||
self.offset += o;
|
||||
}
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut s,
|
||||
)) => match *s {
|
||||
IndexingCodePtr::Fail => {
|
||||
*s = IndexingCodePtr::External(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(structures)
|
||||
) => {
|
||||
IndexingCodePtr::External(o) => {
|
||||
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||
self.internalize_structure(IndexingCodePtr::External(o));
|
||||
}
|
||||
IndexingCodePtr::Internal(o) => {
|
||||
self.offset += o;
|
||||
}
|
||||
},
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(structures)) => {
|
||||
match structures.get(&key).cloned() {
|
||||
None | Some(IndexingCodePtr::Fail) => {
|
||||
structures.insert(key, IndexingCodePtr::External(index));
|
||||
@@ -404,9 +408,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
// replace this value, at self.offset, with
|
||||
// SwitchOnStructures, and swap this IndexedChoice
|
||||
// vector to the end of self.indexing_code.
|
||||
self.internalize_structure(
|
||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||
);
|
||||
self.internalize_structure(IndexingCodePtr::Internal(
|
||||
indexing_code_len - self.offset,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
unreachable!()
|
||||
@@ -419,9 +423,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
let indexing_code_len = self.indexing_code.len();
|
||||
|
||||
match &mut self.indexing_code[self.offset] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||
match *l {
|
||||
IndexingCodePtr::Fail => {
|
||||
*l = IndexingCodePtr::External(index);
|
||||
@@ -429,22 +431,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
IndexingCodePtr::External(o) => {
|
||||
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||
|
||||
let third_level_index =
|
||||
if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(o),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(o)
|
||||
]
|
||||
};
|
||||
let third_level_index = if self.append_or_prepend.is_append() {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(o),
|
||||
IndexedChoiceInstruction::Trust(index)
|
||||
]
|
||||
} else {
|
||||
sdeq![
|
||||
IndexedChoiceInstruction::Try(index),
|
||||
IndexedChoiceInstruction::Trust(o)
|
||||
]
|
||||
};
|
||||
|
||||
self.indexing_code.push(
|
||||
IndexingLine::IndexedChoice(third_level_index),
|
||||
);
|
||||
self.indexing_code
|
||||
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||
}
|
||||
IndexingCodePtr::Internal(o) => {
|
||||
self.offset += o;
|
||||
@@ -462,24 +462,16 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
||||
pub fn merge_clause_index(
|
||||
target_indexing_code: &mut Vec<IndexingLine>,
|
||||
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,
|
||||
) {
|
||||
let opt_arg_index_key =
|
||||
match append_or_prepend {
|
||||
AppendOrPrepend::Append => {
|
||||
skeleton.last_mut().unwrap().opt_arg_index_key.take()
|
||||
}
|
||||
AppendOrPrepend::Prepend => {
|
||||
skeleton.first_mut().unwrap().opt_arg_index_key.take()
|
||||
}
|
||||
};
|
||||
let opt_arg_index_key = match append_or_prepend {
|
||||
AppendOrPrepend::Append => 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(
|
||||
skeleton,
|
||||
target_indexing_code,
|
||||
append_or_prepend,
|
||||
);
|
||||
let mut merging_ptr =
|
||||
IndexingCodeMergingPtr::new(skeleton, target_indexing_code, append_or_prepend);
|
||||
|
||||
match &opt_arg_index_key {
|
||||
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
|
||||
@@ -488,7 +480,9 @@ pub fn merge_clause_index(
|
||||
|
||||
for overlapping_constant in overlapping_constants {
|
||||
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]
|
||||
fn remove_instruction_with_offset(
|
||||
code: &mut SliceDeque<IndexedChoiceInstruction>,
|
||||
offset: usize,
|
||||
) {
|
||||
fn remove_instruction_with_offset(code: &mut SliceDeque<IndexedChoiceInstruction>, offset: usize) {
|
||||
for (index, line) in code.iter().enumerate() {
|
||||
if offset == line.offset() {
|
||||
code.remove(index);
|
||||
@@ -537,9 +528,7 @@ pub fn remove_constant_indices(
|
||||
let iter = once(constant).chain(overlapping_constants.iter());
|
||||
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
match *c {
|
||||
IndexingCodePtr::External(_) => {
|
||||
*c = IndexingCodePtr::Fail;
|
||||
@@ -560,12 +549,13 @@ pub fn remove_constant_indices(
|
||||
|
||||
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 {
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||
ref mut constants,
|
||||
)) => {
|
||||
constants_index = index;
|
||||
|
||||
match constants.get(constant).cloned() {
|
||||
@@ -586,18 +576,21 @@ pub fn remove_constant_indices(
|
||||
|
||||
if indexed_choice_instrs.len() == 1 {
|
||||
let ext = IndexingCodePtr::External(
|
||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
||||
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||
);
|
||||
|
||||
match &mut indexing_code[constants_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
ref mut c,
|
||||
..,
|
||||
)) => {
|
||||
*c = ext;
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||
ref mut constants,
|
||||
)) => {
|
||||
constants.insert(constant.clone(), ext);
|
||||
}
|
||||
_ => {
|
||||
@@ -616,13 +609,11 @@ pub fn remove_constant_indices(
|
||||
}
|
||||
|
||||
match &indexing_code[constants_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnConstant(ref constants)
|
||||
) if constants.is_empty() => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref constants))
|
||||
if constants.is_empty() =>
|
||||
{
|
||||
match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||
*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;
|
||||
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)) => {
|
||||
match *s {
|
||||
IndexingCodePtr::External(_) => {
|
||||
*s = IndexingCodePtr::Fail;
|
||||
@@ -669,9 +657,7 @@ pub fn remove_structure_index(
|
||||
|
||||
loop {
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||
structures_index = index;
|
||||
|
||||
match structures.get(&(name.clone(), arity)).cloned() {
|
||||
@@ -692,18 +678,22 @@ pub fn remove_structure_index(
|
||||
|
||||
if indexed_choice_instrs.len() == 1 {
|
||||
let ext = IndexingCodePtr::External(
|
||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
||||
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||
);
|
||||
|
||||
match &mut indexing_code[structures_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut s,
|
||||
)) => {
|
||||
*s = ext;
|
||||
}
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
||||
ref mut structures,
|
||||
)) => {
|
||||
structures.insert((name.clone(), arity), ext);
|
||||
}
|
||||
_ => {
|
||||
@@ -721,13 +711,17 @@ pub fn remove_structure_index(
|
||||
}
|
||||
|
||||
match &indexing_code[structures_index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnStructure(ref structures)
|
||||
) if structures.is_empty() => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref structures))
|
||||
if structures.is_empty() =>
|
||||
{
|
||||
match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut s,
|
||||
)) => {
|
||||
*s = IndexingCodePtr::Fail;
|
||||
}
|
||||
_ => {
|
||||
@@ -735,21 +729,15 @@ pub fn remove_structure_index(
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_list_index(
|
||||
indexing_code: &mut Vec<IndexingLine>,
|
||||
offset: usize,
|
||||
) {
|
||||
pub fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
|
||||
let mut index = 0;
|
||||
|
||||
match &mut indexing_code[index] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||
match *l {
|
||||
IndexingCodePtr::External(_) => {
|
||||
*l = IndexingCodePtr::Fail;
|
||||
@@ -773,14 +761,17 @@ pub fn remove_list_index(
|
||||
remove_instruction_with_offset(indexed_choice_instrs, offset);
|
||||
|
||||
if indexed_choice_instrs.len() == 1 {
|
||||
let ext = IndexingCodePtr::External(
|
||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
||||
);
|
||||
let ext =
|
||||
IndexingCodePtr::External(indexed_choice_instrs.pop_back().unwrap().offset());
|
||||
|
||||
match &mut indexing_code[0] {
|
||||
IndexingLine::Indexing(
|
||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
||||
) => {
|
||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
ref mut l,
|
||||
_,
|
||||
)) => {
|
||||
*l = ext;
|
||||
}
|
||||
_ => {
|
||||
@@ -836,8 +827,7 @@ pub fn remove_index(
|
||||
fn second_level_index<IndexKey: Eq + Hash>(
|
||||
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
|
||||
prelude: &mut SliceDeque<IndexingLine>,
|
||||
) -> IndexMap<IndexKey, IndexingCodePtr>
|
||||
{
|
||||
) -> IndexMap<IndexKey, IndexingCodePtr> {
|
||||
let mut index_locs = IndexMap::new();
|
||||
|
||||
for (key, mut code) in indices.into_iter() {
|
||||
@@ -868,10 +858,11 @@ fn switch_on<IndexKey: Eq + Hash>(
|
||||
|
||||
IndexingCodePtr::Internal(1)
|
||||
} else {
|
||||
index.into_iter()
|
||||
.next()
|
||||
.map(|(_, v)| v)
|
||||
.unwrap_or(IndexingCodePtr::Fail)
|
||||
index
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|(_, v)| v)
|
||||
.unwrap_or(IndexingCodePtr::Fail)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,9 +875,10 @@ fn switch_on_list(
|
||||
prelude.push_back(IndexingLine::from(lists));
|
||||
IndexingCodePtr::Internal(1)
|
||||
} else {
|
||||
lists.first()
|
||||
.map(|i| IndexingCodePtr::External(i.offset()))
|
||||
.unwrap_or(IndexingCodePtr::Fail)
|
||||
lists
|
||||
.first()
|
||||
.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
|
||||
@@ -1001,7 +992,7 @@ impl CodeOffsets {
|
||||
constants: IndexMap::new(),
|
||||
lists: sdeq![],
|
||||
structures: IndexMap::new(),
|
||||
optimal_index
|
||||
optimal_index,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1011,20 +1002,15 @@ impl CodeOffsets {
|
||||
}
|
||||
|
||||
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
|
||||
let overlapping_constants =
|
||||
constant_key_alternatives(constant, self.atom_tbl.clone());
|
||||
let overlapping_constants = constant_key_alternatives(constant, self.atom_tbl.clone());
|
||||
|
||||
let code = self.constants
|
||||
.entry(constant.clone())
|
||||
.or_insert(sdeq![]);
|
||||
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||
|
||||
let is_initial_index = code.is_empty();
|
||||
code.push_back(compute_index(is_initial_index, index));
|
||||
|
||||
for constant in &overlapping_constants {
|
||||
let code = self.constants
|
||||
.entry(constant.clone())
|
||||
.or_insert(sdeq![]);
|
||||
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||
|
||||
let is_initial_index = code.is_empty();
|
||||
let index = compute_index(is_initial_index, index);
|
||||
@@ -1062,25 +1048,21 @@ impl CodeOffsets {
|
||||
self.index_structure(name, terms.len(), index);
|
||||
}
|
||||
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
||||
clause_index_info.opt_arg_index_key =
|
||||
OptArgIndexKey::List(self.optimal_index, 0);
|
||||
clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0);
|
||||
|
||||
self.index_list(index);
|
||||
}
|
||||
&Term::Constant(_, ref constant) => {
|
||||
let overlapping_constants =
|
||||
self.index_constant(constant, index);
|
||||
let overlapping_constants = self.index_constant(constant, index);
|
||||
|
||||
clause_index_info.opt_arg_index_key =
|
||||
OptArgIndexKey::Constant(
|
||||
self.optimal_index,
|
||||
0,
|
||||
constant.clone(),
|
||||
overlapping_constants,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
clause_index_info.opt_arg_index_key = OptArgIndexKey::Constant(
|
||||
self.optimal_index,
|
||||
0,
|
||||
constant.clone(),
|
||||
overlapping_constants,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1117,8 +1099,7 @@ impl CodeOffsets {
|
||||
IndexingCodePtr::Internal(ref mut i) => {
|
||||
*i += con_loc.is_internal() as usize;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
match &mut lst_loc {
|
||||
@@ -1126,15 +1107,18 @@ impl CodeOffsets {
|
||||
*i += con_loc.is_internal() as usize;
|
||||
*i += str_loc.is_internal() as usize;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let var_offset = 1 + skip_stub_try_me_else as usize;
|
||||
|
||||
prelude.push_front(IndexingLine::from(
|
||||
IndexingInstruction::SwitchOnTerm(self.optimal_index, var_offset, con_loc, lst_loc, str_loc)
|
||||
));
|
||||
prelude.push_front(IndexingLine::from(IndexingInstruction::SwitchOnTerm(
|
||||
self.optimal_index,
|
||||
var_offset,
|
||||
con_loc,
|
||||
lst_loc,
|
||||
str_loc,
|
||||
)));
|
||||
|
||||
prelude.into_iter().collect()
|
||||
}
|
||||
|
||||
@@ -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::forms::*;
|
||||
@@ -8,7 +9,7 @@ use crate::machine::machine_errors::MachineStub;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::rug::Integer;
|
||||
|
||||
use crate::indexmap::IndexMap;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use slice_deque::SliceDeque;
|
||||
|
||||
@@ -34,9 +35,7 @@ impl Level {
|
||||
impl ArithmeticTerm {
|
||||
fn into_functor(&self) -> MachineStub {
|
||||
match self {
|
||||
&ArithmeticTerm::Reg(r) => {
|
||||
reg_type_into_functor(r)
|
||||
}
|
||||
&ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
||||
&ArithmeticTerm::Interm(i) => {
|
||||
functor!("intermediate", [integer(i)])
|
||||
}
|
||||
@@ -185,16 +184,11 @@ impl Line {
|
||||
|
||||
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
|
||||
match self {
|
||||
&Line::Arithmetic(ref arith_instr) =>
|
||||
functors.push(arith_instr.to_functor(h)),
|
||||
&Line::Choice(ref choice_instr) =>
|
||||
functors.push(choice_instr.to_functor()),
|
||||
&Line::Control(ref control_instr) =>
|
||||
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::Arithmetic(ref arith_instr) => functors.push(arith_instr.to_functor(h)),
|
||||
&Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor()),
|
||||
&Line::Control(ref control_instr) => 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) => {
|
||||
for indexing_instr in indexing_instrs {
|
||||
match indexing_instr {
|
||||
@@ -213,10 +207,10 @@ impl Line {
|
||||
}
|
||||
}
|
||||
}
|
||||
&Line::IndexedChoice(ref indexed_choice_instr) =>
|
||||
functors.push(indexed_choice_instr.to_functor()),
|
||||
&Line::Query(ref query_instr) =>
|
||||
functors.push(query_instr.to_functor(h)),
|
||||
&Line::IndexedChoice(ref indexed_choice_instr) => {
|
||||
functors.push(indexed_choice_instr.to_functor())
|
||||
}
|
||||
&Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,24 +218,16 @@ impl Line {
|
||||
#[inline]
|
||||
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
||||
match line {
|
||||
Line::IndexingCode(ref mut indexing_code) => {
|
||||
Some(indexing_code)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
||||
match line {
|
||||
Line::IndexingCode(ref indexing_code) => {
|
||||
Some(indexing_code)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
Line::IndexingCode(ref indexing_code) => Some(indexing_code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,11 +282,7 @@ fn arith_instr_unary_functor(
|
||||
) -> MachineStub {
|
||||
let at_stub = at.into_functor();
|
||||
|
||||
functor!(
|
||||
name,
|
||||
[aux(h, 0), integer(t)],
|
||||
[at_stub]
|
||||
)
|
||||
functor!(name, [aux(h, 0), integer(t)], [at_stub])
|
||||
}
|
||||
|
||||
fn arith_instr_bin_functor(
|
||||
@@ -383,39 +365,17 @@ impl ArithmeticInstruction {
|
||||
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
||||
arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
|
||||
}
|
||||
&ArithmeticInstruction::Sign(ref 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::Tan(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "tan", 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::Sign(ref 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::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", 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) => {
|
||||
arith_instr_unary_functor(h, "float", at, t)
|
||||
}
|
||||
@@ -431,12 +391,8 @@ impl ArithmeticInstruction {
|
||||
&ArithmeticInstruction::Floor(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "floor", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Neg(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "-", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Plus(ref at, t) => {
|
||||
arith_instr_unary_functor(h, "+", at, t)
|
||||
}
|
||||
&ArithmeticInstruction::Neg(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) => {
|
||||
arith_instr_unary_functor(h, "\\", at, t)
|
||||
}
|
||||
@@ -451,21 +407,18 @@ pub enum ControlInstruction {
|
||||
CallClause(ClauseType, usize, usize, bool, bool),
|
||||
Deallocate,
|
||||
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
||||
RevJmpBy(usize), // notice the lack of context change as in
|
||||
// JmpBy. RevJmpBy is used only to patch extensible
|
||||
// predicates together.
|
||||
RevJmpBy(usize), // notice the lack of context change as in
|
||||
// JmpBy. RevJmpBy is used only to patch extensible
|
||||
// predicates together.
|
||||
Proceed,
|
||||
}
|
||||
|
||||
impl ControlInstruction {
|
||||
pub fn perm_vars(&self) -> Option<usize> {
|
||||
match self {
|
||||
ControlInstruction::CallClause(_, _, num_cells, ..) =>
|
||||
Some(*num_cells),
|
||||
ControlInstruction::JmpBy(_, _, num_cells, ..) =>
|
||||
Some(*num_cells),
|
||||
_ =>
|
||||
None
|
||||
ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
|
||||
ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,7 +453,13 @@ impl ControlInstruction {
|
||||
#[derive(Debug)]
|
||||
pub enum IndexingInstruction {
|
||||
// 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>),
|
||||
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
|
||||
}
|
||||
@@ -511,11 +470,13 @@ impl IndexingInstruction {
|
||||
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
||||
functor!(
|
||||
"switch_on_term",
|
||||
[integer(arg),
|
||||
integer(vars),
|
||||
indexing_code_ptr(h, constants),
|
||||
indexing_code_ptr(h, lists),
|
||||
indexing_code_ptr(h, structures)]
|
||||
[
|
||||
integer(arg),
|
||||
integer(vars),
|
||||
indexing_code_ptr(h, constants),
|
||||
indexing_code_ptr(h, lists),
|
||||
indexing_code_ptr(h, structures)
|
||||
]
|
||||
)
|
||||
}
|
||||
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
||||
@@ -528,15 +489,14 @@ impl IndexingInstruction {
|
||||
let key_value_pair = functor!(
|
||||
":",
|
||||
SharedOpDesc::new(600, XFY),
|
||||
[constant(c),
|
||||
indexing_code_ptr(h + 3, *ptr)]
|
||||
[constant(c), 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::Str(h + 3)));
|
||||
key_value_list_stub.push(HeapCellValue::Addr(
|
||||
Addr::HeapCell(h + 3 + key_value_pair.len())
|
||||
));
|
||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||
h + 3 + key_value_pair.len(),
|
||||
)));
|
||||
|
||||
h += key_value_pair.len() + 3;
|
||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||
@@ -560,23 +520,21 @@ impl IndexingInstruction {
|
||||
let predicate_indicator_stub = functor!(
|
||||
"/",
|
||||
SharedOpDesc::new(400, YFX),
|
||||
[clause_name(name.clone()),
|
||||
integer(*arity)]
|
||||
[clause_name(name.clone()), integer(*arity)]
|
||||
);
|
||||
|
||||
let key_value_pair = functor!(
|
||||
":",
|
||||
SharedOpDesc::new(600, XFY),
|
||||
[aux(h + 3, 0),
|
||||
indexing_code_ptr(h + 3, *ptr)],
|
||||
[aux(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
|
||||
[predicate_indicator_stub]
|
||||
);
|
||||
|
||||
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::HeapCell(h + 3 + key_value_pair.len())
|
||||
));
|
||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||
h + 3 + key_value_pair.len(),
|
||||
)));
|
||||
|
||||
h += key_value_pair.len() + 3;
|
||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||
@@ -614,7 +572,7 @@ impl FactInstruction {
|
||||
match self {
|
||||
&FactInstruction::GetConstant(lvl, ref c, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_constant",
|
||||
@@ -624,17 +582,13 @@ impl FactInstruction {
|
||||
}
|
||||
&FactInstruction::GetList(lvl, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_list",
|
||||
[aux(h, 0), aux(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
functor!("get_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||
}
|
||||
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_partial_string",
|
||||
@@ -654,20 +608,12 @@ impl FactInstruction {
|
||||
&FactInstruction::GetValue(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_value",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("get_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::GetVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_variable",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyConstant(ref c) => {
|
||||
functor!("unify_constant", [constant(h, c)], [])
|
||||
@@ -675,29 +621,17 @@ impl FactInstruction {
|
||||
&FactInstruction::UnifyLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"unify_local_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("unify_local_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyVariable(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"unify_variable",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("unify_variable", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"unify_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("unify_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&FactInstruction::UnifyVoid(vars) => {
|
||||
functor!("unify_void", [integer(vars)])
|
||||
@@ -726,13 +660,12 @@ pub enum QueryInstruction {
|
||||
impl QueryInstruction {
|
||||
pub fn to_functor(&self, h: usize) -> MachineStub {
|
||||
match self {
|
||||
&QueryInstruction::PutUnsafeValue(norm, arg) => functor!(
|
||||
"put_unsafe_value",
|
||||
[integer(norm), integer(arg)]
|
||||
),
|
||||
&QueryInstruction::PutUnsafeValue(norm, arg) => {
|
||||
functor!("put_unsafe_value", [integer(norm), integer(arg)])
|
||||
}
|
||||
&QueryInstruction::PutConstant(lvl, ref c, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_constant",
|
||||
@@ -742,17 +675,13 @@ impl QueryInstruction {
|
||||
}
|
||||
&QueryInstruction::PutList(lvl, r) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_list",
|
||||
[aux(h, 0), aux(h, 1)],
|
||||
[lvl_stub, rt_stub]
|
||||
)
|
||||
functor!("put_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||
}
|
||||
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
|
||||
let lvl_stub = lvl.into_functor();
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_partial_string",
|
||||
@@ -772,29 +701,17 @@ impl QueryInstruction {
|
||||
&QueryInstruction::PutValue(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_value",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("put_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::GetVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"get_variable",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::PutVariable(r, arg) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"put_variable",
|
||||
[aux(h, 0), integer(arg)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("put_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetConstant(ref c) => {
|
||||
functor!("set_constant", [constant(h, c)], [])
|
||||
@@ -802,29 +719,17 @@ impl QueryInstruction {
|
||||
&QueryInstruction::SetLocalValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"set_local_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("set_local_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetVariable(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"set_variable",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("set_variable", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetValue(r) => {
|
||||
let rt_stub = reg_type_into_functor(r);
|
||||
|
||||
functor!(
|
||||
"set_value",
|
||||
[aux(h, 0)],
|
||||
[rt_stub]
|
||||
)
|
||||
functor!("set_value", [aux(h, 0)], [rt_stub])
|
||||
}
|
||||
&QueryInstruction::SetVoid(vars) => {
|
||||
functor!("set_void", [integer(vars)])
|
||||
|
||||
@@ -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::forms::*;
|
||||
@@ -25,11 +26,11 @@ impl<'a> TermRef<'a> {
|
||||
pub fn level(self) -> Level {
|
||||
match self {
|
||||
TermRef::AnonVar(lvl)
|
||||
| TermRef::Cons(lvl, ..)
|
||||
| TermRef::Constant(lvl, ..)
|
||||
| TermRef::Var(lvl, ..)
|
||||
| TermRef::Clause(lvl, ..) => lvl,
|
||||
| TermRef::PartialString(lvl, ..) => lvl,
|
||||
| TermRef::Cons(lvl, ..)
|
||||
| TermRef::Constant(lvl, ..)
|
||||
| TermRef::Var(lvl, ..)
|
||||
| TermRef::Clause(lvl, ..) => lvl,
|
||||
TermRef::PartialString(lvl, ..) => lvl,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,23 +52,16 @@ pub enum TermIterState<'a> {
|
||||
Var(Level, &'a Cell<VarReg>, Rc<Var>),
|
||||
}
|
||||
|
||||
fn is_partial_string<'a>(
|
||||
head: &'a Term,
|
||||
mut tail: &'a Term,
|
||||
) -> Option<(String, Option<&'a Term>)>
|
||||
{
|
||||
let mut string =
|
||||
match head {
|
||||
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
||||
atom.as_str().chars().next().unwrap().to_string()
|
||||
}
|
||||
&Term::Constant(_, Constant::Char(c)) => {
|
||||
c.to_string()
|
||||
}
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
fn is_partial_string<'a>(head: &'a Term, mut tail: &'a Term) -> Option<(String, Option<&'a Term>)> {
|
||||
let mut string = match head {
|
||||
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
||||
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 {
|
||||
match head.as_ref() {
|
||||
@@ -105,9 +99,7 @@ fn is_partial_string<'a>(
|
||||
impl<'a> TermIterState<'a> {
|
||||
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
|
||||
match term {
|
||||
&Term::AnonVar => {
|
||||
TermIterState::AnonVar(lvl)
|
||||
}
|
||||
&Term::AnonVar => TermIterState::AnonVar(lvl),
|
||||
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
|
||||
let ct = if let Some(spec) = spec {
|
||||
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
|
||||
@@ -120,12 +112,8 @@ impl<'a> TermIterState<'a> {
|
||||
&Term::Cons(ref cell, ref head, ref tail) => {
|
||||
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
|
||||
}
|
||||
&Term::Constant(ref cell, ref constant) => {
|
||||
TermIterState::Constant(lvl, cell, constant)
|
||||
}
|
||||
&Term::Var(ref cell, ref var) => {
|
||||
TermIterState::Var(lvl, cell, var.clone())
|
||||
}
|
||||
&Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
|
||||
&Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,8 +163,7 @@ impl<'a> QueryIterator<'a> {
|
||||
state_stack: vec![],
|
||||
}
|
||||
}
|
||||
&Term::Var(ref cell, ref var) =>
|
||||
TermIterState::Var(Level::Root, cell, (*var).clone()),
|
||||
&Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
|
||||
};
|
||||
|
||||
QueryIterator {
|
||||
@@ -265,18 +252,15 @@ impl<'a> Iterator for QueryIterator<'a> {
|
||||
}
|
||||
TermIterState::InitialCons(lvl, cell, head, tail) => {
|
||||
if let Some((string, tail)) = is_partial_string(head, tail) {
|
||||
self.state_stack.push(TermIterState::PartialString(
|
||||
lvl,
|
||||
cell,
|
||||
string,
|
||||
tail,
|
||||
));
|
||||
self.state_stack
|
||||
.push(TermIterState::PartialString(lvl, cell, string, tail));
|
||||
|
||||
if let Some(tail) = tail {
|
||||
self.push_subterm(lvl.child_level(), tail);
|
||||
}
|
||||
} 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(), head);
|
||||
@@ -309,7 +293,8 @@ pub struct FactIterator<'a> {
|
||||
|
||||
impl<'a> FactIterator<'a> {
|
||||
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 {
|
||||
@@ -393,8 +378,7 @@ impl<'a> Iterator for FactIterator<'a> {
|
||||
TermIterState::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 {
|
||||
ChunkedIterator {
|
||||
chunk_num: 0,
|
||||
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false,
|
||||
/*
|
||||
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
|
||||
ChunkedIterator {
|
||||
chunk_num: 0,
|
||||
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
||||
deep_cut_encountered: false,
|
||||
cut_var_in_head: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
|
||||
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
|
||||
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
abolish/1, asserta/1, assertz/1,
|
||||
at_end_of_stream/0, at_end_of_stream/1,
|
||||
atom_chars/2, atom_codes/2, atom_concat/3,
|
||||
atom_length/2, bagof/3, catch/3, char_code/2,
|
||||
clause/2, close/1, close/2, current_input/1,
|
||||
current_output/1, current_op/3,
|
||||
atom_length/2, bagof/3, call/1, call/2, call/3,
|
||||
call/4, call/5, call/6, call/7, call/8, call/9,
|
||||
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,
|
||||
fail/0, false/0, findall/3, findall/4,
|
||||
flush_output/0, flush_output/1, get_byte/1,
|
||||
@@ -38,6 +39,30 @@ true.
|
||||
|
||||
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 :-
|
||||
( atom(Module) ->
|
||||
'$module_call'(Module, Predicate)
|
||||
@@ -209,6 +234,8 @@ G1 -> G2 :-
|
||||
).
|
||||
|
||||
|
||||
:-non_counted_backtracking call_or_cut/3.
|
||||
|
||||
call_or_cut(G, B, ErrorPI) :-
|
||||
( '$call_with_default_policy'(var(G)) ->
|
||||
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).
|
||||
call_or_cut((G1, G2), B) :-
|
||||
!,
|
||||
call_or_cut_interp((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_or_cut((G1 -> G2), B) :-
|
||||
!,
|
||||
call_or_cut_interp((G1 -> G2), B) :-
|
||||
'$call_with_default_policy'(->(G1, G2, B)).
|
||||
call_or_cut(G, _) :-
|
||||
'$call_with_default_policy'(G).
|
||||
|
||||
|
||||
:- non_counted_backtracking (',')/3.
|
||||
','((G1, G2), G3, B) :-
|
||||
|
||||
','(M:G1, G2, B) :-
|
||||
!,
|
||||
'$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'(';'(G1, G2, B)),
|
||||
'$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)).
|
||||
( 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'(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.
|
||||
';'((G1, G2), G3, B) :-
|
||||
|
||||
';'(M:G1, G2, B) :-
|
||||
!,
|
||||
( '$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'(';'(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))
|
||||
( 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))
|
||||
@@ -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.
|
||||
->((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'(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'(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'(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.
|
||||
|
||||
@@ -640,8 +711,11 @@ iterate_variants([V-Solution|GroupSolutions], V, Solution) :-
|
||||
iterate_variants([_|GroupSolutions], Ws, Solution) :-
|
||||
iterate_variants(GroupSolutions, Ws, Solution).
|
||||
|
||||
|
||||
rightmost_power(Term, FinalTerm, Xs) :-
|
||||
( Term = X ^ Y
|
||||
( ( Term = X ^ Y
|
||||
; Term = _ : X ^ Y
|
||||
)
|
||||
-> ( var(Y) -> FinalTerm = Y, Xs = [X]
|
||||
; 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) :-
|
||||
( nonvar(Goal),
|
||||
Goal = _ ^ _ ->
|
||||
( Goal = _ ^ _
|
||||
; Goal = _ : (_ ^ _)
|
||||
) ->
|
||||
rightmost_power(Goal, Goal1, ExistentialVars0),
|
||||
term_variables(ExistentialVars0, ExistentialVars),
|
||||
sort(Witnesses0, Witnesses1),
|
||||
@@ -714,13 +788,16 @@ setof(Template, Goal, Solution) :-
|
||||
).
|
||||
|
||||
'$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) ->
|
||||
( Name == '.' ->
|
||||
throw(error(type_error(callable, H), clause/2))
|
||||
; '$no_such_predicate'(Module, H) ->
|
||||
'$fail'
|
||||
; '$head_is_dynamic'(Module, H) ->
|
||||
'$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),
|
||||
clause/2))
|
||||
)
|
||||
@@ -728,8 +805,6 @@ setof(Template, Goal, Solution) :-
|
||||
).
|
||||
|
||||
|
||||
:- dynamic('$clause'/2).
|
||||
|
||||
clause(H, B) :-
|
||||
( var(H) ->
|
||||
throw(error(instantiation_error, clause/2))
|
||||
@@ -753,24 +828,19 @@ clause(H, B) :-
|
||||
; 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),
|
||||
functor(VarHead, Name, Arity),
|
||||
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses),
|
||||
'$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).
|
||||
functor(_, Name, Arity),
|
||||
'$asserta'(Head, Body, Name, Arity, 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),
|
||||
atom(Name),
|
||||
Name \== '.' ->
|
||||
( '$module_head_is_dynamic'(Head, Module) ->
|
||||
call_module_asserta(Head, Body, Name, Arity, Module)
|
||||
( '$head_is_dynamic'(Module, Head) ->
|
||||
call_asserta(Head, Body, Name, Arity, Module)
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
|
||||
)
|
||||
; throw(error(type_error(callable, Head), asserta/1))
|
||||
@@ -787,9 +857,9 @@ asserta_clause(Head, Body) :-
|
||||
arg(2, Head, F),
|
||||
module_asserta_clause(F, Body, Module)
|
||||
; '$no_such_predicate'(user, Head) ->
|
||||
call_asserta(Head, Body, Name, Arity)
|
||||
call_asserta(Head, Body, Name, Arity, user)
|
||||
; '$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(type_error(callable, Head), asserta/1))
|
||||
@@ -798,36 +868,33 @@ asserta_clause(Head, Body) :-
|
||||
asserta(Clause) :-
|
||||
( Clause \= (_ :- _) ->
|
||||
Head = Clause,
|
||||
Body = true, asserta_clause(Head, Body)
|
||||
Body = true,
|
||||
asserta_clause(Head, Body)
|
||||
; 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) :-
|
||||
( var(Head) ->
|
||||
throw(error(instantiation_error, assertz/1))
|
||||
; functor(Head, Name, Arity),
|
||||
atom(Name),
|
||||
Name \== '.' ->
|
||||
( '$head_is_dynamic'(Module, Head) ->
|
||||
call_module_assertz(Head, Body, Name, Arity, Module)
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1))
|
||||
( '$no_such_predicate'(Module, Head) ->
|
||||
call_assertz(Head, Body, Name, Arity, Module)
|
||||
; '$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))
|
||||
).
|
||||
|
||||
% MODIFIED.
|
||||
call_assertz(Head, Body, Name, Arity) :-
|
||||
|
||||
call_assertz(Head, Body, Name, Arity, Module) :-
|
||||
'$clause_body_is_valid'(Body),
|
||||
functor(VarHead, Name, Arity),
|
||||
'$assertz'(Head, Body, Name, Arity).
|
||||
functor(_, Name, Arity),
|
||||
'$assertz'(Head, Body, Name, Arity, Module).
|
||||
|
||||
assertz_clause(Head, Body) :-
|
||||
( var(Head) ->
|
||||
@@ -835,16 +902,17 @@ assertz_clause(Head, Body) :-
|
||||
; functor(Head, Name, Arity),
|
||||
atom(Name),
|
||||
Name \== '.' ->
|
||||
( Name == (:),
|
||||
Arity =:= 2 ->
|
||||
arg(1, Head, Module),
|
||||
arg(2, Head, F),
|
||||
module_assertz_clause(F, Body, Module)
|
||||
; '$no_such_predicate'(user, Head) ->
|
||||
call_assertz(Head, Body, Name, Arity)
|
||||
; '$head_is_dynamic'(user, Head) ->
|
||||
call_assertz(Head, Body, Name, Arity)
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1))
|
||||
( Name == (:),
|
||||
Arity =:= 2 ->
|
||||
arg(1, Head, Module),
|
||||
arg(2, Head, F),
|
||||
module_assertz_clause(F, Body, Module)
|
||||
; '$no_such_predicate'(user, Head) ->
|
||||
call_assertz(Head, Body, Name, Arity, user)
|
||||
; '$head_is_dynamic'(user, Head) ->
|
||||
call_assertz(Head, Body, Name, Arity, user)
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity),
|
||||
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) :-
|
||||
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),
|
||||
( Clauses0 == [] -> !
|
||||
; 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).
|
||||
|
||||
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).
|
||||
|
||||
retract_module_clause(Head, Body, Module) :-
|
||||
@@ -881,9 +949,12 @@ retract_module_clause(Head, Body, Module) :-
|
||||
; functor(Head, Name, Arity),
|
||||
atom(Name),
|
||||
Name \== '.' ->
|
||||
( '$module_head_is_dynamic'(Head, Module) ->
|
||||
call_module_retract(Head, Body, Name, Arity, Module)
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
||||
( '$head_is_dynamic'(Module, Head) ->
|
||||
( Module == user ->
|
||||
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))
|
||||
).
|
||||
@@ -904,7 +975,7 @@ retract_clauses([Clause | Clauses0], Head, Body, Name, Arity) :-
|
||||
( Clauses0 == [] -> !
|
||||
; 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).
|
||||
@@ -919,16 +990,16 @@ retract_clause(Head, Body) :-
|
||||
; functor(Head, Name, Arity),
|
||||
atom(Name),
|
||||
Name \== '.' ->
|
||||
( Name == (:),
|
||||
Arity =:= 2 ->
|
||||
arg(1, Head, Module),
|
||||
arg(2, Head, F),
|
||||
retract_module_clause(F, Body, Module)
|
||||
; '$head_is_dynamic'(user, Head) ->
|
||||
call_retract(Head, Body, Name, Arity)
|
||||
; '$no_such_predicate'(user, Head) ->
|
||||
'$fail'
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
||||
( Name == (:),
|
||||
Arity =:= 2 ->
|
||||
arg(1, Head, Module),
|
||||
arg(2, Head, F),
|
||||
retract_module_clause(F, Body, Module)
|
||||
; '$head_is_dynamic'(user, Head) ->
|
||||
call_retract(Head, Body, Name, Arity)
|
||||
; '$no_such_predicate'(user, Head) ->
|
||||
'$fail'
|
||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
||||
)
|
||||
; throw(error(type_error(callable, Head), retract/1))
|
||||
).
|
||||
@@ -950,21 +1021,21 @@ module_abolish(Pred, Module) :-
|
||||
( var(Name) ->
|
||||
throw(error(instantiation_error, abolish/1))
|
||||
; integer(Arity) ->
|
||||
( \+ atom(Name) ->
|
||||
throw(error(type_error(atom, Name), abolish/1))
|
||||
; Arity < 0 ->
|
||||
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
||||
; max_arity(N), Arity > N ->
|
||||
throw(error(representation_error(max_arity), abolish/1))
|
||||
; functor(Head, Name, Arity) ->
|
||||
( '$module_head_is_dynamic'(Head, Module) ->
|
||||
'$abolish_module_clause'(Name, Arity, Module)
|
||||
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
|
||||
)
|
||||
( \+ atom(Name) ->
|
||||
throw(error(type_error(atom, Name), abolish/1))
|
||||
; Arity < 0 ->
|
||||
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
||||
; max_arity(N), Arity > N ->
|
||||
throw(error(representation_error(max_arity), abolish/1))
|
||||
; functor(Head, Name, Arity) ->
|
||||
( '$head_is_dynamic'(Module, Head) ->
|
||||
'$abolish_clause'(Module, Name, Arity)
|
||||
; throw(error(permission_error(modify, static_procedure, Pred), 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) :-
|
||||
@@ -978,17 +1049,19 @@ abolish(Pred) :-
|
||||
; var(Arity) ->
|
||||
throw(error(instantiation_error, abolish/1))
|
||||
; integer(Arity) ->
|
||||
( \+ atom(Name) ->
|
||||
throw(error(type_error(atom, Name), abolish/1))
|
||||
; Arity < 0 ->
|
||||
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
||||
; max_arity(N), Arity > N ->
|
||||
throw(error(representation_error(max_arity), abolish/1))
|
||||
; functor(Head, Name, Arity) ->
|
||||
( '$no_such_predicate'(Head) -> true
|
||||
; '$head_is_dynamic'(Head) -> '$abolish_clause'(Name, Arity)
|
||||
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
|
||||
)
|
||||
( \+ atom(Name) ->
|
||||
throw(error(type_error(atom, Name), abolish/1))
|
||||
; Arity < 0 ->
|
||||
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
||||
; max_arity(N), Arity > N ->
|
||||
throw(error(representation_error(max_arity), abolish/1))
|
||||
; functor(Head, Name, Arity) ->
|
||||
( '$no_such_predicate'(user, Head) ->
|
||||
true
|
||||
; '$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))
|
||||
)
|
||||
|
||||
@@ -3068,12 +3068,10 @@ is_false(var(X)) :- nonvar(X).
|
||||
|
||||
:- dynamic(goal_expansion/1).
|
||||
|
||||
% goal expansion is disabled for now, until #445 is resolved
|
||||
%
|
||||
% user:goal_expansion(Goal0, Goal) :-
|
||||
% \+ goal_expansion(false),
|
||||
% clpz_expandable(Goal0),
|
||||
% clpz_expansion(Goal0, Goal).
|
||||
user:goal_expansion(Goal0, Goal) :-
|
||||
\+ goal_expansion(false),
|
||||
clpz_expandable(Goal0),
|
||||
clpz_expansion(Goal0, Goal).
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
@@ -125,3 +125,5 @@
|
||||
:- meta_predicate call(61, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||
:- meta_predicate call(62, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||
:- meta_predicate call(63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||
:- meta_predicate call(64, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||
:- meta_predicate call(65, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||
|
||||
@@ -15,7 +15,7 @@ parse_socket_options_(Option, OptionPair) :-
|
||||
|
||||
parse_socket_options(Options, OptionValues, Stub) :-
|
||||
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) :-
|
||||
( var(Addr) ->
|
||||
|
||||
844
src/loader.pl
844
src/loader.pl
@@ -18,14 +18,14 @@
|
||||
|
||||
|
||||
'$print_message_and_fail'(Error, Culprit) :-
|
||||
% writeq(error(Error, Culprit)),
|
||||
% nl,
|
||||
% writeq(error(Error, Culprit)),
|
||||
% nl,
|
||||
'$fail'.
|
||||
|
||||
expand_term(Term, ExpandedTerm) :-
|
||||
( catch(user:term_expansion(Term, ExpandedTerm0),
|
||||
( catch('$call'(user:term_expansion(Term, ExpandedTerm0)),
|
||||
E,
|
||||
loader:'$print_message_and_fail'(E, user:term_expansion)) ->
|
||||
'$call'(loader:'$print_message_and_fail'(E, user:term_expansion))) ->
|
||||
( var(ExpandedTerm0) ->
|
||||
error:instantiation_error(term_expansion/2)
|
||||
; ExpandedTerm0 = [_|_] ->
|
||||
@@ -35,7 +35,6 @@ expand_term(Term, ExpandedTerm) :-
|
||||
; Term = ExpandedTerm
|
||||
).
|
||||
|
||||
|
||||
term_expansion_list([], ExpandedTerms, ExpandedTerms).
|
||||
term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
|
||||
expand_term(Term, ExpandedTerm0),
|
||||
@@ -50,9 +49,9 @@ term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
|
||||
|
||||
|
||||
goal_expansion(Goal, Module, ExpandedGoal) :-
|
||||
( catch(Module:goal_expansion(Goal, ExpandedGoal0),
|
||||
( catch('$call'(Module:goal_expansion(Goal, ExpandedGoal0)),
|
||||
E,
|
||||
loader:'$print_message_and_fail'(E, Module:goal_expansion)) ->
|
||||
'$call'(loader:'$print_message_and_fail'(E, Module:goal_expansion))) ->
|
||||
( var(ExpandedGoal0) ->
|
||||
error:instantiation_error(goal_expansion/2)
|
||||
; goal_expansion(ExpandedGoal0, Module, ExpandedGoal)
|
||||
@@ -74,6 +73,16 @@ unload_evacuable(Evacuable) :-
|
||||
'$pop_load_state_payload'(Evacuable),
|
||||
'$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, _).
|
||||
@@ -83,6 +92,7 @@ file_load(Stream, Path, Evacuable) :-
|
||||
catch(loader:load_loop(Stream, Evacuable),
|
||||
E,
|
||||
(loader:unload_evacuable(Evacuable), throw(E))),
|
||||
run_initialization_goals,
|
||||
'$pop_load_context'.
|
||||
|
||||
|
||||
@@ -91,6 +101,7 @@ load(Stream) :-
|
||||
catch(loader:load_loop(Stream, Evacuable),
|
||||
E,
|
||||
(loader:unload_evacuable(Evacuable), throw(E))),
|
||||
run_initialization_goals,
|
||||
'$pop_load_context'.
|
||||
|
||||
load_loop(Stream, Evacuable) :-
|
||||
@@ -195,8 +206,7 @@ compile_dispatch_or_clause(Term, Evacuable, VNs) :-
|
||||
compile_dispatch((:- Declaration), Evacuable, _VNs) :-
|
||||
( var(Declaration) ->
|
||||
instantiation_error(load/1)
|
||||
;
|
||||
compile_declaration(Declaration, Evacuable)
|
||||
; compile_declaration(Declaration, Evacuable)
|
||||
).
|
||||
compile_dispatch(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 == [] ->
|
||||
'$remove_module_exports'(Module, Evacuable) % TODO: implement this.
|
||||
;
|
||||
use_module(Module, Exports, Evacuable)
|
||||
use_module(Module, Exports, Evacuable)
|
||||
).
|
||||
compile_declaration(module(Module, Exports), Evacuable) :-
|
||||
( atom(Module) ->
|
||||
'$declare_module'(Module, Exports, Evacuable)
|
||||
;
|
||||
type_error(atom, Module, load/1)
|
||||
type_error(atom, Module, load/1)
|
||||
).
|
||||
compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
||||
must_be(atom, Name),
|
||||
@@ -238,9 +248,8 @@ compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
||||
'$add_dynamic_predicate'(Name, Arity, Evacuable).
|
||||
compile_declaration(initialization(Goal), Evacuable) :-
|
||||
prolog_load_context(module, Module),
|
||||
'$compile_pending_predicates'(Evacuable),
|
||||
expand_goal(call(Goal), Module, call(ExpandedGoal)),
|
||||
call(ExpandedGoal).
|
||||
assertz(Module:'$initialization_goals'(Goal)).
|
||||
|
||||
|
||||
|
||||
compile_clause(Clause, Evacuable, VNs) :-
|
||||
@@ -290,45 +299,64 @@ use_module(Module, Exports) :-
|
||||
'$push_load_state_payload'(Evacuable),
|
||||
( Exports == [] ->
|
||||
'$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
|
||||
%% directory. Otherwise, use the relative path of Path.
|
||||
|
||||
load_context_path(Module, Path) :-
|
||||
( prolog_load_context(directory, CurrentDir) ->
|
||||
atom_concat(CurrentDir, Path, Module)
|
||||
;
|
||||
Module = Path
|
||||
% Rust's Path module never ends a directory path with '/', so
|
||||
% add one here.
|
||||
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) :-
|
||||
( var(Module) ->
|
||||
instantiation_error(load/1)
|
||||
; Module = library(Library) ->
|
||||
( atom(Library) ->
|
||||
( '$load_compiled_library'(Library, Evacuable) -> %% TODO: What about Exports?
|
||||
( path_atom(Library, LibraryPath) ->
|
||||
( '$load_compiled_library'(LibraryPath, Evacuable) -> %% TODO: What about Exports?
|
||||
true
|
||||
;
|
||||
'$load_library_as_stream'(Library, Stream, Path),
|
||||
; '$load_library_as_stream'(LibraryPath, Stream, Path),
|
||||
file_load(Stream, Path, Subevacuable),
|
||||
'$use_module'(Evacuable, Subevacuable, Exports)
|
||||
)
|
||||
; var(Library) ->
|
||||
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).
|
||||
check_predicate_property(built_in, _, Name, Arity, built_in) :-
|
||||
'$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) :-
|
||||
@@ -345,35 +380,47 @@ extract_predicate_property(Property, PropertyType) :-
|
||||
; functor(Property, PropertyType, _)
|
||||
).
|
||||
|
||||
load_context(Module) :-
|
||||
( prolog_load_context(module, Module) ->
|
||||
true
|
||||
; Module = user
|
||||
).
|
||||
|
||||
predicate_property(Callable, Property) :-
|
||||
( var(Callable) ->
|
||||
instantiation_error(load/1)
|
||||
; Callable =.. [(:), Module, Callable0],
|
||||
; functor(Callable, (:), 2), % Callable =.. [(:), Module, Callable0],
|
||||
arg(1, Callable, Module),
|
||||
arg(2, Callable, Callable0),
|
||||
atom(Module) ->
|
||||
functor(Callable0, Name, Arity),
|
||||
extract_predicate_property(Property, PropertyType),
|
||||
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
||||
( atom(Name),
|
||||
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),
|
||||
extract_predicate_property(Property, PropertyType),
|
||||
( prolog_load_context(module, Module) ->
|
||||
true
|
||||
; Module = user
|
||||
),
|
||||
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
||||
( atom(Name),
|
||||
Name \== [] ->
|
||||
extract_predicate_property(Property, PropertyType),
|
||||
load_context(Module),
|
||||
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),
|
||||
G0 = (MG1:G2) ->
|
||||
strip_module_(MG1, G2, M1, G1)
|
||||
strip_module(MG1, G2, M1, G1)
|
||||
; M0 = M1,
|
||||
G0 = G1
|
||||
).
|
||||
|
||||
strip_module(Goal, M, G) :-
|
||||
strip_module_(_, Goal, M, G).
|
||||
|
||||
strip_module(_, Goal, M, G).
|
||||
|
||||
|
||||
expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
|
||||
@@ -498,3 +545,710 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
|
||||
; 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
@@ -51,7 +51,6 @@ call_goals_0([Module-GoalList | GoalLists]) :-
|
||||
call_goals_0([]).
|
||||
|
||||
call_goals_1([Goal | Goals], Module) :-
|
||||
expand_goal(Goal, Module, Goal1), % TODO: remove this when goal expansions are added to call/N.
|
||||
call(Module:Goal1),
|
||||
call(Module:Goal),
|
||||
call_goals_1(Goals, Module).
|
||||
call_goals_1([], _).
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use crate::heap_iter::*;
|
||||
use crate::machine::*;
|
||||
use prolog_parser::temp_v;
|
||||
|
||||
use crate::indexmap::IndexSet;
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::vec::IntoIter;
|
||||
@@ -20,8 +21,7 @@ pub(super) struct AttrVarInitializer {
|
||||
}
|
||||
|
||||
impl AttrVarInitializer {
|
||||
pub(super)
|
||||
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||
AttrVarInitializer {
|
||||
attribute_goals: vec![],
|
||||
attr_var_queue: vec![],
|
||||
@@ -34,24 +34,21 @@ impl AttrVarInitializer {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn reset(&mut self) {
|
||||
self.attribute_goals.clear();
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.attribute_goals.clear();
|
||||
self.attr_var_queue.clear();
|
||||
self.bindings.clear();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||
pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||
self.attr_var_queue.truncate(queue_b);
|
||||
self.bindings.truncate(bindings_b);
|
||||
}
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(super)
|
||||
fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||
if self.attr_var_init.bindings.is_empty() {
|
||||
self.attr_var_init.instigating_p = self.p.local();
|
||||
|
||||
@@ -79,7 +76,7 @@ impl MachineState {
|
||||
let iter = self
|
||||
.attr_var_init
|
||||
.bindings
|
||||
.drain(0 ..)
|
||||
.drain(0..)
|
||||
.map(|(_, addr)| HeapCellValue::Addr(addr));
|
||||
|
||||
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
|
||||
@@ -97,8 +94,7 @@ impl MachineState {
|
||||
self[temp_v!(2)] = value_list_addr;
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||
pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
||||
.iter()
|
||||
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||
@@ -107,29 +103,25 @@ impl MachineState {
|
||||
})
|
||||
.collect();
|
||||
|
||||
attr_vars.sort_unstable_by(|a1, a2| {
|
||||
self.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
|
||||
});
|
||||
attr_vars
|
||||
.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2).unwrap_or(Ordering::Less));
|
||||
|
||||
self.term_dedup(&mut attr_vars);
|
||||
attr_vars.into_iter()
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn verify_attr_interrupt(&mut self, p: usize) {
|
||||
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
||||
self.allocate(self.num_of_args + 2);
|
||||
|
||||
let e = self.e;
|
||||
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)[self.num_of_args + 1] =
|
||||
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 + 1] = Addr::CutPoint(self.b0);
|
||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Usize(self.num_of_args);
|
||||
|
||||
self.verify_attributes();
|
||||
|
||||
@@ -138,9 +130,8 @@ impl MachineState {
|
||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
||||
let mut seen_set = IndexSet::new();
|
||||
pub(super) fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
||||
let mut seen_set = IndexSet::new();
|
||||
let mut seen_vars = vec![];
|
||||
|
||||
let mut iter = self.acyclic_pre_order_iter(addr);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::prolog_parser_rebis::ast::Constant;
|
||||
use prolog_parser::ast::Constant;
|
||||
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::partial_string::*;
|
||||
@@ -42,16 +42,17 @@ impl<T: RawBlockTraits> Drop for HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate)
|
||||
struct HeapIntoIter<T: RawBlockTraits> {
|
||||
pub(crate) struct HeapIntoIter<T: RawBlockTraits> {
|
||||
offset: usize,
|
||||
buf: RawBlock<T>,
|
||||
}
|
||||
|
||||
impl<T: RawBlockTraits> Drop for HeapIntoIter<T> {
|
||||
fn drop(&mut self) {
|
||||
let mut heap =
|
||||
HeapTemplate { buf: self.buf.take(), _marker: PhantomData };
|
||||
let mut heap = HeapTemplate {
|
||||
buf: self.buf.take(),
|
||||
_marker: PhantomData,
|
||||
};
|
||||
|
||||
heap.truncate(self.offset / mem::size_of::<HeapCellValue>());
|
||||
heap.buf.deallocate();
|
||||
@@ -66,9 +67,7 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
|
||||
self.offset += mem::size_of::<HeapCellValue>();
|
||||
|
||||
if ptr < self.buf.top as usize {
|
||||
unsafe {
|
||||
Some(ptr::read(ptr as *const HeapCellValue))
|
||||
}
|
||||
unsafe { Some(ptr::read(ptr as *const HeapCellValue)) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -76,15 +75,13 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate)
|
||||
struct HeapIter<'a, T: RawBlockTraits> {
|
||||
pub(crate) struct HeapIter<'a, T: RawBlockTraits> {
|
||||
offset: usize,
|
||||
buf: &'a RawBlock<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: RawBlockTraits> HeapIter<'a, T> {
|
||||
pub(crate)
|
||||
fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
|
||||
pub(crate) fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
|
||||
HeapIter { buf, offset }
|
||||
}
|
||||
}
|
||||
@@ -97,9 +94,7 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
|
||||
self.offset += mem::size_of::<HeapCellValue>();
|
||||
|
||||
if ptr < self.buf.top as usize {
|
||||
unsafe {
|
||||
Some(&*(ptr as *const _))
|
||||
}
|
||||
unsafe { Some(&*(ptr as *const _)) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -107,23 +102,20 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate)
|
||||
fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
|
||||
pub(crate) fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
|
||||
for (index, term) in heap.enumerate() {
|
||||
println!("{} : {}", h + index, term);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate)
|
||||
struct HeapIterMut<'a, T: RawBlockTraits> {
|
||||
pub(crate) struct HeapIterMut<'a, T: RawBlockTraits> {
|
||||
offset: usize,
|
||||
buf: &'a mut RawBlock<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> {
|
||||
pub(crate)
|
||||
fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
|
||||
pub(crate) fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
|
||||
HeapIterMut { buf, offset }
|
||||
}
|
||||
}
|
||||
@@ -136,9 +128,7 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
|
||||
self.offset += mem::size_of::<HeapCellValue>();
|
||||
|
||||
if ptr < self.buf.top as usize {
|
||||
unsafe {
|
||||
Some(&mut *(ptr as *mut _))
|
||||
}
|
||||
unsafe { Some(&mut *(ptr as *mut _)) }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -147,51 +137,33 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
|
||||
|
||||
impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn new() -> Self {
|
||||
HeapTemplate { 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))
|
||||
}
|
||||
pub(crate) fn new() -> Self {
|
||||
HeapTemplate {
|
||||
buf: RawBlock::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn put_complete_string(&mut self, s: &str) -> Addr {
|
||||
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]
|
||||
pub(crate) fn put_complete_string(&mut self, s: &str) -> Addr {
|
||||
if s.is_empty() {
|
||||
return Addr::EmptyList;
|
||||
}
|
||||
@@ -214,30 +186,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn put_constant(&mut self, c: Constant) -> Addr {
|
||||
pub(crate) fn put_constant(&mut self, c: Constant) -> Addr {
|
||||
match c {
|
||||
Constant::Atom(name, op) => {
|
||||
Addr::Con(self.push(HeapCellValue::Atom(name, op)))
|
||||
}
|
||||
Constant::Char(c) => {
|
||||
Addr::Char(c)
|
||||
}
|
||||
Constant::EmptyList => {
|
||||
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::Atom(name, op) => Addr::Con(self.push(HeapCellValue::Atom(name, op))),
|
||||
Constant::Char(c) => Addr::Char(c),
|
||||
Constant::EmptyList => 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) => {
|
||||
if s.is_empty() {
|
||||
Addr::EmptyList
|
||||
@@ -245,15 +202,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
self.put_complete_string(&s)
|
||||
}
|
||||
}
|
||||
Constant::Usize(n) => {
|
||||
Addr::Usize(n)
|
||||
}
|
||||
Constant::Usize(n) => Addr::Usize(n),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn pop(&mut self) {
|
||||
pub(crate) fn pop(&mut self) {
|
||||
let h = self.h();
|
||||
|
||||
if h > 0 {
|
||||
@@ -262,8 +216,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn push(&mut self, val: HeapCellValue) -> usize {
|
||||
pub(crate) fn push(&mut self, val: HeapCellValue) -> usize {
|
||||
let h = self.h();
|
||||
|
||||
unsafe {
|
||||
@@ -276,8 +229,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn atom_at(&self, h: usize) -> bool {
|
||||
pub(crate) fn atom_at(&self, h: usize) -> bool {
|
||||
if let HeapCellValue::Atom(..) = &self[h] {
|
||||
true
|
||||
} else {
|
||||
@@ -286,24 +238,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
|
||||
pub(crate) fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
|
||||
match non_heap_value {
|
||||
HeapCellValue::Addr(addr) => {
|
||||
addr
|
||||
}
|
||||
val @ HeapCellValue::Atom(..) |
|
||||
val @ HeapCellValue::Integer(_) |
|
||||
val @ HeapCellValue::DBRef(_) |
|
||||
val @ HeapCellValue::Rational(_) => {
|
||||
Addr::Con(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::LoadStatePayload(_) => {
|
||||
Addr::LoadStatePayload(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::NamedStr(..) => {
|
||||
Addr::Str(self.push(val))
|
||||
}
|
||||
HeapCellValue::Addr(addr) => addr,
|
||||
val @ HeapCellValue::Atom(..)
|
||||
| val @ HeapCellValue::Integer(_)
|
||||
| val @ HeapCellValue::DBRef(_)
|
||||
| val @ HeapCellValue::Rational(_) => 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) => {
|
||||
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
@@ -313,20 +256,14 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
|
||||
Addr::Con(h)
|
||||
}
|
||||
val @ HeapCellValue::Stream(..) => {
|
||||
Addr::Stream(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::TcpListener(..) => {
|
||||
Addr::TcpListener(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::Stream(..) => Addr::Stream(self.push(val)),
|
||||
val @ HeapCellValue::TcpListener(..) => Addr::TcpListener(self.push(val)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn allocate_pstr(&mut self, src: &str) -> Addr {
|
||||
self.write_pstr(src)
|
||||
.unwrap_or_else(|| Addr::EmptyList)
|
||||
pub(crate) fn allocate_pstr(&mut self, src: &str) -> Addr {
|
||||
self.write_pstr(src).unwrap_or_else(|| Addr::EmptyList)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -347,23 +284,20 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
|
||||
let h = self.h();
|
||||
|
||||
let (pstr, rest_src) =
|
||||
match PartialString::new(src) {
|
||||
Some(tuple) => {
|
||||
tuple
|
||||
let (pstr, rest_src) = match PartialString::new(src) {
|
||||
Some(tuple) => tuple,
|
||||
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));
|
||||
}
|
||||
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));
|
||||
|
||||
@@ -378,8 +312,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn truncate(&mut self, h: usize) {
|
||||
pub(crate) fn truncate(&mut self, h: usize) {
|
||||
let new_top = h * mem::size_of::<HeapCellValue>() + self.buf.base as usize;
|
||||
let mut h = new_top;
|
||||
|
||||
@@ -395,30 +328,27 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn h(&self) -> usize {
|
||||
pub(crate) fn h(&self) -> usize {
|
||||
(self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>()
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn append(&mut self, vals: Vec<HeapCellValue>) {
|
||||
pub(crate) fn append(&mut self, vals: Vec<HeapCellValue>) {
|
||||
for val in vals {
|
||||
self.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn clear(&mut self) {
|
||||
pub(crate) fn clear(&mut self) {
|
||||
if !self.buf.base.is_null() {
|
||||
self.truncate(0);
|
||||
self.buf.top = self.buf.base;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn to_list<Iter, SrcT>(&mut self, values: Iter) -> usize
|
||||
where Iter: Iterator<Item = SrcT>,
|
||||
SrcT: Into<HeapCellValue>
|
||||
pub(crate) fn to_list<Iter, SrcT>(&mut self, values: Iter) -> usize
|
||||
where
|
||||
Iter: Iterator<Item = SrcT>,
|
||||
SrcT: Into<HeapCellValue>,
|
||||
{
|
||||
let head_addr = self.h();
|
||||
let mut h = head_addr;
|
||||
@@ -436,35 +366,33 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
}
|
||||
|
||||
/* Create an iterator starting from the passed offset. */
|
||||
pub(crate)
|
||||
fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
|
||||
pub(crate) fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
|
||||
HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
|
||||
pub(crate) fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
|
||||
HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn into_iter(mut self) -> HeapIntoIter<T> {
|
||||
HeapIntoIter { buf: self.buf.take(), offset: 0 }
|
||||
pub(crate) fn into_iter(mut self) -> HeapIntoIter<T> {
|
||||
HeapIntoIter {
|
||||
buf: self.buf.take(),
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
|
||||
pub(crate) fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
|
||||
for hcv in iter {
|
||||
self.push(hcv);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
|
||||
pub(crate) fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
|
||||
let extract_integer = |s: usize| -> Option<usize> {
|
||||
match &self[s] {
|
||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => usize::try_from(n).ok(),
|
||||
&HeapCellValue::Integer(ref n) => n.to_usize(),
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -473,9 +401,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
match &self[*s] {
|
||||
HeapCellValue::NamedStr(arity, ref name, _) => {
|
||||
match (name.as_str(), *arity) {
|
||||
("dir_entry", 1) => {
|
||||
extract_integer(s+1).map(LocalCodePtr::DirEntry)
|
||||
}
|
||||
("dir_entry", 1) => extract_integer(s + 1).map(LocalCodePtr::DirEntry),
|
||||
/*
|
||||
("top_level", 2) => {
|
||||
if let Some(chunk_num) = extract_integer(s+1) {
|
||||
@@ -487,15 +413,13 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
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) => {
|
||||
RefOrOwned::Borrowed(&self[h])
|
||||
}
|
||||
addr => {
|
||||
RefOrOwned::Owned(HeapCellValue::Addr(*addr))
|
||||
}
|
||||
addr => RefOrOwned::Owned(HeapCellValue::Addr(*addr)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::machine::*;
|
||||
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 crate::ref_thread_local::RefThreadLocal;
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
|
||||
type ModuleOpExports = Vec<(OpDecl, Option<(usize, Specifier)>)>;
|
||||
|
||||
@@ -19,37 +20,35 @@ pub(super) struct LoadState<'a> {
|
||||
pub(super) wam: &'a mut Machine,
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn set_code_index(
|
||||
pub(super) fn set_code_index(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
key: PredicateKey,
|
||||
code_index: &CodeIndex,
|
||||
code_ptr: IndexPtr,
|
||||
) {
|
||||
let record =
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedUserPredicate(key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
||||
}
|
||||
let record = match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedUserPredicate(key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
|
||||
}
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if IndexPtr::Undefined == code_index.get() {
|
||||
code_index.set(code_ptr);
|
||||
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
|
||||
} else {
|
||||
// TODO: emit warning about overwriting previous record
|
||||
let replaced = code_index.replace(code_ptr);
|
||||
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
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) {
|
||||
Some((prec, spec)) => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec)
|
||||
);
|
||||
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||
op_decl.clone(),
|
||||
prec,
|
||||
spec,
|
||||
));
|
||||
|
||||
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
|
||||
}
|
||||
None => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::AddedUserOp(op_decl.clone())
|
||||
);
|
||||
|
||||
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||
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);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn add_op_decl(
|
||||
pub(super) fn add_op_decl(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
op_dir: &mut OpDir,
|
||||
op_decl: &OpDecl,
|
||||
) {
|
||||
match op_decl.insert_into_op_dir(op_dir) {
|
||||
Some((prec, spec)) => {
|
||||
match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec),
|
||||
);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
retraction_info.push_record(
|
||||
RetractionRecord::ReplacedModuleOp(
|
||||
module_name.clone(), op_decl.clone(), prec, spec,
|
||||
),
|
||||
);
|
||||
}
|
||||
Some((prec, spec)) => match &compilation_target {
|
||||
CompilationTarget::User => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||
op_decl.clone(),
|
||||
prec,
|
||||
spec,
|
||||
));
|
||||
}
|
||||
}
|
||||
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()),
|
||||
);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
|
||||
module_name.clone(),
|
||||
op_decl.clone(),
|
||||
prec,
|
||||
spec,
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
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)
|
||||
fn import_module_exports(
|
||||
pub(super) fn import_module_exports(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
compilation_target: &CompilationTarget,
|
||||
imported_module: &Module,
|
||||
code_dir: &mut CodeDir,
|
||||
op_dir: &mut OpDir,
|
||||
meta_predicates: &mut MetaPredicateDir,
|
||||
) {
|
||||
) -> Result<(), SessionError> {
|
||||
for export in imported_module.module_decl.exports.iter() {
|
||||
match export {
|
||||
ModuleExport::PredicateKey((ref name, arity)) => {
|
||||
@@ -162,19 +156,19 @@ fn import_module_exports(
|
||||
src_code_index.get(),
|
||||
);
|
||||
} else {
|
||||
unreachable!()
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
imported_module.module_decl.name.clone(),
|
||||
(name.clone(), *arity),
|
||||
));
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(ref op_decl) => {
|
||||
add_op_decl(
|
||||
retraction_info,
|
||||
compilation_target,
|
||||
op_dir,
|
||||
op_decl,
|
||||
);
|
||||
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn import_module_exports_into_module(
|
||||
@@ -185,8 +179,8 @@ fn import_module_exports_into_module(
|
||||
op_dir: &mut OpDir,
|
||||
meta_predicates: &mut MetaPredicateDir,
|
||||
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() {
|
||||
match export {
|
||||
ModuleExport::PredicateKey((ref name, arity)) => {
|
||||
@@ -210,7 +204,10 @@ fn import_module_exports_into_module(
|
||||
src_code_index.get(),
|
||||
);
|
||||
} else {
|
||||
unreachable!()
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
imported_module.module_decl.name.clone(),
|
||||
(name.clone(), *arity),
|
||||
));
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(ref op_decl) => {
|
||||
@@ -225,8 +222,9 @@ fn import_module_exports_into_module(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn import_qualified_module_exports(
|
||||
retraction_info: &mut RetractionInfo,
|
||||
@@ -235,7 +233,7 @@ fn import_qualified_module_exports(
|
||||
exports: &IndexSet<ModuleExport>,
|
||||
code_dir: &mut CodeDir,
|
||||
op_dir: &mut OpDir,
|
||||
) {
|
||||
) -> Result<(), SessionError> {
|
||||
for export in imported_module.module_decl.exports.iter() {
|
||||
if !exports.contains(export) {
|
||||
continue;
|
||||
@@ -259,19 +257,19 @@ fn import_qualified_module_exports(
|
||||
src_code_index.get(),
|
||||
);
|
||||
} else {
|
||||
unreachable!()
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
imported_module.module_decl.name.clone(),
|
||||
(name.clone(), *arity),
|
||||
));
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(ref op_decl) => {
|
||||
add_op_decl(
|
||||
retraction_info,
|
||||
compilation_target,
|
||||
op_dir,
|
||||
op_decl,
|
||||
);
|
||||
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn import_qualified_module_exports_into_module(
|
||||
@@ -283,7 +281,7 @@ fn import_qualified_module_exports_into_module(
|
||||
op_dir: &mut OpDir,
|
||||
wam_op_dir: &mut OpDir,
|
||||
module_op_exports: &mut ModuleOpExports,
|
||||
) {
|
||||
) -> Result<(), SessionError> {
|
||||
for export in imported_module.module_decl.exports.iter() {
|
||||
if !exports.contains(export) {
|
||||
continue;
|
||||
@@ -307,7 +305,10 @@ fn import_qualified_module_exports_into_module(
|
||||
src_code_index.get(),
|
||||
);
|
||||
} else {
|
||||
unreachable!()
|
||||
return Err(SessionError::ModuleDoesNotContainExport(
|
||||
imported_module.module_decl.name.clone(),
|
||||
(name.clone(), *arity),
|
||||
));
|
||||
}
|
||||
}
|
||||
ModuleExport::OpDecl(ref op_decl) => {
|
||||
@@ -322,33 +323,34 @@ fn import_qualified_module_exports_into_module(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<'a> LoadState<'a> {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn increment_clause_assert_margin(&mut self, incr: usize) {
|
||||
pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
}
|
||||
CompilationTarget::User => {}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::IncreasedClauseAssertMargin(
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::IncreasedClauseAssertMargin(
|
||||
module_name.clone(),
|
||||
incr,
|
||||
),
|
||||
);
|
||||
));
|
||||
|
||||
self.wam.indices.modules.get_mut(module_name)
|
||||
self.wam
|
||||
.indices
|
||||
.modules
|
||||
.get_mut(module_name)
|
||||
.map(|module| module.clause_assert_margin += incr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn remove_module_op_exports(&mut self) {
|
||||
for (mut op_decl, record) in self.module_op_exports.drain(0 ..) {
|
||||
pub(super) fn remove_module_op_exports(&mut self) {
|
||||
for (mut op_decl, record) in self.module_op_exports.drain(0..) {
|
||||
op_decl.remove(&mut self.wam.indices.op_dir);
|
||||
|
||||
if let Some((prec, spec)) = record {
|
||||
@@ -365,26 +367,28 @@ impl<'a> LoadState<'a> {
|
||||
key: PredicateKey,
|
||||
) -> CodeIndex {
|
||||
match self.wam.indices.modules.get_mut(&module_name) {
|
||||
Some(ref mut module) => {
|
||||
module.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone()
|
||||
}
|
||||
Some(ref mut module) => module
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone(),
|
||||
None => {
|
||||
let mut module = Module::new(
|
||||
ModuleDecl { name: module_name.clone(), exports: vec![] },
|
||||
ModuleDecl {
|
||||
name: module_name.clone(),
|
||||
exports: vec![],
|
||||
},
|
||||
ListingSource::DynamicallyGenerated,
|
||||
);
|
||||
|
||||
let code_index = module.code_dir
|
||||
let code_index = module
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone();
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedModule(module_name.clone()),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
code_index
|
||||
@@ -392,29 +396,31 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
||||
pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
||||
match self.compilation_target.clone() {
|
||||
CompilationTarget::User => {
|
||||
self.wam.indices.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone()
|
||||
}
|
||||
CompilationTarget::User => self
|
||||
.wam
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone(),
|
||||
CompilationTarget::Module(module_name) => {
|
||||
self.get_or_insert_local_code_index(module_name, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_or_insert_qualified_code_index(
|
||||
pub(super) fn get_or_insert_qualified_code_index(
|
||||
&mut self,
|
||||
module_name: ClauseName,
|
||||
key: PredicateKey,
|
||||
) -> CodeIndex {
|
||||
if module_name.as_str() == "user" {
|
||||
return self.wam.indices.code_dir
|
||||
return self
|
||||
.wam
|
||||
.indices
|
||||
.code_dir
|
||||
.entry(key)
|
||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||
.clone();
|
||||
@@ -424,15 +430,20 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn add_extensible_predicate(&mut self, key: PredicateKey, skeleton: PredicateSkeleton) {
|
||||
pub(super) fn add_extensible_predicate(
|
||||
&mut self,
|
||||
key: PredicateKey,
|
||||
skeleton: PredicateSkeleton,
|
||||
) {
|
||||
match &self.compilation_target {
|
||||
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(
|
||||
RetractionRecord::AddedUserExtensiblePredicate(key),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
|
||||
@@ -448,8 +459,7 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
||||
pub(super) fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
add_op_decl(
|
||||
@@ -479,8 +489,7 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_clause_type(
|
||||
pub(super) fn get_clause_type(
|
||||
&mut self,
|
||||
name: ClauseName,
|
||||
arity: usize,
|
||||
@@ -495,14 +504,11 @@ impl<'a> LoadState<'a> {
|
||||
let idx = self.get_or_insert_code_index((name.clone(), arity));
|
||||
ClauseType::Op(name, fixity, idx)
|
||||
}
|
||||
ct => {
|
||||
ct
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_qualified_clause_type(
|
||||
pub(super) fn get_qualified_clause_type(
|
||||
&mut self,
|
||||
module_name: ClauseName,
|
||||
name: ClauseName,
|
||||
@@ -522,27 +528,11 @@ impl<'a> LoadState<'a> {
|
||||
|
||||
ClauseType::Op(name, fixity, idx)
|
||||
}
|
||||
ct => {
|
||||
ct
|
||||
}
|
||||
ct => ct,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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(
|
||||
pub(super) fn add_meta_predicate_record(
|
||||
&mut self,
|
||||
module_name: ClauseName,
|
||||
name: ClauseName,
|
||||
@@ -553,20 +543,26 @@ impl<'a> LoadState<'a> {
|
||||
|
||||
match module_name.as_str() {
|
||||
"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) => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedMetaPredicate(
|
||||
module_name.clone(), key.0, old_meta_specs,
|
||||
),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::ReplacedMetaPredicate(
|
||||
module_name.clone(),
|
||||
key.0,
|
||||
old_meta_specs,
|
||||
));
|
||||
}
|
||||
None => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(), key,
|
||||
)
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(),
|
||||
key,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -577,15 +573,15 @@ impl<'a> LoadState<'a> {
|
||||
Some(old_meta_specs) => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedMetaPredicate(
|
||||
module_name.clone(), key.0, old_meta_specs,
|
||||
module_name.clone(),
|
||||
key.0,
|
||||
old_meta_specs,
|
||||
),
|
||||
);
|
||||
}
|
||||
None => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(), key,
|
||||
)
|
||||
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -601,15 +597,14 @@ impl<'a> LoadState<'a> {
|
||||
|
||||
module.meta_predicates.insert(key.clone(), meta_specs);
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(), key,
|
||||
)
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||
module_name.clone(),
|
||||
key,
|
||||
));
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedModule(module_name.clone()),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
}
|
||||
@@ -632,36 +627,33 @@ impl<'a> LoadState<'a> {
|
||||
code_dir,
|
||||
op_dir,
|
||||
meta_predicates,
|
||||
);
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
||||
pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
||||
let module_name = module_decl.name.clone();
|
||||
|
||||
let mut module =
|
||||
match self.wam.indices.modules.remove(&module_name) {
|
||||
Some(mut module) => {
|
||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
||||
let mut module = match self.wam.indices.modules.remove(&module_name) {
|
||||
Some(mut module) => {
|
||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
||||
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::ReplacedModule(
|
||||
old_module_decl, listing_src.clone(),
|
||||
),
|
||||
);
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::ReplacedModule(
|
||||
old_module_decl,
|
||||
listing_src.clone(),
|
||||
));
|
||||
|
||||
module.listing_src = listing_src;
|
||||
module
|
||||
}
|
||||
None => {
|
||||
self.retraction_info.push_record(
|
||||
RetractionRecord::AddedModule(module_name.clone()),
|
||||
);
|
||||
module.listing_src = listing_src;
|
||||
module
|
||||
}
|
||||
None => {
|
||||
self.retraction_info
|
||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||
|
||||
Module::new(module_decl, listing_src)
|
||||
}
|
||||
};
|
||||
Module::new(module_decl, listing_src)
|
||||
}
|
||||
};
|
||||
|
||||
self.import_builtins_in_module(
|
||||
&mut module.code_dir,
|
||||
@@ -689,8 +681,7 @@ impl<'a> LoadState<'a> {
|
||||
self.wam.indices.modules.insert(module_name, module);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
||||
pub(super) fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
||||
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
@@ -701,7 +692,7 @@ impl<'a> LoadState<'a> {
|
||||
&mut self.wam.indices.code_dir,
|
||||
&mut self.wam.indices.op_dir,
|
||||
&mut self.wam.indices.meta_predicates,
|
||||
);
|
||||
)?;
|
||||
}
|
||||
CompilationTarget::Module(ref 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 self.wam.indices.op_dir,
|
||||
&mut self.module_op_exports,
|
||||
);
|
||||
)?;
|
||||
}
|
||||
None => {
|
||||
// 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);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||
module_name,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,7 +742,7 @@ impl<'a> LoadState<'a> {
|
||||
&exports,
|
||||
&mut self.wam.indices.code_dir,
|
||||
&mut self.wam.indices.op_dir,
|
||||
);
|
||||
)?;
|
||||
}
|
||||
CompilationTarget::Module(ref 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 self.wam.indices.op_dir,
|
||||
&mut self.module_op_exports,
|
||||
);
|
||||
)?;
|
||||
}
|
||||
None => {
|
||||
// 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);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
||||
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||
module_name,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||
let (stream, listing_src) =
|
||||
match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&path_buf)?;
|
||||
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||
let (stream, listing_src) = match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&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) => {
|
||||
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
} else {
|
||||
return self.import_module(library);
|
||||
}
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
(
|
||||
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) => {
|
||||
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
} else {
|
||||
return self.import_module(library);
|
||||
}
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
};
|
||||
None => {
|
||||
return self.import_module(library);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let compilation_target = {
|
||||
let stream = &mut parsing_stream(stream)?;
|
||||
@@ -833,43 +826,39 @@ impl<'a> LoadState<'a> {
|
||||
// nothing to do.
|
||||
Ok(())
|
||||
}
|
||||
CompilationTarget::Module(module_name) => {
|
||||
self.import_module(module_name)
|
||||
}
|
||||
CompilationTarget::Module(module_name) => self.import_module(module_name),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn use_qualified_module(
|
||||
pub(crate) fn use_qualified_module(
|
||||
&mut self,
|
||||
module_src: ModuleSource,
|
||||
exports: IndexSet<ModuleExport>,
|
||||
) -> Result<(), SessionError> {
|
||||
let (stream, listing_src) =
|
||||
match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&path_buf)?;
|
||||
let (stream, listing_src) = match module_src {
|
||||
ModuleSource::File(filename) => {
|
||||
let mut path_buf = PathBuf::from(filename.as_str());
|
||||
path_buf.set_extension("pl");
|
||||
let file = File::open(&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) => {
|
||||
if self.wam.indices.modules.contains_key(&library) {
|
||||
return self.import_qualified_module(library, exports);
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return self.import_qualified_module(library, exports);
|
||||
}
|
||||
(
|
||||
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) => {
|
||||
if self.wam.indices.modules.contains_key(&library) {
|
||||
return self.import_qualified_module(library, exports);
|
||||
} else {
|
||||
(Stream::from(*code), ListingSource::User)
|
||||
}
|
||||
}
|
||||
};
|
||||
None => {
|
||||
return self.import_qualified_module(library, exports);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let compilation_target = {
|
||||
let stream = &mut parsing_stream(stream)?;
|
||||
@@ -897,12 +886,9 @@ impl<'a> LoadState<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn composite_op_dir(&self) -> CompositeOpDir {
|
||||
pub(super) fn composite_op_dir(&self) -> CompositeOpDir {
|
||||
match &self.compilation_target {
|
||||
CompilationTarget::User => {
|
||||
CompositeOpDir::new(&self.wam.indices.op_dir, None)
|
||||
}
|
||||
CompilationTarget::User => CompositeOpDir::new(&self.wam.indices.op_dir, None),
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
match self.wam.indices.modules.get(module_name) {
|
||||
Some(ref module) => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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::machine::PredicateKey;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
@@ -23,74 +25,59 @@ pub(crate) struct MachineError {
|
||||
from: ErrorProvenance,
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
trait TypeError {
|
||||
pub(crate) trait TypeError {
|
||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
||||
}
|
||||
|
||||
impl TypeError for Addr {
|
||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), addr(self)]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), addr(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for HeapCellValue {
|
||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), value(self)]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), value(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for MachineStub {
|
||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), aux(h, 0)],
|
||||
[self]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), aux(h, 0)], [self]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeError for Number {
|
||||
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"type_error",
|
||||
[atom(valid_type.as_str()), number(self)]
|
||||
);
|
||||
let stub = functor!("type_error", [atom(valid_type.as_str()), number(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
trait PermissionError {
|
||||
pub(crate) trait PermissionError {
|
||||
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
||||
}
|
||||
|
||||
@@ -104,7 +91,7 @@ impl PermissionError for Addr {
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,22 +107,18 @@ impl PermissionError for MachineStub {
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Constructed
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
trait DomainError {
|
||||
pub(super) trait DomainError {
|
||||
fn domain_error(self, error: DomainErrorType) -> MachineError;
|
||||
}
|
||||
|
||||
impl DomainError for Addr {
|
||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"domain_error",
|
||||
[atom(error.as_str()), addr(self)]
|
||||
);
|
||||
let stub = functor!("domain_error", [atom(error.as_str()), addr(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -147,10 +130,7 @@ impl DomainError for Addr {
|
||||
|
||||
impl DomainError for Number {
|
||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||
let stub = functor!(
|
||||
"domain_error",
|
||||
[atom(error.as_str()), number(self)]
|
||||
);
|
||||
let stub = functor!("domain_error", [atom(error.as_str()), number(self)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -161,8 +141,7 @@ impl DomainError for Number {
|
||||
}
|
||||
|
||||
impl MachineError {
|
||||
pub(super)
|
||||
fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||
functor!(
|
||||
"/",
|
||||
SharedOpDesc::new(400, YFX),
|
||||
@@ -171,8 +150,7 @@ impl MachineError {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn interrupt_error() -> Self {
|
||||
pub(super) fn interrupt_error() -> Self {
|
||||
let stub = functor!("$interrupt_thrown");
|
||||
|
||||
MachineError {
|
||||
@@ -182,8 +160,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn evaluation_error(eval_error: EvalError) -> Self {
|
||||
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
|
||||
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
|
||||
|
||||
MachineError {
|
||||
@@ -193,13 +170,11 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
||||
pub(super) fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
||||
culprit.type_error(h, valid_type)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn module_resolution_error(
|
||||
pub(super) fn module_resolution_error(
|
||||
h: usize,
|
||||
mod_name: ClauseName,
|
||||
name: ClauseName,
|
||||
@@ -218,11 +193,7 @@ impl MachineError {
|
||||
[res_stub]
|
||||
);
|
||||
|
||||
let stub = functor!(
|
||||
"evaluation_error",
|
||||
[aux(h, 0)],
|
||||
[ind_stub]
|
||||
);
|
||||
let stub = functor!("evaluation_error", [aux(h, 0)], [ind_stub]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -231,14 +202,10 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn existence_error(h: usize, err: ExistenceError) -> Self {
|
||||
pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
|
||||
match err {
|
||||
ExistenceError::Module(name) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("source_sink"), clause_name(name)]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("source_sink"), clause_name(name)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -253,11 +220,7 @@ impl MachineError {
|
||||
[clause_name(name), integer(arity)]
|
||||
);
|
||||
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("procedure"), aux(h, 0)],
|
||||
[culprit]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("procedure"), aux(h, 0)], [culprit]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -281,10 +244,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
ExistenceError::SourceSink(culprit) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("source_sink"), addr(culprit)]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("source_sink"), addr(culprit)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -293,10 +253,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
ExistenceError::Stream(culprit) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("stream"), addr(culprit)]
|
||||
);
|
||||
let stub = functor!("existence_error", [atom("stream"), addr(culprit)]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -307,25 +264,18 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn permission_error<T: PermissionError>(
|
||||
pub(super) fn permission_error<T: PermissionError>(
|
||||
h: usize,
|
||||
err: Permission,
|
||||
index_str: &'static str,
|
||||
culprit: T,
|
||||
) -> Self {
|
||||
culprit.permission_error(
|
||||
h,
|
||||
index_str,
|
||||
err,
|
||||
)
|
||||
culprit.permission_error(h, index_str, err)
|
||||
}
|
||||
|
||||
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
||||
match err {
|
||||
ArithmeticError::UninstantiatedVar => {
|
||||
Self::instantiation_error()
|
||||
}
|
||||
ArithmeticError::UninstantiatedVar => Self::instantiation_error(),
|
||||
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
||||
let culprit = functor!(
|
||||
"/",
|
||||
@@ -339,13 +289,11 @@ impl MachineError {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||
pub(super) fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||
culprit.domain_error(error)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn instantiation_error() -> Self {
|
||||
pub(super) fn instantiation_error() -> Self {
|
||||
let stub = functor!("instantiation_error");
|
||||
|
||||
MachineError {
|
||||
@@ -355,8 +303,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn session_error(h: usize, err: SessionError) -> Self {
|
||||
pub(super) fn session_error(h: usize, err: SessionError) -> Self {
|
||||
match err {
|
||||
// SessionError::CannotOverwriteBuiltIn(pred_str) |
|
||||
/*
|
||||
@@ -369,13 +316,10 @@ impl MachineError {
|
||||
)
|
||||
}
|
||||
*/
|
||||
SessionError::ExistenceError(err) => {
|
||||
Self::existence_error(h, err)
|
||||
}
|
||||
SessionError::ExistenceError(err) => Self::existence_error(h, err),
|
||||
// SessionError::InvalidFileName(filename) => {
|
||||
// Self::existence_error(h, ExistenceError::Module(filename))
|
||||
// }
|
||||
/*
|
||||
SessionError::ModuleDoesNotContainExport(..) => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
@@ -384,47 +328,32 @@ impl MachineError {
|
||||
functor!("module_does_not_contain_claimed_export"),
|
||||
)
|
||||
}
|
||||
*/
|
||||
SessionError::ModuleCannotImportSelf(module_name) => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
Permission::Modify,
|
||||
"module",
|
||||
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
||||
)
|
||||
}
|
||||
SessionError::NamelessEntry => {
|
||||
Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"static_procedure",
|
||||
functor!("nameless_procedure")
|
||||
)
|
||||
}
|
||||
SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
|
||||
h,
|
||||
Permission::Modify,
|
||||
"module",
|
||||
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
||||
),
|
||||
SessionError::NamelessEntry => Self::permission_error(
|
||||
h,
|
||||
Permission::Create,
|
||||
"static_procedure",
|
||||
functor!("nameless_procedure"),
|
||||
),
|
||||
SessionError::OpIsInfixAndPostFix(op) => {
|
||||
Self::permission_error(
|
||||
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")
|
||||
)
|
||||
Self::permission_error(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"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
||||
pub(super) fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
||||
let err = err.into();
|
||||
|
||||
if let CompilationError::Arithmetic(err) = err {
|
||||
@@ -434,11 +363,7 @@ impl MachineError {
|
||||
let location = err.line_and_col_num();
|
||||
let stub = err.as_functor(h);
|
||||
|
||||
let stub = functor!(
|
||||
"syntax_error",
|
||||
[aux(h, 0)],
|
||||
[stub]
|
||||
);
|
||||
let stub = functor!("syntax_error", [aux(h, 0)], [stub]);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
@@ -447,8 +372,7 @@ impl MachineError {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn representation_error(flag: RepFlag) -> Self {
|
||||
pub(super) fn representation_error(flag: RepFlag) -> Self {
|
||||
let stub = functor!("representation_error", [atom(flag.as_str())]);
|
||||
|
||||
MachineError {
|
||||
@@ -515,63 +439,46 @@ impl From<ParserError> for CompilationError {
|
||||
impl CompilationError {
|
||||
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||
match self {
|
||||
&CompilationError::ParserError(ref err) =>
|
||||
err.line_and_col_num(),
|
||||
_ =>
|
||||
None
|
||||
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_functor(&self, _h: usize) -> MachineStub {
|
||||
match self {
|
||||
&CompilationError::Arithmetic(..) =>
|
||||
functor!("arithmetic_error"),
|
||||
&CompilationError::Arithmetic(..) => functor!("arithmetic_error"),
|
||||
// &CompilationError::BadPendingByte =>
|
||||
// functor!("bad_pending_byte"),
|
||||
&CompilationError::CannotParseCyclicTerm =>
|
||||
functor!("cannot_parse_cyclic_term"),
|
||||
&CompilationError::CannotParseCyclicTerm => functor!("cannot_parse_cyclic_term"),
|
||||
// &CompilationError::ExpandedTermsListNotAList =>
|
||||
// functor!("expanded_terms_list_is_not_a_list"),
|
||||
&CompilationError::ExpectedRel =>
|
||||
functor!("expected_relation"),
|
||||
&CompilationError::ExpectedRel => functor!("expected_relation"),
|
||||
// &CompilationError::ExpectedTopLevelTerm =>
|
||||
// functor!("expected_atom_or_cons_or_clause"),
|
||||
&CompilationError::InadmissibleFact =>
|
||||
functor!("inadmissible_fact"),
|
||||
&CompilationError::InadmissibleQueryTerm =>
|
||||
functor!("inadmissible_query_term"),
|
||||
&CompilationError::InconsistentEntry =>
|
||||
functor!("inconsistent_entry"),
|
||||
&CompilationError::InadmissibleFact => functor!("inadmissible_fact"),
|
||||
&CompilationError::InadmissibleQueryTerm => functor!("inadmissible_query_term"),
|
||||
&CompilationError::InconsistentEntry => functor!("inconsistent_entry"),
|
||||
// &CompilationError::InvalidDoubleQuotesDecl =>
|
||||
// functor!("invalid_double_quotes_declaration"),
|
||||
// &CompilationError::InvalidHook =>
|
||||
// functor!("invalid_hook"),
|
||||
&CompilationError::InvalidMetaPredicateDecl =>
|
||||
functor!("invalid_meta_predicate_decl"),
|
||||
&CompilationError::InvalidModuleDecl =>
|
||||
functor!("invalid_module_declaration"),
|
||||
&CompilationError::InvalidModuleExport =>
|
||||
functor!("invalid_module_export"),
|
||||
&CompilationError::InvalidModuleResolution(ref module_name) =>
|
||||
functor!(
|
||||
"no_such_module",
|
||||
[clause_name(module_name.clone())]
|
||||
),
|
||||
&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"),
|
||||
&CompilationError::InvalidMetaPredicateDecl => functor!("invalid_meta_predicate_decl"),
|
||||
&CompilationError::InvalidModuleDecl => functor!("invalid_module_declaration"),
|
||||
&CompilationError::InvalidModuleExport => functor!("invalid_module_export"),
|
||||
&CompilationError::InvalidModuleResolution(ref module_name) => {
|
||||
functor!("no_such_module", [clause_name(module_name.clone())])
|
||||
}
|
||||
&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)]
|
||||
pub enum Permission {
|
||||
// Access,
|
||||
Access,
|
||||
Create,
|
||||
InputStream,
|
||||
Modify,
|
||||
@@ -584,7 +491,7 @@ impl Permission {
|
||||
#[inline]
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
// Permission::Access => "access",
|
||||
Permission::Access => "access",
|
||||
Permission::Create => "create",
|
||||
Permission::InputStream => "input",
|
||||
Permission::Modify => "modify",
|
||||
@@ -715,16 +622,15 @@ impl EvalError {
|
||||
pub(super) enum CycleSearchResult {
|
||||
EmptyList,
|
||||
NotList,
|
||||
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
|
||||
ProperList(usize), // the list length.
|
||||
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
|
||||
ProperList(usize), // the list length.
|
||||
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).
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
// see 8.4.3 of Draft Technical Corrigendum 2.
|
||||
pub(super)
|
||||
fn check_sort_errors(&self) -> CallResult {
|
||||
pub(super) fn check_sort_errors(&self) -> CallResult {
|
||||
let stub = MachineError::functor_stub(clause_name!("sort"), 2);
|
||||
let list = self.store(self.deref(self[temp_v!(1)].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))
|
||||
}
|
||||
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;
|
||||
}
|
||||
HeapCellValue::NamedStr(2, ref name, Some(_))
|
||||
if name.as_str() == "-" => {
|
||||
if name.as_str() == "-" =>
|
||||
{
|
||||
break;
|
||||
}
|
||||
HeapCellValue::Addr(Addr::HeapCell(_)) => {
|
||||
@@ -793,11 +702,10 @@ impl MachineState {
|
||||
}
|
||||
|
||||
// see 8.4.4 of Draft Technical Corrigendum 2.
|
||||
pub(super)
|
||||
fn check_keysort_errors(&self) -> CallResult {
|
||||
pub(super) fn check_keysort_errors(&self) -> CallResult {
|
||||
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()));
|
||||
|
||||
match self.detect_cycles(pairs.clone()) {
|
||||
@@ -814,8 +722,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn type_error<T: TypeError>(
|
||||
pub(crate) fn type_error<T: TypeError>(
|
||||
&self,
|
||||
valid_type: ValidType,
|
||||
culprit: T,
|
||||
@@ -823,33 +730,25 @@ impl MachineState {
|
||||
arity: usize,
|
||||
) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(caller, arity);
|
||||
let err = MachineError::type_error(
|
||||
self.heap.h(),
|
||||
valid_type,
|
||||
culprit,
|
||||
);
|
||||
let err = MachineError::type_error(self.heap.h(), valid_type, culprit);
|
||||
|
||||
return self.error_form(err, stub);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn representation_error(
|
||||
pub(crate) fn representation_error(
|
||||
&self,
|
||||
rep_flag: RepFlag,
|
||||
caller: ClauseName,
|
||||
arity: usize,
|
||||
) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(caller, arity);
|
||||
let err = MachineError::representation_error(
|
||||
rep_flag,
|
||||
);
|
||||
let err = MachineError::representation_error(rep_flag);
|
||||
|
||||
return self.error_form(err, stub);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||
pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||
let location = err.location;
|
||||
let err_len = err.len();
|
||||
|
||||
@@ -874,8 +773,7 @@ impl MachineState {
|
||||
stub
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn throw_exception(&mut self, err: MachineStub) {
|
||||
pub(super) fn throw_exception(&mut self, err: MachineStub) {
|
||||
let h = self.heap.h();
|
||||
|
||||
self.ball.boundary = 0;
|
||||
@@ -906,7 +804,7 @@ pub enum SessionError {
|
||||
// CannotOverwriteImport(ClauseName),
|
||||
ExistenceError(ExistenceError),
|
||||
// InvalidFileName(ClauseName),
|
||||
// ModuleDoesNotContainExport(ClauseName, PredicateKey),
|
||||
ModuleDoesNotContainExport(ClauseName, PredicateKey),
|
||||
ModuleCannotImportSelf(ClauseName),
|
||||
NamelessEntry,
|
||||
OpIsInfixAndPostFix(ClauseName),
|
||||
|
||||
@@ -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::fixtures::*;
|
||||
use crate::forms::*;
|
||||
use crate::machine::CompilationTarget;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::code_repo::CodeRepo;
|
||||
use crate::machine::Ball;
|
||||
use crate::machine::heap::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::partial_string::*;
|
||||
use crate::machine::raw_block::RawBlockTraits;
|
||||
use crate::machine::streams::Stream;
|
||||
use crate::machine::term_stream::LoadStatePayload;
|
||||
use crate::instructions::*;
|
||||
use crate::ordered_float::OrderedFloat;
|
||||
use crate::machine::Ball;
|
||||
use crate::machine::CompilationTarget;
|
||||
use crate::rug::{Integer, Rational};
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use crate::indexmap::IndexMap;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cmp::Ordering;
|
||||
@@ -96,20 +97,14 @@ impl Ord for Ref {
|
||||
fn cmp(&self, other: &Ref) -> Ordering {
|
||||
match (self, other) {
|
||||
(Ref::AttrVar(h1), Ref::AttrVar(h2))
|
||||
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
||||
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
||||
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => {
|
||||
h1.cmp(&h2)
|
||||
}
|
||||
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
||||
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
||||
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => h1.cmp(&h2),
|
||||
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
|
||||
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
|
||||
}
|
||||
(Ref::StackCell(..), _) => {
|
||||
Ordering::Greater
|
||||
}
|
||||
(_, Ref::StackCell(..)) => {
|
||||
Ordering::Less
|
||||
}
|
||||
(Ref::StackCell(..), _) => Ordering::Greater,
|
||||
(_, Ref::StackCell(..)) => Ordering::Less,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,35 +119,23 @@ impl PartialEq<Ref> for Addr {
|
||||
impl PartialOrd<Ref> for Addr {
|
||||
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
||||
match self {
|
||||
&Addr::StackCell(fr, sc) => {
|
||||
match *r {
|
||||
Ref::AttrVar(_) | Ref::HeapCell(_) => {
|
||||
&Addr::StackCell(fr, sc) => match *r {
|
||||
Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater),
|
||||
Ref::StackCell(fr1, sc1) => {
|
||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||
Some(Ordering::Greater)
|
||||
}
|
||||
Ref::StackCell(fr1, sc1) => {
|
||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||
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(..) => {
|
||||
} else if fr1 == fr && sc1 == sc {
|
||||
Some(Ordering::Equal)
|
||||
} else {
|
||||
Some(Ordering::Less)
|
||||
}
|
||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
||||
h.partial_cmp(h1)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
},
|
||||
&Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
|
||||
Ref::StackCell(..) => Some(Ordering::Less),
|
||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => h.partial_cmp(h1),
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,26 +144,21 @@ impl Addr {
|
||||
#[inline]
|
||||
pub fn is_heap_bound(&self) -> bool {
|
||||
match self {
|
||||
Addr::Char(_) | Addr::EmptyList |
|
||||
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Fixnum(_) |
|
||||
Addr::Float(_) => {
|
||||
false
|
||||
}
|
||||
_ => {
|
||||
true
|
||||
}
|
||||
Addr::Char(_)
|
||||
| Addr::EmptyList
|
||||
| Addr::CutPoint(_)
|
||||
| Addr::Usize(_)
|
||||
| Addr::Fixnum(_)
|
||||
| Addr::Float(_) => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_ref(&self) -> bool {
|
||||
match self {
|
||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
false
|
||||
}
|
||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,92 +172,54 @@ impl Addr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||
pub(super) fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||
match Number::try_from((*self, heap)) {
|
||||
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
|
||||
Some(TermOrderCategory::Integer)
|
||||
}
|
||||
Ok(Number::Float(_)) => {
|
||||
Some(TermOrderCategory::FloatingPoint)
|
||||
}
|
||||
_ => {
|
||||
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
|
||||
}
|
||||
Ok(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
|
||||
_ => 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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
|
||||
match self {
|
||||
&Addr::Char(c) => {
|
||||
Some(Constant::Char(c))
|
||||
}
|
||||
&Addr::Con(h) => {
|
||||
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
|
||||
}
|
||||
&Addr::Char(c) => Some(Constant::Char(c)),
|
||||
&Addr::Con(h) => match &machine_st.heap[h] {
|
||||
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
||||
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
||||
}
|
||||
}
|
||||
&Addr::EmptyList => {
|
||||
Some(Constant::EmptyList)
|
||||
}
|
||||
&Addr::Fixnum(n) => {
|
||||
Some(Constant::Fixnum(n))
|
||||
}
|
||||
&Addr::Float(f) => {
|
||||
Some(Constant::Float(f))
|
||||
}
|
||||
&Addr::Usize(n) => {
|
||||
Some(Constant::Usize(n))
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
&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,
|
||||
},
|
||||
&Addr::EmptyList => Some(Constant::EmptyList),
|
||||
&Addr::Fixnum(n) => Some(Constant::Fixnum(n)),
|
||||
&Addr::Float(f) => Some(Constant::Float(f)),
|
||||
&Addr::Usize(n) => Some(Constant::Usize(n)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,61 +323,37 @@ impl HeapCellValue {
|
||||
#[inline]
|
||||
pub fn as_addr(&self, focus: usize) -> Addr {
|
||||
match self {
|
||||
HeapCellValue::Addr(ref a) => {
|
||||
*a
|
||||
}
|
||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
||||
HeapCellValue::Rational(..) => {
|
||||
Addr::Con(focus)
|
||||
}
|
||||
HeapCellValue::LoadStatePayload(_) => {
|
||||
Addr::LoadStatePayload(focus)
|
||||
}
|
||||
HeapCellValue::NamedStr(_, _, _) => {
|
||||
Addr::Str(focus)
|
||||
}
|
||||
HeapCellValue::PartialString(..) => {
|
||||
Addr::PStrLocation(focus, 0)
|
||||
}
|
||||
HeapCellValue::Stream(_) => {
|
||||
Addr::Stream(focus)
|
||||
}
|
||||
HeapCellValue::TcpListener(_) => {
|
||||
Addr::TcpListener(focus)
|
||||
}
|
||||
HeapCellValue::Addr(ref a) => *a,
|
||||
HeapCellValue::Atom(..)
|
||||
| HeapCellValue::DBRef(..)
|
||||
| HeapCellValue::Integer(..)
|
||||
| HeapCellValue::Rational(..) => Addr::Con(focus),
|
||||
HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(focus),
|
||||
HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
|
||||
HeapCellValue::PartialString(..) => Addr::PStrLocation(focus, 0),
|
||||
HeapCellValue::Stream(_) => Addr::Stream(focus),
|
||||
HeapCellValue::TcpListener(_) => Addr::TcpListener(focus),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn context_free_clone(&self) -> HeapCellValue {
|
||||
match self {
|
||||
&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::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::Atom(clause_name!("$live_term_stream"), None)
|
||||
}
|
||||
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
||||
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
||||
}
|
||||
&HeapCellValue::Rational(ref r) => {
|
||||
HeapCellValue::Rational(r.clone())
|
||||
}
|
||||
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||
}
|
||||
&HeapCellValue::Stream(ref stream) => {
|
||||
HeapCellValue::Stream(stream.clone())
|
||||
}
|
||||
&HeapCellValue::Stream(ref stream) => HeapCellValue::Stream(stream.clone()),
|
||||
&HeapCellValue::TcpListener(_) => {
|
||||
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
||||
}
|
||||
@@ -473,8 +389,7 @@ impl Deref for CodeIndex {
|
||||
|
||||
impl CodeIndex {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn new(ptr: IndexPtr) -> Self {
|
||||
pub(super) fn new(ptr: IndexPtr) -> Self {
|
||||
CodeIndex(Rc::new(Cell::new(ptr)))
|
||||
}
|
||||
|
||||
@@ -482,7 +397,7 @@ impl CodeIndex {
|
||||
pub fn is_undefined(&self) -> bool {
|
||||
match self.0.get() {
|
||||
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,7 +420,6 @@ pub enum REPLCodePtr {
|
||||
AddDynamicPredicate,
|
||||
AddGoalExpansionClause,
|
||||
AddTermExpansionClause,
|
||||
BuiltInProperty,
|
||||
ClauseToEvacuable,
|
||||
ConcludeLoad,
|
||||
DeclareModule,
|
||||
@@ -520,11 +434,15 @@ pub enum REPLCodePtr {
|
||||
PushLoadContext,
|
||||
PushLoadStatePayload,
|
||||
UseModule,
|
||||
BuiltInProperty,
|
||||
MetaPredicateProperty,
|
||||
CompilePendingPredicates,
|
||||
UserAsserta,
|
||||
UserAssertz,
|
||||
UserRetract,
|
||||
MultifileProperty,
|
||||
DiscontiguousProperty,
|
||||
DynamicProperty,
|
||||
AbolishClause,
|
||||
Asserta,
|
||||
Assertz,
|
||||
Retract,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@@ -533,7 +451,7 @@ pub enum CodePtr {
|
||||
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
|
||||
Local(LocalCodePtr),
|
||||
// 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.
|
||||
}
|
||||
|
||||
@@ -541,10 +459,10 @@ impl CodePtr {
|
||||
pub fn local(&self) -> LocalCodePtr {
|
||||
match self {
|
||||
&CodePtr::BuiltInClause(_, ref local)
|
||||
| &CodePtr::CallN(_, ref local, _)
|
||||
| &CodePtr::Local(ref local) => local.clone(),
|
||||
| &CodePtr::CallN(_, ref local, _)
|
||||
| &CodePtr::Local(ref local) => local.clone(),
|
||||
&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
|
||||
Halt,
|
||||
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 {
|
||||
pub(crate)
|
||||
fn assign_if_local(&mut self, cp: CodePtr) {
|
||||
pub(crate) fn assign_if_local(&mut self, cp: CodePtr) {
|
||||
match cp {
|
||||
CodePtr::Local(local) => *self = local,
|
||||
_ => {}
|
||||
@@ -576,8 +493,7 @@ impl LocalCodePtr {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn abs_loc(&self) -> usize {
|
||||
pub(crate) fn abs_loc(&self) -> usize {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref p) => *p,
|
||||
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
||||
@@ -585,35 +501,28 @@ impl LocalCodePtr {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
||||
Some(line) => {
|
||||
match line.as_ref() {
|
||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||
return true;
|
||||
}
|
||||
Some(line) => match line.as_ref() {
|
||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
||||
pub(crate) fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
||||
let addr = Addr::HeapCell(heap.h());
|
||||
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) => {
|
||||
heap.append(functor!(
|
||||
"dir_entry",
|
||||
[integer(*p)]
|
||||
));
|
||||
heap.append(functor!("dir_entry", [integer(*p)]));
|
||||
}
|
||||
LocalCodePtr::Halt => {
|
||||
heap.append(functor!("halt"));
|
||||
@@ -655,7 +564,7 @@ impl PartialOrd<CodePtr> for CodePtr {
|
||||
impl PartialOrd<LocalCodePtr> for LocalCodePtr {
|
||||
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
||||
match (self, other) {
|
||||
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
|
||||
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
|
||||
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
|
||||
p1.partial_cmp(p2)
|
||||
}
|
||||
@@ -690,12 +599,9 @@ impl Add<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) =>
|
||||
LocalCodePtr::DirEntry(p + rhs),
|
||||
LocalCodePtr::Halt =>
|
||||
unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
||||
LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,12 +612,11 @@ impl Sub<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn sub(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(p) =>
|
||||
p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||
LocalCodePtr::Halt =>
|
||||
unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
||||
i.checked_sub(rhs).map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||
LocalCodePtr::Halt => unreachable!(),
|
||||
LocalCodePtr::IndexingBuf(p, o, i) => i
|
||||
.checked_sub(rhs)
|
||||
.map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -720,15 +625,12 @@ impl SubAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, rhs: usize) {
|
||||
match self {
|
||||
LocalCodePtr::DirEntry(ref mut p) =>
|
||||
*p -= rhs,
|
||||
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) =>
|
||||
unreachable!(),
|
||||
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
|
||||
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl AddAssign<usize> for LocalCodePtr {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, rhs: usize) {
|
||||
@@ -746,14 +648,12 @@ impl Add<usize> for CodePtr {
|
||||
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
match self {
|
||||
p @ CodePtr::REPL(..) |
|
||||
p @ CodePtr::VerifyAttrInterrupt(_) => { // |
|
||||
// p @ CodePtr::DynamicTransaction(..) => {
|
||||
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
|
||||
// |
|
||||
// p @ CodePtr::DynamicTransaction(..) => {
|
||||
p
|
||||
}
|
||||
CodePtr::Local(local) => {
|
||||
CodePtr::Local(local + rhs)
|
||||
}
|
||||
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
||||
CodePtr::Local(local + rhs)
|
||||
}
|
||||
@@ -781,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
||||
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
||||
|
||||
@@ -821,29 +720,43 @@ impl Default for IndexStore {
|
||||
}
|
||||
|
||||
impl IndexStore {
|
||||
pub fn get_predicate_skeleton(
|
||||
pub fn get_predicate_skeleton_mut(
|
||||
&mut self,
|
||||
compilation_target: &CompilationTarget,
|
||||
key: &PredicateKey,
|
||||
) -> Option<&mut PredicateSkeleton> {
|
||||
match (key.0.as_str(), key.1) {
|
||||
("term_expansion", 2) => {
|
||||
self.extensible_predicates.get_mut(key)
|
||||
}
|
||||
_ => {
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.extensible_predicates.get_mut(key)
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.get_mut(key)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
("term_expansion", 2) => self.extensible_predicates.get_mut(key),
|
||||
_ => match compilation_target {
|
||||
CompilationTarget::User => self.extensible_predicates.get_mut(key),
|
||||
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) {
|
||||
("term_expansion", 2) => {
|
||||
self.extensible_predicates.remove(key);
|
||||
},
|
||||
_ => {
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.extensible_predicates.remove(key);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.remove(key);
|
||||
}
|
||||
}
|
||||
_ => match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.extensible_predicates.remove(key);
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
if let Some(module) = self.modules.get_mut(module_name) {
|
||||
module.extensible_predicates.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -880,15 +791,9 @@ impl IndexStore {
|
||||
) -> Option<CodeIndex> {
|
||||
if module.as_str() == "user" {
|
||||
match ClauseType::from(name, arity, op_spec) {
|
||||
ClauseType::Named(name, arity, _) => {
|
||||
self.code_dir.get(&(name, arity)).cloned()
|
||||
}
|
||||
ClauseType::Op(name, spec, ..) => {
|
||||
self.code_dir.get(&(name, spec.arity())).cloned()
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||
ClauseType::Op(name, spec, ..) => self.code_dir.get(&(name, spec.arity())).cloned(),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
self.modules.get(&module).and_then(|module| {
|
||||
@@ -899,9 +804,7 @@ impl IndexStore {
|
||||
ClauseType::Op(name, spec, ..) => {
|
||||
module.code_dir.get(&(name, spec.arity())).cloned()
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -914,44 +817,32 @@ impl IndexStore {
|
||||
compilation_target: &CompilationTarget,
|
||||
) -> Option<&Vec<MetaSpec>> {
|
||||
match compilation_target {
|
||||
CompilationTarget::User => {
|
||||
self.meta_predicates.get(&(name, arity))
|
||||
}
|
||||
CompilationTarget::Module(ref module_name) => {
|
||||
match self.modules.get(module_name) {
|
||||
Some(ref module) => {
|
||||
module.meta_predicates.get(&(name.clone(), arity))
|
||||
.or_else(|| {
|
||||
self.meta_predicates.get(&(name, arity))
|
||||
})
|
||||
}
|
||||
None => {
|
||||
self.meta_predicates.get(&(name, arity))
|
||||
}
|
||||
}
|
||||
}
|
||||
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
|
||||
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
|
||||
Some(ref module) => module
|
||||
.meta_predicates
|
||||
.get(&(name.clone(), 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 {
|
||||
match module_name.as_str() {
|
||||
"user" => {
|
||||
self.extensible_predicates.get(&key)
|
||||
"user" => self
|
||||
.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)
|
||||
.unwrap_or(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
|
||||
}
|
||||
}
|
||||
}
|
||||
.unwrap_or(false),
|
||||
None => false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -960,8 +851,7 @@ impl IndexStore {
|
||||
IndexStore::default()
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn get_cleaner_sites(&self) -> (usize, usize) {
|
||||
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
|
||||
let r_w_h = clause_name!("run_cleaners_with_handling");
|
||||
let r_wo_h = clause_name!("run_cleaners_without_handling");
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&RefOrOwned::Borrowed(ref borrowed) =>
|
||||
write!(f, "Borrowed({:?})", borrowed),
|
||||
&RefOrOwned::Owned(ref owned) =>
|
||||
write!(f, "Owned({:?})", owned),
|
||||
&RefOrOwned::Borrowed(ref borrowed) => write!(f, "Borrowed({:?})", borrowed),
|
||||
&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 {
|
||||
RefOrOwned::Borrowed(item) => item.clone(),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use prolog_parser::{clause_name, temp_v};
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
@@ -14,9 +15,11 @@ use crate::machine::stack::*;
|
||||
use crate::machine::streams::*;
|
||||
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::convert::TryFrom;
|
||||
@@ -32,33 +35,26 @@ pub struct Ball {
|
||||
}
|
||||
|
||||
impl Ball {
|
||||
pub(super)
|
||||
fn new() -> Self {
|
||||
pub(super) fn new() -> Self {
|
||||
Ball {
|
||||
boundary: 0,
|
||||
stub: Heap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn reset(&mut self) {
|
||||
pub(super) fn reset(&mut self) {
|
||||
self.boundary = 0;
|
||||
self.stub.clear();
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn copy_and_align(&self, h: usize) -> Heap {
|
||||
pub(super) fn copy_and_align(&self, h: usize) -> Heap {
|
||||
let diff = self.boundary as i64 - h as i64;
|
||||
let mut stub = Heap::new();
|
||||
|
||||
for heap_value in self.stub.iter_from(0) {
|
||||
stub.push(match heap_value {
|
||||
&HeapCellValue::Addr(addr) => {
|
||||
HeapCellValue::Addr(addr - diff)
|
||||
}
|
||||
heap_value => {
|
||||
heap_value.context_free_clone()
|
||||
}
|
||||
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
|
||||
heap_value => heap_value.context_free_clone(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -123,11 +119,7 @@ pub(super) struct CopyBallTerm<'a> {
|
||||
}
|
||||
|
||||
impl<'a> CopyBallTerm<'a> {
|
||||
pub(super) fn new(
|
||||
stack: &'a mut Stack,
|
||||
heap: &'a mut Heap,
|
||||
stub: &'a mut Heap,
|
||||
) -> Self {
|
||||
pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
|
||||
let hb = heap.h();
|
||||
|
||||
CopyBallTerm {
|
||||
@@ -182,12 +174,8 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
||||
let index = h - self.heap_boundary;
|
||||
self.stub[index].as_addr(h)
|
||||
}
|
||||
Addr::StackCell(fr, sc) => {
|
||||
self.stack.index_and_frame(fr)[sc]
|
||||
}
|
||||
addr => {
|
||||
addr
|
||||
}
|
||||
Addr::StackCell(fr, sc) => self.stack.index_and_frame(fr)[sc],
|
||||
addr => addr,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,9 +214,7 @@ impl Index<RegType> for MachineState {
|
||||
impl IndexMut<RegType> for MachineState {
|
||||
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
|
||||
match reg {
|
||||
RegType::Temp(temp) => {
|
||||
&mut self.registers[temp]
|
||||
}
|
||||
RegType::Temp(temp) => &mut self.registers[temp],
|
||||
RegType::Perm(perm) => {
|
||||
let e = self.e;
|
||||
|
||||
@@ -255,15 +241,12 @@ pub(super) enum HeapPtr {
|
||||
|
||||
impl HeapPtr {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn read(&self, heap: &Heap) -> Addr {
|
||||
pub(super) fn read(&self, heap: &Heap) -> Addr {
|
||||
match self {
|
||||
&HeapPtr::HeapCell(h) => {
|
||||
Addr::HeapCell(h)
|
||||
}
|
||||
&HeapPtr::HeapCell(h) => Addr::HeapCell(h),
|
||||
&HeapPtr::PStrChar(h, n) => {
|
||||
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)
|
||||
} else if has_tail {
|
||||
Addr::HeapCell(h + 1)
|
||||
@@ -274,9 +257,7 @@ impl HeapPtr {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
&HeapPtr::PStrLocation(h, n) => {
|
||||
Addr::PStrLocation(h, n)
|
||||
}
|
||||
&HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,16 +294,11 @@ pub struct MachineState {
|
||||
pub(super) last_call: bool,
|
||||
pub(crate) heap_locs: HeapVarDict,
|
||||
pub(crate) flags: MachineFlags,
|
||||
pub(crate) at_end_of_expansion: bool
|
||||
pub(crate) at_end_of_expansion: bool,
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate)
|
||||
fn read_term(
|
||||
&mut self,
|
||||
mut stream: Stream,
|
||||
indices: &mut IndexStore,
|
||||
) -> CallResult {
|
||||
pub(crate) fn read_term(&mut self, mut stream: Stream, indices: &mut IndexStore) -> CallResult {
|
||||
self.check_stream_properties(
|
||||
&mut stream,
|
||||
StreamType::Text,
|
||||
@@ -342,11 +318,7 @@ impl MachineState {
|
||||
let mut orig_stream = stream.clone();
|
||||
|
||||
loop {
|
||||
match self.read(
|
||||
stream.clone(),
|
||||
self.atom_tbl.clone(),
|
||||
&indices.op_dir,
|
||||
) {
|
||||
match self.read(stream.clone(), self.atom_tbl.clone(), &indices.op_dir) {
|
||||
Ok(term_write_result) => {
|
||||
let term = self[temp_v!(2)];
|
||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
||||
@@ -363,7 +335,8 @@ impl MachineState {
|
||||
let h = self.heap.h();
|
||||
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::Addr(binding));
|
||||
|
||||
@@ -406,8 +379,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
let vars_addr = self[temp_v!(4)];
|
||||
let vars_offset =
|
||||
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||
let vars_offset = Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||
|
||||
self.unify(vars_offset, vars_addr);
|
||||
|
||||
@@ -427,7 +399,7 @@ impl MachineState {
|
||||
self[temp_v!(2)],
|
||||
&mut orig_stream,
|
||||
clause_name!("read_term"),
|
||||
3
|
||||
3,
|
||||
)?;
|
||||
|
||||
if orig_stream.options.eof_action == EOFAction::Reset {
|
||||
@@ -448,12 +420,10 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn write_term<'a>(
|
||||
pub(crate) fn write_term<'a>(
|
||||
&'a self,
|
||||
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 numbervars = self.store(self.deref(self[temp_v!(4)]));
|
||||
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());
|
||||
|
||||
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";
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -470,7 +440,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
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";
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -478,7 +448,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
if let &Addr::Con(h) = "ed {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||
printer.quoted = name.as_str() == "true";
|
||||
} else {
|
||||
unreachable!()
|
||||
@@ -514,9 +484,7 @@ impl MachineState {
|
||||
for addr in addrs {
|
||||
match addr {
|
||||
Addr::Str(s) => match &self.heap[s] {
|
||||
&HeapCellValue::NamedStr(2, ref name, _)
|
||||
if name.as_str() == "=" =>
|
||||
{
|
||||
&HeapCellValue::NamedStr(2, ref name, _) if name.as_str() == "=" => {
|
||||
let atom = self.heap[s + 1].as_addr(s + 1);
|
||||
let var = self.heap[s + 2].as_addr(s + 2);
|
||||
|
||||
@@ -540,11 +508,9 @@ impl MachineState {
|
||||
|
||||
var_names.insert(var, atom);
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,8 +524,7 @@ impl MachineState {
|
||||
Ok(Some(printer))
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
||||
pub(super) fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||
let h = self.heap.h();
|
||||
let key = ExistenceError::Procedure(name, arity);
|
||||
@@ -568,13 +533,11 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||
pub(crate) fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||
HeapPStrIter::new(self, focus)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||
pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||
let mut chars = String::new();
|
||||
let mut iter = addrs.iter();
|
||||
|
||||
@@ -594,55 +557,46 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let h = self.heap.h();
|
||||
|
||||
return Err(
|
||||
MachineError::type_error(h, ValidType::Character, addr)
|
||||
);
|
||||
return Err(MachineError::type_error(h, ValidType::Character, addr));
|
||||
}
|
||||
|
||||
Ok(chars)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
||||
pub(super) fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
||||
let predicate_name = atom_from!(self, self.store(self.deref(name)));
|
||||
let arity = self.store(self.deref(arity));
|
||||
|
||||
let arity =
|
||||
match Number::try_from((arity, &self.heap)) {
|
||||
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY =>
|
||||
n.to_usize().unwrap(),
|
||||
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize =>
|
||||
usize::try_from(n).unwrap(),
|
||||
_ =>
|
||||
unreachable!()
|
||||
};
|
||||
let arity = match Number::try_from((arity, &self.heap)) {
|
||||
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => n.to_usize().unwrap(),
|
||||
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => {
|
||||
usize::try_from(n).unwrap()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
(predicate_name, arity)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
self.cp.assign_if_local(self.p.clone() + 1);
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||
self.num_of_args = arity;
|
||||
self.b0 = self.b;
|
||||
self.p = CodePtr::Local(p);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn module_lookup(
|
||||
pub(super) fn module_lookup(
|
||||
&mut self,
|
||||
indices: &IndexStore,
|
||||
call_policy: &mut Box<dyn CallPolicy>,
|
||||
@@ -687,10 +641,15 @@ pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
||||
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||
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 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
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.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 =
|
||||
machine_st.stack.index_or_frame(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;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(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.p += 1;
|
||||
@@ -726,10 +692,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
|
||||
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||
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 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
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.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 =
|
||||
machine_st.stack.index_or_frame(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;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(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.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 {
|
||||
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 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
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.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 =
|
||||
machine_st.stack.index_or_frame(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;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(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.b = machine_st.stack.index_or_frame(b).prelude.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 {
|
||||
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 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
||||
for i in 1..n + 1 {
|
||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||
}
|
||||
|
||||
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.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 =
|
||||
machine_st.stack.index_or_frame(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;
|
||||
let attr_var_init_queue_b = machine_st
|
||||
.stack
|
||||
.index_or_frame(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.b = machine_st.stack.index_or_frame(b).prelude.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) => {
|
||||
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
|
||||
match atom.as_str() {
|
||||
">" | "<" | "=" => {
|
||||
}
|
||||
">" | "<" | "=" => {}
|
||||
_ => {
|
||||
let stub =
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -948,8 +953,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
let err = MachineError::type_error(h, ValidType::Atom, a1);
|
||||
return Err(machine_st.error_form(err, stub));
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
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 eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
|
||||
|
||||
let atom = machine_st.heap.to_unifiable(
|
||||
HeapCellValue::Atom(eof, None)
|
||||
);
|
||||
let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
|
||||
|
||||
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)?;
|
||||
|
||||
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);
|
||||
@@ -1081,7 +1085,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1155,11 +1161,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||
|
||||
return Err(machine_st.error_form(
|
||||
MachineError::type_error(
|
||||
machine_st.heap.h(),
|
||||
ValidType::Callable,
|
||||
name
|
||||
),
|
||||
MachineError::type_error(machine_st.heap.h(), ValidType::Callable, name),
|
||||
stub,
|
||||
));
|
||||
}
|
||||
@@ -1200,7 +1202,8 @@ impl CallPolicy for CWILCallPolicy {
|
||||
arity: usize,
|
||||
idx: &CodeIndex,
|
||||
) -> 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)
|
||||
}
|
||||
|
||||
@@ -1239,7 +1242,7 @@ impl CallPolicy for CWILCallPolicy {
|
||||
code_dir,
|
||||
op_dir,
|
||||
current_input_stream,
|
||||
current_output_stream
|
||||
current_output_stream,
|
||||
)?;
|
||||
|
||||
self.increment(machine_st)
|
||||
@@ -1283,8 +1286,7 @@ pub(crate) struct CWILCallPolicy {
|
||||
}
|
||||
|
||||
impl CWILCallPolicy {
|
||||
pub(crate)
|
||||
fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
||||
pub(crate) fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
||||
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||
mem::swap(&mut prev_policy, policy);
|
||||
|
||||
@@ -1319,8 +1321,7 @@ impl CWILCallPolicy {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||
pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||
limit += &self.count;
|
||||
|
||||
match self.limits.last().cloned() {
|
||||
@@ -1331,8 +1332,7 @@ impl CWILCallPolicy {
|
||||
&self.count
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||
pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||
if let Some((_, bp)) = self.limits.last().cloned() {
|
||||
if bp == b {
|
||||
self.limits.pop();
|
||||
@@ -1342,13 +1342,11 @@ impl CWILCallPolicy {
|
||||
&self.count
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn is_empty(&self) -> bool {
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.limits.is_empty()
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
||||
pub(crate) fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
||||
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||
mem::swap(&mut self.prev_policy, &mut new_inner);
|
||||
new_inner
|
||||
@@ -1369,7 +1367,6 @@ fn cut_body(machine_st: &mut MachineState, addr: &Addr) -> bool {
|
||||
&Addr::CutPoint(b0) | &Addr::Usize(b0) => {
|
||||
if b > b0 {
|
||||
machine_st.b = b0;
|
||||
machine_st.tidy_trail();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@@ -1457,7 +1454,6 @@ impl CutPolicy for SCCCutPolicy {
|
||||
Addr::Usize(b0) | Addr::CutPoint(b0) => {
|
||||
if b > b0 {
|
||||
machine_st.b = b0;
|
||||
machine_st.tidy_trail();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use prolog_parser::{clause_name, temp_v};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
@@ -34,17 +37,18 @@ mod machine_state_impl;
|
||||
mod system_calls;
|
||||
|
||||
//use crate::machine::attributed_variables::*;
|
||||
use crate::machine::compile::*;
|
||||
use crate::machine::code_repo::*;
|
||||
use crate::machine::compile::*;
|
||||
// use crate::machine::loader::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::machine::machine_state::*;
|
||||
use crate::machine::streams::*;
|
||||
|
||||
use crate::indexmap::IndexMap;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
//use std::convert::TryFrom;
|
||||
use prolog_parser::ast::ClauseName;
|
||||
use std::fs::File;
|
||||
use std::mem;
|
||||
use std::path::PathBuf;
|
||||
@@ -119,39 +123,6 @@ include!(concat!(env!("OUT_DIR"), "/libraries.rs"));
|
||||
|
||||
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) {
|
||||
let mut path = match dirs_next::home_dir() {
|
||||
Some(path) => path,
|
||||
@@ -177,13 +148,7 @@ impl Machine {
|
||||
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) {
|
||||
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) {
|
||||
self.machine_st[temp_v!(1)] = Addr::Stream(
|
||||
self.machine_st.heap.push(HeapCellValue::Stream(
|
||||
stream,
|
||||
))
|
||||
);
|
||||
self.machine_st[temp_v!(1)] =
|
||||
Addr::Stream(self.machine_st.heap.push(HeapCellValue::Stream(stream)));
|
||||
|
||||
self.machine_st[temp_v!(2)] = Addr::Con(
|
||||
self.machine_st.heap.push(HeapCellValue::Atom(
|
||||
clause_name!(path, self.machine_st.atom_tbl),
|
||||
None,
|
||||
))
|
||||
);
|
||||
self.machine_st[temp_v!(2)] = Addr::Con(self.machine_st.heap.push(HeapCellValue::Atom(
|
||||
clause_name!(path, self.machine_st.atom_tbl),
|
||||
None,
|
||||
)));
|
||||
|
||||
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
|
||||
}
|
||||
@@ -245,11 +205,9 @@ impl Machine {
|
||||
bootstrapping_compile(
|
||||
Stream::from(include_str!("attributed_variables.pl")),
|
||||
self,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("attributed_variables"),
|
||||
path_buf,
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("attributed_variables"), path_buf),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut path_buf = current_dir();
|
||||
path_buf.push("machine/project_attributes.pl");
|
||||
@@ -257,11 +215,9 @@ impl Machine {
|
||||
bootstrapping_compile(
|
||||
Stream::from(include_str!("project_attributes.pl")),
|
||||
self,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("project_attributes"),
|
||||
path_buf,
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("project_attributes"), path_buf),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
|
||||
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;
|
||||
|
||||
// WAS:
|
||||
// self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("$repl"), 1));
|
||||
|
||||
self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("repl"), 0));
|
||||
self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("$repl"), 1));
|
||||
}
|
||||
|
||||
pub fn new(user_input: Stream, user_output: Stream) -> Self
|
||||
{
|
||||
use crate::ref_thread_local::RefThreadLocal;
|
||||
fn configure_modules(&mut self) {
|
||||
fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
|
||||
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 {
|
||||
machine_st: MachineState::new(),
|
||||
@@ -322,16 +329,15 @@ impl Machine {
|
||||
clause_name!("ops_and_meta_predicates.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
).unwrap();
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
bootstrapping_compile(
|
||||
Stream::from(LIBRARIES.borrow()["builtins"]),
|
||||
&mut wam,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("builtins.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("builtins.pl"), lib_path.clone()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
|
||||
load_module(
|
||||
@@ -350,38 +356,20 @@ impl Machine {
|
||||
bootstrapping_compile(
|
||||
Stream::from(include_str!("../loader.pl")),
|
||||
&mut wam,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("loader.pl"),
|
||||
lib_path.clone(),
|
||||
),
|
||||
).unwrap();
|
||||
ListingSource::from_file_and_path(clause_name!("loader.pl"), lib_path.clone()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if let Some(loader) = wam.indices.modules.swap_remove(&clause_name!("loader")) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
wam.configure_modules();
|
||||
|
||||
if let Some(loader) = wam.indices.modules.get(&clause_name!("loader")) {
|
||||
load_module(
|
||||
&mut wam.indices.code_dir,
|
||||
&mut wam.indices.op_dir,
|
||||
&mut wam.indices.meta_predicates,
|
||||
&CompilationTarget::User,
|
||||
&loader,
|
||||
loader,
|
||||
);
|
||||
|
||||
wam.indices.modules.insert(clause_name!("loader"), loader);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
@@ -396,25 +384,19 @@ impl Machine {
|
||||
pub fn configure_streams(&mut self) {
|
||||
self.user_input.options.alias = Some(clause_name!("user_input"));
|
||||
|
||||
self.indices.stream_aliases.insert(
|
||||
clause_name!("user_input"),
|
||||
self.user_input.clone(),
|
||||
);
|
||||
self.indices
|
||||
.stream_aliases
|
||||
.insert(clause_name!("user_input"), self.user_input.clone());
|
||||
|
||||
self.indices.streams.insert(
|
||||
self.user_input.clone()
|
||||
);
|
||||
self.indices.streams.insert(self.user_input.clone());
|
||||
|
||||
self.user_output.options.alias = Some(clause_name!("user_output"));
|
||||
|
||||
self.indices.stream_aliases.insert(
|
||||
clause_name!("user_output"),
|
||||
self.user_output.clone(),
|
||||
);
|
||||
self.indices
|
||||
.stream_aliases
|
||||
.insert(clause_name!("user_output"), self.user_output.clone());
|
||||
|
||||
self.indices.streams.insert(
|
||||
self.user_output.clone()
|
||||
);
|
||||
self.indices.streams.insert(self.user_output.clone());
|
||||
}
|
||||
|
||||
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
|
||||
@@ -487,25 +469,33 @@ impl Machine {
|
||||
REPLCodePtr::BuiltInProperty => {
|
||||
self.builtin_property();
|
||||
}
|
||||
REPLCodePtr::CompilePendingPredicates => {
|
||||
self.compile_pending_predicates();
|
||||
REPLCodePtr::MultifileProperty => {
|
||||
self.multifile_property();
|
||||
}
|
||||
REPLCodePtr::UserAssertz => {
|
||||
self.compile_user_assert(AppendOrPrepend::Append);
|
||||
REPLCodePtr::DiscontiguousProperty => {
|
||||
self.discontiguous_property();
|
||||
}
|
||||
REPLCodePtr::UserAsserta => {
|
||||
self.compile_user_assert(AppendOrPrepend::Prepend);
|
||||
REPLCodePtr::DynamicProperty => {
|
||||
self.dynamic_property();
|
||||
}
|
||||
REPLCodePtr::UserRetract => {
|
||||
self.retract_user_clause();
|
||||
REPLCodePtr::Assertz => {
|
||||
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);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn run_query(&mut self) {
|
||||
pub(super) fn run_query(&mut self) {
|
||||
while !self.machine_st.p.is_halt() {
|
||||
self.machine_st.query_stepper(
|
||||
&mut self.indices,
|
||||
@@ -523,23 +513,6 @@ impl Machine {
|
||||
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;
|
||||
}
|
||||
@@ -559,26 +532,22 @@ impl MachineState {
|
||||
user_output: &mut Stream,
|
||||
) {
|
||||
match instr {
|
||||
&Line::Arithmetic(ref arith_instr) => {
|
||||
self.execute_arith_instr(arith_instr)
|
||||
}
|
||||
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||
&Line::Choice(ref choice_instr) => {
|
||||
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
|
||||
}
|
||||
&Line::Cut(ref cut_instr) => {
|
||||
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
||||
}
|
||||
&Line::Control(ref control_instr) => {
|
||||
self.execute_ctrl_instr(
|
||||
indices,
|
||||
code_repo,
|
||||
&mut policies.call_policy,
|
||||
&mut policies.cut_policy,
|
||||
user_input,
|
||||
user_output,
|
||||
control_instr,
|
||||
)
|
||||
}
|
||||
&Line::Control(ref control_instr) => self.execute_ctrl_instr(
|
||||
indices,
|
||||
code_repo,
|
||||
&mut policies.call_policy,
|
||||
&mut policies.cut_policy,
|
||||
user_input,
|
||||
user_output,
|
||||
control_instr,
|
||||
),
|
||||
&Line::Fact(ref fact_instr) => {
|
||||
self.execute_fact_instr(&fact_instr);
|
||||
self.p += 1;
|
||||
@@ -620,44 +589,23 @@ impl MachineState {
|
||||
}
|
||||
|
||||
fn backtrack(&mut self) {
|
||||
// if self.b > 0 {
|
||||
let b = self.b;
|
||||
|
||||
self.b0 = self.stack.index_or_frame(b).prelude.b0;
|
||||
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;
|
||||
// }
|
||||
/*} else {
|
||||
self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
|
||||
}*/
|
||||
}
|
||||
|
||||
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
|
||||
match self.p {
|
||||
CodePtr::Local(LocalCodePtr::DirEntry(p)) |
|
||||
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
||||
if p < code_repo.code.len() => {
|
||||
}
|
||||
CodePtr::Local(LocalCodePtr::DirEntry(p))
|
||||
| CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
||||
if p < code_repo.code.len() => {}
|
||||
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
|
||||
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
|
||||
@@ -721,13 +669,7 @@ impl MachineState {
|
||||
user_output: &mut Stream,
|
||||
) {
|
||||
loop {
|
||||
self.execute_instr(
|
||||
indices,
|
||||
policies,
|
||||
code_repo,
|
||||
user_input,
|
||||
user_output,
|
||||
);
|
||||
self.execute_instr(indices, policies, code_repo, user_input, user_output);
|
||||
|
||||
if self.fail {
|
||||
self.backtrack();
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::tabled_rc::*;
|
||||
use prolog_parser::{atom, clause_name, rc_atom};
|
||||
|
||||
use crate::forms::*;
|
||||
use crate::iterators::*;
|
||||
use crate::machine::*;
|
||||
use crate::machine::load_state::*;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::*;
|
||||
|
||||
use crate::indexmap::IndexSet;
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
@@ -85,28 +86,25 @@ fn setup_op_decl(
|
||||
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 {
|
||||
Term::Clause(_, ref slash, ref mut terms, Some(_))
|
||||
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
|
||||
{
|
||||
let arity = *terms.pop().unwrap();
|
||||
let name = *terms.pop().unwrap();
|
||||
let name = *terms.pop().unwrap();
|
||||
|
||||
let arity = arity
|
||||
.to_constant()
|
||||
.and_then(|c| {
|
||||
match c {
|
||||
Constant::Integer(n) => n.to_usize(),
|
||||
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
||||
_ => None
|
||||
}
|
||||
.into_constant()
|
||||
.and_then(|c| match c {
|
||||
Constant::Integer(n) => n.to_usize(),
|
||||
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
||||
_ => None,
|
||||
})
|
||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||
|
||||
let name = name
|
||||
.to_constant()
|
||||
let name = name
|
||||
.into_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||
|
||||
@@ -116,9 +114,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
|
||||
Ok((name, arity + 2))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidModuleExport)
|
||||
}
|
||||
_ => Err(CompilationError::InvalidModuleExport),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,10 +151,7 @@ fn setup_module_export(
|
||||
.or_else(|_| {
|
||||
if let Term::Clause(_, name, terms, _) = term {
|
||||
if terms.len() == 3 && name.as_str() == "op" {
|
||||
Ok(ModuleExport::OpDecl(setup_op_decl(
|
||||
terms,
|
||||
atom_tbl
|
||||
)?))
|
||||
Ok(ModuleExport::OpDecl(setup_op_decl(terms, atom_tbl)?))
|
||||
} else {
|
||||
Err(CompilationError::InvalidModuleDecl)
|
||||
}
|
||||
@@ -168,8 +161,7 @@ fn setup_module_export(
|
||||
})
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn setup_module_export_list(
|
||||
pub(super) fn setup_module_export_list(
|
||||
mut export_list: Term,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
) -> Result<Vec<ModuleExport>, CompilationError> {
|
||||
@@ -182,7 +174,7 @@ fn setup_module_export_list(
|
||||
export_list = *t2;
|
||||
}
|
||||
|
||||
if export_list.to_constant() != Some(Constant::EmptyList) {
|
||||
if export_list.into_constant() != Some(Constant::EmptyList) {
|
||||
Err(CompilationError::InvalidModuleDecl)
|
||||
} else {
|
||||
Ok(exports)
|
||||
@@ -197,7 +189,7 @@ fn setup_module_decl(
|
||||
let name = terms
|
||||
.pop()
|
||||
.unwrap()
|
||||
.to_constant()
|
||||
.into_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
.ok_or(CompilationError::InvalidModuleDecl)?;
|
||||
|
||||
@@ -213,13 +205,12 @@ fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, Comp
|
||||
terms
|
||||
.pop()
|
||||
.unwrap()
|
||||
.to_constant()
|
||||
.into_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) =>
|
||||
Ok(ModuleSource::File(name.clone())),
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||
}
|
||||
}
|
||||
@@ -266,17 +257,13 @@ fn setup_qualified_import(
|
||||
terms
|
||||
.pop()
|
||||
.unwrap()
|
||||
.to_constant()
|
||||
.into_constant()
|
||||
.and_then(|c| c.to_atom())
|
||||
.map(|c| ModuleSource::Library(c))
|
||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
||||
Ok(ModuleSource::File(name.clone()))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidUseModuleDecl)
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||
}?;
|
||||
|
||||
let mut exports = IndexSet::new();
|
||||
@@ -286,7 +273,7 @@ fn setup_qualified_import(
|
||||
export_list = *t2;
|
||||
}
|
||||
|
||||
if export_list.to_constant() != Some(Constant::EmptyList) {
|
||||
if export_list.into_constant() != Some(Constant::EmptyList) {
|
||||
Err(CompilationError::InvalidModuleDecl)
|
||||
} else {
|
||||
Ok((module_src, exports))
|
||||
@@ -334,8 +321,7 @@ fn setup_qualified_import(
|
||||
fn setup_meta_predicate<'a>(
|
||||
mut terms: Vec<Box<Term>>,
|
||||
load_state: &LoadState<'a>,
|
||||
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError>
|
||||
{
|
||||
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> {
|
||||
fn get_name_and_meta_specs(
|
||||
name: ClauseName,
|
||||
terms: &mut [Box<Term>],
|
||||
@@ -345,26 +331,23 @@ fn setup_meta_predicate<'a>(
|
||||
for meta_spec in terms.into_iter() {
|
||||
match &**meta_spec {
|
||||
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
|
||||
let meta_spec =
|
||||
match meta_spec.as_str() {
|
||||
"+" => MetaSpec::Plus,
|
||||
"-" => MetaSpec::Minus,
|
||||
"?" => MetaSpec::Either,
|
||||
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
};
|
||||
let meta_spec = match meta_spec.as_str() {
|
||||
"+" => MetaSpec::Plus,
|
||||
"-" => MetaSpec::Minus,
|
||||
"?" => MetaSpec::Either,
|
||||
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
};
|
||||
|
||||
meta_specs.push(meta_spec);
|
||||
}
|
||||
Term::Constant(_, Constant::Fixnum(n)) => {
|
||||
match usize::try_from(*n) {
|
||||
Ok(n) if n <= MAX_ARITY => {
|
||||
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||
}
|
||||
Term::Constant(_, Constant::Fixnum(n)) => match usize::try_from(*n) {
|
||||
Ok(n) if n <= MAX_ARITY => {
|
||||
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||
}
|
||||
@@ -375,42 +358,35 @@ fn setup_meta_predicate<'a>(
|
||||
}
|
||||
|
||||
match *terms.pop().unwrap() {
|
||||
Term::Clause(_, name, mut terms, _)
|
||||
if name.as_str() == ":" && terms.len() == 2 => {
|
||||
let spec = *terms.pop().unwrap();
|
||||
let module_name = *terms.pop().unwrap();
|
||||
Term::Clause(_, name, mut terms, _) if name.as_str() == ":" && terms.len() == 2 => {
|
||||
let spec = *terms.pop().unwrap();
|
||||
let module_name = *terms.pop().unwrap();
|
||||
|
||||
match module_name {
|
||||
Term::Constant(_, Constant::Atom(module_name, _)) => {
|
||||
match spec {
|
||||
Term::Clause(_, name, mut terms, _) => {
|
||||
let (name, meta_specs) =
|
||||
get_name_and_meta_specs(name, &mut terms)?;
|
||||
match module_name {
|
||||
Term::Constant(_, Constant::Atom(module_name, _)) => match spec {
|
||||
Term::Clause(_, name, mut terms, _) => {
|
||||
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||
|
||||
Ok((module_name, name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
||||
}
|
||||
}
|
||||
Ok((module_name, name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
||||
}
|
||||
}
|
||||
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
},
|
||||
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||
}
|
||||
}
|
||||
Term::Clause(_, name, mut terms, _) => {
|
||||
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||
Ok((load_state.module_name(), name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
||||
Ok((
|
||||
load_state.compilation_target.module_name(),
|
||||
name,
|
||||
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![];
|
||||
|
||||
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);
|
||||
clauses.push(clause);
|
||||
}
|
||||
TopLevel::Predicate(predicate) => {
|
||||
clauses.extend(predicate.into_iter())
|
||||
}
|
||||
TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()),
|
||||
_ => {
|
||||
tls.push_front(tl);
|
||||
break;
|
||||
@@ -506,8 +480,8 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
|
||||
|
||||
conq_terms.push_front(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("blocked_!"), None))
|
||||
);
|
||||
Constant::Atom(clause_name!("blocked_!"), None),
|
||||
));
|
||||
|
||||
while let Some(term) = pre_cut_terms.pop_back() {
|
||||
conq_terms.push_front(term);
|
||||
@@ -531,38 +505,29 @@ fn setup_declaration<'a>(
|
||||
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
|
||||
|
||||
match term {
|
||||
Term::Clause(_, name, mut terms, _) =>
|
||||
match (name.as_str(), terms.len()) {
|
||||
("dynamic", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::Dynamic(name, arity))
|
||||
}
|
||||
("module", 2) =>
|
||||
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
||||
("op", 3) =>
|
||||
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
||||
("non_counted_backtracking", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||
}
|
||||
("use_module", 1) => {
|
||||
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
|
||||
}
|
||||
("use_module", 2) => {
|
||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||
}
|
||||
("meta_predicate", 1) => {
|
||||
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
||||
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InconsistentEntry)
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
Err(CompilationError::InconsistentEntry)
|
||||
}
|
||||
Term::Clause(_, name, mut terms, _) => match (name.as_str(), terms.len()) {
|
||||
("dynamic", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::Dynamic(name, arity))
|
||||
}
|
||||
("module", 2) => Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
||||
("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
||||
("non_counted_backtracking", 1) => {
|
||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||
}
|
||||
("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||
("use_module", 2) => {
|
||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||
}
|
||||
("meta_predicate", 1) => {
|
||||
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
||||
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
||||
}
|
||||
_ => Err(CompilationError::InconsistentEntry),
|
||||
},
|
||||
_ => Err(CompilationError::InconsistentEntry),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,8 +561,7 @@ pub(crate) struct Preprocessor {
|
||||
}
|
||||
|
||||
impl Preprocessor {
|
||||
pub(super)
|
||||
fn new(flags: MachineFlags) -> Self {
|
||||
pub(super) fn new(flags: MachineFlags) -> Self {
|
||||
Preprocessor {
|
||||
flags,
|
||||
queue: VecDeque::new(),
|
||||
@@ -606,12 +570,8 @@ impl Preprocessor {
|
||||
|
||||
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
|
||||
match term {
|
||||
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => {
|
||||
Ok(term)
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InadmissibleFact)
|
||||
}
|
||||
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(term),
|
||||
_ => Err(CompilationError::InadmissibleFact),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,109 +672,97 @@ impl Preprocessor {
|
||||
Ok(clause_to_query_term(load_state, name, vec![], fixity))
|
||||
}
|
||||
}
|
||||
Term::Constant(_, Constant::Char('!')) => {
|
||||
Ok(QueryTerm::BlockedCut)
|
||||
}
|
||||
Term::Constant(_, Constant::Char('!')) => Ok(QueryTerm::BlockedCut),
|
||||
Term::Var(_, ref v) if v.as_str() == "!" => {
|
||||
Ok(QueryTerm::UnblockedCut(Cell::default()))
|
||||
}
|
||||
Term::Clause(r, name, mut terms, fixity) => {
|
||||
match (name.as_str(), terms.len()) {
|
||||
(";", 2) => {
|
||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||
Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) {
|
||||
(";", 2) => {
|
||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
self.queue.push_back(clauses);
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
self.queue.push_back(clauses);
|
||||
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("->", 2) => {
|
||||
let conq = *terms.pop().unwrap();
|
||||
let prec = *terms.pop().unwrap();
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("->", 2) => {
|
||||
let conq = *terms.pop().unwrap();
|
||||
let prec = *terms.pop().unwrap();
|
||||
|
||||
let (stub, clauses) = self.fabricate_if_then(prec, conq);
|
||||
self.queue.push_back(clauses);
|
||||
let (stub, clauses) = self.fabricate_if_then(prec, conq);
|
||||
self.queue.push_back(clauses);
|
||||
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("\\+", 1) => {
|
||||
terms.push(Box::new(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("$fail"), None)
|
||||
)));
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("\\+", 1) => {
|
||||
terms.push(Box::new(Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("$fail"), None),
|
||||
)));
|
||||
|
||||
let conq = Term::Constant(
|
||||
Cell::default(),
|
||||
Constant::Atom(clause_name!("true"), None)
|
||||
);
|
||||
let conq =
|
||||
Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
|
||||
|
||||
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
||||
let terms = vec![Box::new(prec), Box::new(conq)];
|
||||
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
||||
let terms = vec![Box::new(prec), Box::new(conq)];
|
||||
|
||||
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
|
||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||
|
||||
debug_assert!(clauses.len() > 0);
|
||||
self.queue.push_back(clauses);
|
||||
debug_assert!(clauses.len() > 0);
|
||||
self.queue.push_back(clauses);
|
||||
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("$get_level", 1) => {
|
||||
if let Term::Var(_, ref var) = *terms[0] {
|
||||
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
|
||||
} else {
|
||||
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))
|
||||
Ok(QueryTerm::Jump(stub))
|
||||
}
|
||||
("$get_level", 1) => {
|
||||
if let Term::Var(_, ref var) = *terms[0] {
|
||||
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
|
||||
} else {
|
||||
Err(CompilationError::InadmissibleQueryTerm)
|
||||
}
|
||||
}
|
||||
}
|
||||
Term::Var(..) => {
|
||||
Ok(QueryTerm::Clause(
|
||||
Cell::default(),
|
||||
ClauseType::CallN,
|
||||
vec![Box::new(term)],
|
||||
false,
|
||||
))
|
||||
}
|
||||
_ => {
|
||||
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)),
|
||||
},
|
||||
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)
|
||||
}
|
||||
_ => self.to_query_term(load_state, term),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -884,30 +830,23 @@ impl Preprocessor {
|
||||
mut terms: Vec<Box<Term>>,
|
||||
cut_context: CutContext,
|
||||
) -> 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 =
|
||||
self.setup_query(load_state, post_head_terms, cut_context)?;
|
||||
let mut query_terms = 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();
|
||||
|
||||
match *terms.pop().unwrap() {
|
||||
Term::Clause(_, name, terms, _) => {
|
||||
Ok(Rule {
|
||||
head: (name, terms, qt),
|
||||
clauses,
|
||||
})
|
||||
}
|
||||
Term::Constant(_, Constant::Atom(name, _)) => {
|
||||
Ok(Rule {
|
||||
head: (name, vec![], qt),
|
||||
clauses,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
Err(CompilationError::InvalidRuleHead)
|
||||
}
|
||||
Term::Clause(_, name, terms, _) => Ok(Rule {
|
||||
head: (name, terms, qt),
|
||||
clauses,
|
||||
}),
|
||||
Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule {
|
||||
head: (name, vec![], qt),
|
||||
clauses,
|
||||
}),
|
||||
_ => Err(CompilationError::InvalidRuleHead),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -917,11 +856,14 @@ impl Preprocessor {
|
||||
terms: Vec<Box<Term>>,
|
||||
cut_context: CutContext,
|
||||
) -> 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)
|
||||
fn try_term_to_tl<'a>(
|
||||
pub(super) fn try_term_to_tl<'a>(
|
||||
&mut self,
|
||||
load_state: &mut LoadState<'a>,
|
||||
term: Term,
|
||||
@@ -944,9 +886,7 @@ impl Preprocessor {
|
||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
||||
}
|
||||
}
|
||||
term => {
|
||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
||||
}
|
||||
term => Ok(TopLevel::Fact(self.setup_fact(term)?)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,21 +905,18 @@ impl Preprocessor {
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn parse_queue<'a>(
|
||||
pub(super) fn parse_queue<'a>(
|
||||
&mut self,
|
||||
load_state: &mut LoadState<'a>,
|
||||
) -> Result<VecDeque<TopLevel>, CompilationError> {
|
||||
let mut queue = VecDeque::new();
|
||||
|
||||
while let Some(terms) = self.queue.pop_front() {
|
||||
let clauses = merge_clauses(
|
||||
&mut self.try_terms_to_tls(
|
||||
load_state,
|
||||
terms,
|
||||
CutContext::HasCutVariable,
|
||||
)?
|
||||
)?;
|
||||
let clauses = merge_clauses(&mut self.try_terms_to_tls(
|
||||
load_state,
|
||||
terms,
|
||||
CutContext::HasCutVariable,
|
||||
)?)?;
|
||||
|
||||
queue.push_back(clauses);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,16 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::parser::*;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::parser::*;
|
||||
|
||||
use crate::machine::*;
|
||||
use crate::machine::machine_errors::CompilationError;
|
||||
use crate::machine::preprocessor::*;
|
||||
use crate::machine::*;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt;
|
||||
|
||||
pub(crate) trait TermStream : Sized {
|
||||
pub(crate) trait TermStream: Sized {
|
||||
type Evacuable;
|
||||
|
||||
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError>;
|
||||
@@ -27,15 +27,17 @@ pub(super) struct BootstrappingTermStream<'a> {
|
||||
|
||||
impl<'a> BootstrappingTermStream<'a> {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn from_prolog_stream(
|
||||
pub(super) fn from_prolog_stream(
|
||||
stream: &'a mut PrologStream,
|
||||
atom_tbl: TabledData<Atom>,
|
||||
flags: MachineFlags,
|
||||
listing_src: ListingSource,
|
||||
) -> Self {
|
||||
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]
|
||||
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError> {
|
||||
self.parser.reset();
|
||||
self.parser.read_term(op_dir)
|
||||
self.parser
|
||||
.read_term(op_dir)
|
||||
.map_err(CompilationError::from)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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()?)
|
||||
}
|
||||
|
||||
@@ -65,9 +68,10 @@ impl<'a> TermStream for BootstrappingTermStream<'a> {
|
||||
loader.compile_and_submit()?;
|
||||
}
|
||||
|
||||
loader.load_state.retraction_info.reset(
|
||||
loader.load_state.wam.code_repo.code.len(),
|
||||
);
|
||||
loader
|
||||
.load_state
|
||||
.retraction_info
|
||||
.reset(loader.load_state.wam.code_repo.code.len());
|
||||
|
||||
loader.load_state.remove_module_op_exports();
|
||||
|
||||
@@ -82,8 +86,7 @@ pub struct LiveTermStream {
|
||||
|
||||
impl LiveTermStream {
|
||||
#[inline]
|
||||
pub(super)
|
||||
fn new(listing_src: ListingSource) -> Self {
|
||||
pub(super) fn new(listing_src: ListingSource) -> Self {
|
||||
Self {
|
||||
term_queue: VecDeque::new(),
|
||||
listing_src,
|
||||
@@ -109,8 +112,7 @@ impl fmt::Debug for LoadStatePayload {
|
||||
}
|
||||
|
||||
impl LoadStatePayload {
|
||||
pub(super)
|
||||
fn new(wam: &Machine) -> Self {
|
||||
pub(super) fn new(wam: &Machine) -> Self {
|
||||
Self {
|
||||
term_stream: LiveTermStream::new(ListingSource::User),
|
||||
compilation_target: CompilationTarget::default(),
|
||||
|
||||
43
src/main.rs
43
src/main.rs
@@ -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")]
|
||||
extern crate num_rug_adapter as rug;
|
||||
extern crate rustyline;
|
||||
extern crate sha3;
|
||||
extern crate unicode_reader;
|
||||
|
||||
use crate::nix::sys::signal;
|
||||
use num_rug_adapter as rug;
|
||||
#[cfg(feature = "rug")]
|
||||
use rug;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod allocator;
|
||||
mod arithmetic;
|
||||
mod machine;
|
||||
mod codegen;
|
||||
mod clause_types;
|
||||
mod codegen;
|
||||
mod debray_allocator;
|
||||
mod fixtures;
|
||||
mod forms;
|
||||
@@ -46,17 +17,19 @@ mod heap_print;
|
||||
mod indexing;
|
||||
mod instructions;
|
||||
mod iterators;
|
||||
mod machine;
|
||||
mod read;
|
||||
mod targets;
|
||||
mod write;
|
||||
|
||||
use machine::*;
|
||||
use machine::streams::*;
|
||||
use machine::*;
|
||||
use read::*;
|
||||
|
||||
use nix::sys::signal;
|
||||
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();
|
||||
if signal == signal::Signal::SIGINT {
|
||||
INTERRUPT.store(true, Ordering::Relaxed);
|
||||
|
||||
129
src/read.rs
129
src/read.rs
@@ -1,6 +1,6 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use crate::prolog_parser_rebis::parser::*;
|
||||
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
||||
use prolog_parser::ast::*;
|
||||
use prolog_parser::parser::*;
|
||||
use prolog_parser::tabled_rc::TabledData;
|
||||
|
||||
use crate::forms::*;
|
||||
use crate::iterators::*;
|
||||
@@ -16,8 +16,8 @@ pub type PrologStream = ParsingStream<Stream>;
|
||||
|
||||
pub mod readline {
|
||||
use crate::machine::streams::Stream;
|
||||
use crate::rustyline::error::ReadlineError;
|
||||
use crate::rustyline::{Cmd, Editor, KeyEvent};
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::{Cmd, Config, Editor, KeyEvent};
|
||||
use std::io::{Cursor, Error, ErrorKind, Read};
|
||||
|
||||
static mut PROMPT: bool = false;
|
||||
@@ -33,7 +33,11 @@ pub mod readline {
|
||||
#[inline]
|
||||
fn get_prompt() -> &'static str {
|
||||
unsafe {
|
||||
if PROMPT { "?- " } else { "" }
|
||||
if PROMPT {
|
||||
"?- "
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +50,11 @@ pub mod readline {
|
||||
impl ReadlineStream {
|
||||
#[inline]
|
||||
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() {
|
||||
path.push(HISTORY_FILE);
|
||||
if path.exists() {
|
||||
@@ -57,7 +65,10 @@ pub mod readline {
|
||||
}
|
||||
|
||||
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]
|
||||
@@ -85,12 +96,8 @@ pub mod readline {
|
||||
|
||||
self.pending_input.read(buf)
|
||||
}
|
||||
Err(ReadlineError::Eof) => {
|
||||
Ok(0)
|
||||
}
|
||||
Err(e) => {
|
||||
Err(Error::new(ErrorKind::InvalidInput, e))
|
||||
}
|
||||
Err(ReadlineError::Eof) => Ok(0),
|
||||
Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,21 +124,15 @@ pub mod readline {
|
||||
Some(b) => {
|
||||
return Ok(b);
|
||||
}
|
||||
None => {
|
||||
match self.call_readline(&mut []) {
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(0) => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::UnexpectedEof,
|
||||
"end of file",
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
None => match self.call_readline(&mut []) {
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
Ok(0) => {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "end of file"));
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,21 +145,15 @@ pub mod readline {
|
||||
Some(c) => {
|
||||
return Ok(c);
|
||||
}
|
||||
None => {
|
||||
match self.call_readline(&mut []) {
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(0) => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::UnexpectedEof,
|
||||
"end of file",
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
None => match self.call_readline(&mut []) {
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
Ok(0) => {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "end of file"));
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,12 +162,8 @@ pub mod readline {
|
||||
impl Read for ReadlineStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
match self.pending_input.read(buf) {
|
||||
Ok(0) => {
|
||||
self.call_readline(buf)
|
||||
}
|
||||
result => {
|
||||
result
|
||||
}
|
||||
Ok(0) => self.call_readline(buf),
|
||||
result => result,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,8 +201,7 @@ impl MachineState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
|
||||
pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
|
||||
let term_writer = TermWriter::new(machine_st);
|
||||
term_writer.write_term_to_heap(term)
|
||||
}
|
||||
@@ -242,8 +232,7 @@ impl<'a> TermWriter<'a> {
|
||||
#[inline]
|
||||
fn modify_head_of_queue(&mut self, term: &TermRef<'a>, h: usize) {
|
||||
if let Some((arity, site_h)) = self.queue.pop_front() {
|
||||
self.machine_st.heap[site_h] =
|
||||
HeapCellValue::Addr(self.term_as_addr(term, h));
|
||||
self.machine_st.heap[site_h] = HeapCellValue::Addr(self.term_as_addr(term, h));
|
||||
|
||||
if arity > 1 {
|
||||
self.queue.push_front((arity - 1, site_h + 1));
|
||||
@@ -254,26 +243,18 @@ impl<'a> TermWriter<'a> {
|
||||
#[inline]
|
||||
fn push_stub_addr(&mut self) {
|
||||
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 {
|
||||
match term {
|
||||
&TermRef::AnonVar(_) | &TermRef::Var(..) => {
|
||||
Addr::HeapCell(h)
|
||||
}
|
||||
&TermRef::Cons(..) => {
|
||||
Addr::HeapCell(h)
|
||||
}
|
||||
&TermRef::Constant(_, _, c) => {
|
||||
self.machine_st.heap.put_constant(c.clone())
|
||||
}
|
||||
&TermRef::Clause(..) => {
|
||||
Addr::Str(h)
|
||||
}
|
||||
&TermRef::PartialString(..) => {
|
||||
Addr::PStrLocation(h, 0)
|
||||
}
|
||||
&TermRef::AnonVar(_) | &TermRef::Var(..) => Addr::HeapCell(h),
|
||||
&TermRef::Cons(..) => Addr::HeapCell(h),
|
||||
&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 {
|
||||
&TermRef::Cons(lvl, ..) => {
|
||||
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();
|
||||
@@ -355,13 +338,15 @@ impl<'a> TermWriter<'a> {
|
||||
|
||||
continue;
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.modify_head_of_queue(&term, h);
|
||||
}
|
||||
|
||||
TermWriteResult { heap_loc, var_dict: self.var_dict }
|
||||
TermWriteResult {
|
||||
heap_loc,
|
||||
var_dict: self.var_dict,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::prolog_parser_rebis::ast::*;
|
||||
use prolog_parser::ast::*;
|
||||
|
||||
use crate::clause_types::*;
|
||||
use crate::forms::*;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
:- module('$toplevel', [argv/1,
|
||||
copy_term/3,
|
||||
predicate_property/2,
|
||||
prolog_load_context/2]).
|
||||
|
||||
:- use_module(library(loader)).
|
||||
copy_term/3]).
|
||||
|
||||
:- use_module(library(charsio)).
|
||||
:- use_module(library(iso_ext)).
|
||||
@@ -18,15 +14,15 @@
|
||||
'$repl'([_|Args0]) :-
|
||||
\+ argv(_),
|
||||
( append(Args1, ["--"|Args2], Args0) ->
|
||||
asserta(argv(Args2)),
|
||||
asserta('$toplevel':argv(Args2)),
|
||||
Args = Args1
|
||||
; asserta(argv([])),
|
||||
; asserta('$toplevel':argv([])),
|
||||
Args = Args0
|
||||
),
|
||||
delegate_task(Args, []),
|
||||
repl.
|
||||
'$repl'(_) :-
|
||||
( \+ argv(_) -> asserta(argv([]))
|
||||
( \+ argv(_) -> asserta('$toplevel':argv([]))
|
||||
; true
|
||||
),
|
||||
repl.
|
||||
@@ -41,7 +37,8 @@ delegate_task([Arg0|Args], Goals0) :-
|
||||
; member(Arg0, ["-v", "--version"]) -> print_version
|
||||
; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0)
|
||||
; 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).
|
||||
|
||||
@@ -126,7 +123,7 @@ instruction_match(Term, VarList) :-
|
||||
( Item == user ->
|
||||
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),
|
||||
|
||||
44
src/write.rs
44
src/write.rs
@@ -26,14 +26,14 @@ impl fmt::Display for REPLCodePtr {
|
||||
write!(f, "REPLCodePtr::AddGoalExpansionClause"),
|
||||
REPLCodePtr::AddTermExpansionClause =>
|
||||
write!(f, "REPLCodePtr::AddTermExpansionClause"),
|
||||
REPLCodePtr::BuiltInProperty =>
|
||||
write!(f, "REPLCodePtr::BuiltInProperty"),
|
||||
REPLCodePtr::UserAssertz =>
|
||||
write!(f, "REPLCodePtr::UserAssertz"),
|
||||
REPLCodePtr::UserAsserta =>
|
||||
write!(f, "REPLCodePtr::UserAsserta"),
|
||||
REPLCodePtr::UserRetract =>
|
||||
write!(f, "REPLCodePtr::UserRetract"),
|
||||
REPLCodePtr::AbolishClause =>
|
||||
write!(f, "REPLCodePtr::AbolishClause"),
|
||||
REPLCodePtr::Assertz =>
|
||||
write!(f, "REPLCodePtr::Assertz"),
|
||||
REPLCodePtr::Asserta =>
|
||||
write!(f, "REPLCodePtr::Asserta"),
|
||||
REPLCodePtr::Retract =>
|
||||
write!(f, "REPLCodePtr::Retract"),
|
||||
REPLCodePtr::ClauseToEvacuable =>
|
||||
write!(f, "REPLCodePtr::ClauseToEvacuable"),
|
||||
REPLCodePtr::ConcludeLoad =>
|
||||
@@ -64,8 +64,14 @@ impl fmt::Display for REPLCodePtr {
|
||||
write!(f, "REPLCodePtr::UseModule"),
|
||||
REPLCodePtr::MetaPredicateProperty =>
|
||||
write!(f, "REPLCodePtr::MetaPredicateProperty"),
|
||||
REPLCodePtr::CompilePendingPredicates =>
|
||||
write!(f, "REPLCodePtr::CompilePendingPredicates"),
|
||||
REPLCodePtr::BuiltInProperty =>
|
||||
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) => {
|
||||
// write!(f, "filename {} is invalid", filename)
|
||||
// }
|
||||
// &SessionError::ModuleDoesNotContainExport(ref module, ref key) => {
|
||||
// write!(
|
||||
// f,
|
||||
// "module {} does not contain claimed export {}/{}",
|
||||
// module,
|
||||
// key.0,
|
||||
// key.1,
|
||||
// )
|
||||
// }
|
||||
&SessionError::ModuleDoesNotContainExport(ref module, ref key) => {
|
||||
write!(
|
||||
f,
|
||||
"module {} does not contain claimed export {}/{}",
|
||||
module,
|
||||
key.0,
|
||||
key.1,
|
||||
)
|
||||
}
|
||||
&SessionError::OpIsInfixAndPostFix(_) => {
|
||||
write!(f, "cannot define an op to be both postfix and infix.")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user