Merge branch 'Skgland-clean_up' into rebis-dev

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

4
Cargo.lock generated
View File

@@ -878,7 +878,7 @@ dependencies = [
]
[[package]]
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",

View File

@@ -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"

View File

@@ -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",
)

View File

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

View File

@@ -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"

View File

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

View File

@@ -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),
}
}
}

View File

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

View File

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

View File

@@ -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 {

View File

@@ -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())
};
}

View File

@@ -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),
}
}

View File

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

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::temp_v;
use crate::fixtures::*;
use crate::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();

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::{atom, clause_name};
use crate::clause_types::*;
use crate::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(()),
}
}
}

View File

@@ -1,10 +1,11 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::{clause_name, temp_v};
use crate::forms::Number;
use crate::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;
@@ -322,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"),
@@ -337,58 +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::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::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"),
@@ -397,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"),
@@ -424,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"),
@@ -455,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"),
@@ -507,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"),
@@ -521,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"),
@@ -542,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"),
@@ -556,14 +578,16 @@ impl SystemClauseType {
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
match (name, arity) {
("$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)),
("$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),
@@ -602,7 +626,9 @@ impl SystemClauseType {
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
("$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),
@@ -611,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)
@@ -691,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),
@@ -708,12 +728,18 @@ 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)),
("$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)),
@@ -742,18 +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)),
("$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)),
("$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,
}
}
@@ -832,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,
}
}

View File

@@ -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;
}
}

View File

@@ -1,6 +1,7 @@
use crate::indexmap::IndexMap;
use indexmap::IndexMap;
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::temp_v;
use crate::allocator::*;
use crate::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);

View File

@@ -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;
}

View File

@@ -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 => {}
}
}
}

View File

@@ -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,
}
}
}

View File

@@ -1,4 +1,10 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::{
alpha_numeric_char, capital_letter_char, clause_name, cut_char, decimal_digit_char,
graphic_token_char, is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx,
semicolon_char, sign_char, single_quote_char, small_letter_char, solo_char,
variable_indicator_char,
};
use crate::clause_types::*;
use crate::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(

View File

@@ -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()
}

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::clause_name;
use crate::clause_types::*;
use crate::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)])

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::rc_atom;
use crate::clause_types::*;
use crate::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)));

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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)),
}
}
}

View File

@@ -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,16 +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,49 +88,45 @@ 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,
@@ -166,12 +161,7 @@ fn import_module_exports(
}
}
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);
}
}
}
@@ -185,7 +175,7 @@ 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,
) {
for export in imported_module.module_decl.exports.iter() {
match export {
@@ -227,7 +217,6 @@ fn import_module_exports_into_module(
}
}
fn import_qualified_module_exports(
retraction_info: &mut RetractionInfo,
compilation_target: &CompilationTarget,
@@ -263,12 +252,7 @@ fn import_qualified_module_exports(
}
}
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);
}
}
}
@@ -326,29 +310,28 @@ fn import_qualified_module_exports_into_module(
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 +348,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 +377,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 +411,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 +440,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 +470,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 +485,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,14 +509,11 @@ impl<'a> LoadState<'a> {
ClauseType::Op(name, fixity, idx)
}
ct => {
ct
}
ct => ct,
}
}
pub(super)
fn add_meta_predicate_record(
pub(super) fn add_meta_predicate_record(
&mut self,
module_name: ClauseName,
name: ClauseName,
@@ -540,20 +524,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,
));
}
}
}
@@ -564,15 +554,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),
);
}
}
@@ -588,15 +578,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);
}
@@ -623,32 +612,29 @@ impl<'a> LoadState<'a> {
}
}
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,
@@ -676,8 +662,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 => {
@@ -717,7 +702,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,
)))
}
}
@@ -765,41 +752,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)?;
@@ -820,43 +807,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)?;
@@ -884,12 +867,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

View File

@@ -1,4 +1,5 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::{clause_name, temp_v};
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
use crate::machine::heap::*;
@@ -23,74 +24,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 +90,7 @@ impl PermissionError for Addr {
MachineError {
stub,
location: None,
from: ErrorProvenance::Received
from: ErrorProvenance::Received,
}
}
}
@@ -120,22 +106,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 +129,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 +140,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 +149,7 @@ impl MachineError {
}
#[inline]
pub(super)
fn interrupt_error() -> Self {
pub(super) fn interrupt_error() -> Self {
let stub = functor!("$interrupt_thrown");
MachineError {
@@ -182,8 +159,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 +169,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 +192,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 +201,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 +219,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 +243,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 +252,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 +263,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 +288,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 +302,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,9 +315,7 @@ 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))
// }
@@ -385,46 +329,32 @@ impl MachineError {
)
}
*/
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 +364,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 +373,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,56 +440,39 @@ 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"),
}
}
}
@@ -715,16 +623,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 +641,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 +675,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 +703,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 +723,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 +731,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 +774,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;

View File

@@ -1,22 +1,23 @@
use crate::prolog_parser_rebis::ast::*;
use prolog_parser::ast::*;
use prolog_parser::clause_name;
use crate::clause_types::*;
use crate::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,
}
}
@@ -536,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.
}
@@ -544,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,
}
}
@@ -566,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,
_ => {}
@@ -579,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,
@@ -588,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"));
@@ -658,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)
}
@@ -693,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),
}
}
}
@@ -709,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)),
}
}
}
@@ -723,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) {
@@ -749,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)
}
@@ -784,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
}
}
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
@@ -830,23 +726,17 @@ impl IndexStore {
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
}
}
}
},
}
}
@@ -858,19 +748,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);
}
}
}
},
}
}
@@ -883,15 +771,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| {
@@ -902,9 +784,7 @@ impl IndexStore {
ClauseType::Op(name, spec, ..) => {
module.code_dir.get(&(name, spec.arity())).cloned()
}
_ => {
None
}
_ => None,
}
})
}
@@ -917,44 +797,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,
},
}
}
@@ -963,8 +831,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");
@@ -996,10 +863,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),
}
}
}
@@ -1012,7 +877,9 @@ impl<'a, T> RefOrOwned<'a, T> {
}
}
pub fn to_owned(self) -> T where T: Clone
pub fn to_owned(self) -> T
where
T: Clone,
{
match self {
RefOrOwned::Borrowed(item) => item.clone(),

View File

@@ -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) = &quoted {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
printer.quoted = name.as_str() == "true";
} 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

File diff suppressed because it is too large Load Diff

View File

@@ -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;
@@ -162,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));
}
@@ -206,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");
@@ -218,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)) {
@@ -255,12 +250,13 @@ impl Machine {
fn configure_modules(&mut self) {
fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
for arity in 1 .. 66 {
for arity in 1..66 {
let key = (clause_name!("call"), arity);
match loader.code_dir.get(&key) {
Some(src_code_index) => {
let target_code_index = target_module.code_dir
let target_code_index = target_module
.code_dir
.entry(key.clone())
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
@@ -289,10 +285,11 @@ impl Machine {
builtins.module_decl.exports.push(export.clone());
}
for arity in 10 .. 66 {
builtins.module_decl.exports.push(
ModuleExport::PredicateKey((clause_name!("call"), arity)),
);
for arity in 10..66 {
builtins
.module_decl
.exports
.push(ModuleExport::PredicateKey((clause_name!("call"), arity)));
}
}
@@ -306,9 +303,8 @@ impl Machine {
}
}
pub fn new(user_input: Stream, user_output: Stream) -> Self
{
use crate::ref_thread_local::RefThreadLocal;
pub fn new(user_input: Stream, user_output: Stream) -> Self {
use ref_thread_local::RefThreadLocal;
let mut wam = Machine {
machine_st: MachineState::new(),
@@ -333,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(
@@ -361,11 +356,9 @@ 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();
wam.configure_modules();
@@ -391,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) {
@@ -508,8 +495,7 @@ impl Machine {
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,
@@ -546,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;
@@ -617,15 +599,13 @@ impl MachineState {
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;
}
_ => {
}
_ => {}
}
true
@@ -689,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();

View File

@@ -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.compilation_target.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

View File

@@ -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(),

View File

@@ -1,43 +1,14 @@
extern crate blake2;
extern crate chrono;
extern crate cpu_time;
extern crate crossterm;
extern crate divrem;
#[macro_use]
extern crate downcast;
extern crate git_version;
extern crate hostname;
extern crate indexmap;
#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate native_tls;
extern crate nix;
extern crate openssl;
extern crate ordered_float;
#[macro_use]
extern crate prolog_parser_rebis;
#[macro_use]
extern crate ref_thread_local;
extern crate ring;
extern crate ripemd160;
#[cfg(feature = "rug")]
extern crate rug;
#[cfg(feature = "num-rug-adapter")]
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);

View File

@@ -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, Config, 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 {
""
}
}
}
@@ -61,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]
@@ -89,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)),
}
}
@@ -121,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"));
}
_ => {}
},
}
}
}
@@ -148,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"));
}
_ => {}
},
}
}
}
@@ -171,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,
}
}
}
@@ -214,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)
}
@@ -246,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));
@@ -258,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),
}
}
@@ -290,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();
@@ -359,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,
}
}
}

View File

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