Merge branch 'rebis-dev' of https://github.com/mthom/scryer-prolog into rebis-dev
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -878,7 +878,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser_rebis"
|
name = "prolog_parser"
|
||||||
version = "0.8.68"
|
version = "0.8.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical",
|
"lexical",
|
||||||
@@ -1221,7 +1221,7 @@ dependencies = [
|
|||||||
"num-rug-adapter",
|
"num-rug-adapter",
|
||||||
"openssl",
|
"openssl",
|
||||||
"ordered-float",
|
"ordered-float",
|
||||||
"prolog_parser_rebis",
|
"prolog_parser",
|
||||||
"ref_thread_local",
|
"ref_thread_local",
|
||||||
"ring",
|
"ring",
|
||||||
"ripemd160",
|
"ripemd160",
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ members = ["crates/prolog_parser"]
|
|||||||
indexmap = "1.0.2"
|
indexmap = "1.0.2"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rug", "prolog_parser_rebis/rug"]
|
default = ["rug", "prolog_parser/rug"]
|
||||||
num = ["num-rug-adapter", "prolog_parser_rebis/num"]
|
num = ["num-rug-adapter", "prolog_parser/num"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cpu-time = "1.0.0"
|
cpu-time = "1.0.0"
|
||||||
@@ -35,7 +35,7 @@ libc = "0.2.62"
|
|||||||
nix = "0.15.0"
|
nix = "0.15.0"
|
||||||
num-rug-adapter = { optional = true, version = "0.1.4" }
|
num-rug-adapter = { optional = true, version = "0.1.4" }
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser_rebis = { path = "./crates/prolog_parser", default-features = false }
|
prolog_parser = { path = "./crates/prolog_parser", default-features = false }
|
||||||
ref_thread_local = "0.0.0"
|
ref_thread_local = "0.0.0"
|
||||||
rug = { version = "1.4.0", optional = true }
|
rug = { version = "1.4.0", optional = true }
|
||||||
rustyline = "7.0.0"
|
rustyline = "7.0.0"
|
||||||
|
|||||||
10
build.rs
10
build.rs
@@ -1,5 +1,3 @@
|
|||||||
extern crate indexmap;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@@ -15,15 +13,13 @@ fn find_prolog_files(libraries: &mut File, prefix: &str, current_dir: &Path) {
|
|||||||
for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
|
for entry in entries.filter_map(Result::ok).map(|e| e.path()) {
|
||||||
if entry.is_dir() {
|
if entry.is_dir() {
|
||||||
if let Some(file_name) = entry.file_name() {
|
if let Some(file_name) = entry.file_name() {
|
||||||
let new_prefix =
|
let new_prefix = prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
||||||
prefix.to_owned() + file_name.to_str().unwrap() + "/";
|
|
||||||
find_prolog_files(libraries, &new_prefix, &entry);
|
find_prolog_files(libraries, &new_prefix, &entry);
|
||||||
}
|
}
|
||||||
} else if entry.is_file() {
|
} else if entry.is_file() {
|
||||||
let ext = std::ffi::OsStr::new("pl");
|
let ext = std::ffi::OsStr::new("pl");
|
||||||
if entry.extension() == Some(ext) {
|
if entry.extension() == Some(ext) {
|
||||||
let contain =
|
let contain = String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
||||||
String::from_utf8(fs::read(&entry).unwrap()).unwrap();
|
|
||||||
let name = entry.file_stem().unwrap().to_str().unwrap();
|
let name = entry.file_stem().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
let line = format!(
|
let line = format!(
|
||||||
@@ -47,7 +43,7 @@ fn main() {
|
|||||||
|
|
||||||
libraries
|
libraries
|
||||||
.write_all(
|
.write_all(
|
||||||
b"ref_thread_local! {
|
b"ref_thread_local::ref_thread_local! {
|
||||||
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
pub static managed LIBRARIES: IndexMap<&'static str, &'static str> = {
|
||||||
let mut m = IndexMap::new();\n",
|
let mut m = IndexMap::new();\n",
|
||||||
)
|
)
|
||||||
|
|||||||
2
crates/prolog_parser/Cargo.lock
generated
2
crates/prolog_parser/Cargo.lock
generated
@@ -148,7 +148,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser_rebis"
|
name = "prolog_parser"
|
||||||
version = "0.8.68"
|
version = "0.8.68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical",
|
"lexical",
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "prolog_parser_rebis"
|
name = "prolog_parser"
|
||||||
version = "0.8.68"
|
version = "0.8.68"
|
||||||
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
authors = ["Mark Thom <markjordanthom@gmail.com>"]
|
||||||
repository = "https://github.com/mthom/prolog_parser"
|
edition = "2018"
|
||||||
|
repository = "https://github.com/mthom/scryer-prolog"
|
||||||
description = " An operator precedence parser for the Rebis development version of Scryer Prolog, an up and coming ISO Prolog implementation."
|
description = " An operator precedence parser for the Rebis development version of Scryer Prolog, an up and coming ISO Prolog implementation."
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use rug::{Integer, Rational};
|
use crate::rug::{Integer, Rational};
|
||||||
|
use crate::tabled_rc::*;
|
||||||
use ordered_float::*;
|
use ordered_float::*;
|
||||||
use tabled_rc::*;
|
|
||||||
|
|
||||||
use put_back_n::*;
|
use crate::put_back_n::*;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
@@ -27,112 +27,150 @@ pub const MAX_ARITY: usize = 1023;
|
|||||||
pub const XFX: u32 = 0x0001;
|
pub const XFX: u32 = 0x0001;
|
||||||
pub const XFY: u32 = 0x0002;
|
pub const XFY: u32 = 0x0002;
|
||||||
pub const YFX: u32 = 0x0004;
|
pub const YFX: u32 = 0x0004;
|
||||||
pub const XF: u32 = 0x0010;
|
pub const XF: u32 = 0x0010;
|
||||||
pub const YF: u32 = 0x0020;
|
pub const YF: u32 = 0x0020;
|
||||||
pub const FX: u32 = 0x0040;
|
pub const FX: u32 = 0x0040;
|
||||||
pub const FY: u32 = 0x0080;
|
pub const FY: u32 = 0x0080;
|
||||||
pub const DELIMITER: u32 = 0x0100;
|
pub const DELIMITER: u32 = 0x0100;
|
||||||
pub const TERM: u32 = 0x1000;
|
pub const TERM: u32 = 0x1000;
|
||||||
pub const LTERM: u32 = 0x3000;
|
pub const LTERM: u32 = 0x3000;
|
||||||
|
|
||||||
pub const NEGATIVE_SIGN: u32 = 0x0200;
|
pub const NEGATIVE_SIGN: u32 = 0x0200;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! clause_name {
|
macro_rules! clause_name {
|
||||||
($name: expr, $tbl: expr) => (
|
($name: expr, $tbl: expr) => {
|
||||||
ClauseName::User(TabledRc::new($name, $tbl.clone()))
|
$crate::ast::ClauseName::User($crate::tabled_rc::TabledRc::new($name, $tbl.clone()))
|
||||||
) ;
|
};
|
||||||
($name: expr) => (
|
($name: expr) => {
|
||||||
ClauseName::BuiltIn($name)
|
$crate::ast::ClauseName::BuiltIn($name)
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! atom {
|
macro_rules! atom {
|
||||||
($e:expr, $tbl:expr) => (
|
($e:expr, $tbl:expr) => {
|
||||||
Constant::Atom(ClauseName::User(tabled_rc!($e, $tbl)), None)
|
$crate::ast::Constant::Atom(
|
||||||
);
|
$crate::ast::ClauseName::User($crate::tabled_rc!($e, $tbl)),
|
||||||
($e:expr) => (
|
None,
|
||||||
Constant::Atom(clause_name!($e), None)
|
)
|
||||||
)
|
};
|
||||||
|
($e:expr) => {
|
||||||
|
$crate::ast::Constant::Atom($crate::clause_name!($e), None)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! rc_atom {
|
macro_rules! rc_atom {
|
||||||
($e:expr) => (
|
($e:expr) => {
|
||||||
Rc::new(String::from($e))
|
Rc::new(String::from($e))
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
macro_rules! is_term {
|
macro_rules! is_term {
|
||||||
($x:expr) => ( ($x & TERM) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::TERM) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_lterm {
|
macro_rules! is_lterm {
|
||||||
($x:expr) => ( ($x & LTERM) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::LTERM) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_op {
|
macro_rules! is_op {
|
||||||
($x:expr) => ( $x & (XF | YF | FX | FY | XFX | XFY | YFX) != 0 )
|
($x:expr) => {
|
||||||
|
$x & ($crate::ast::XF
|
||||||
|
| $crate::ast::YF
|
||||||
|
| $crate::ast::FX
|
||||||
|
| $crate::ast::FY
|
||||||
|
| $crate::ast::XFX
|
||||||
|
| $crate::ast::XFY
|
||||||
|
| $crate::ast::YFX)
|
||||||
|
!= 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_negate {
|
macro_rules! is_negate {
|
||||||
($x:expr) => ( ($x & NEGATIVE_SIGN) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::NEGATIVE_SIGN) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_prefix {
|
macro_rules! is_prefix {
|
||||||
($x:expr) => ( $x & (FX | FY) != 0 )
|
($x:expr) => {
|
||||||
|
$x & ($crate::ast::FX | $crate::ast::FY) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_postfix {
|
macro_rules! is_postfix {
|
||||||
($x:expr) => ( $x & (XF | YF) != 0 )
|
($x:expr) => {
|
||||||
|
$x & ($crate::ast::XF | $crate::ast::YF) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_infix {
|
macro_rules! is_infix {
|
||||||
($x:expr) => ( ($x & (XFX | XFY | YFX)) != 0 )
|
($x:expr) => {
|
||||||
|
($x & ($crate::ast::XFX | $crate::ast::XFY | $crate::ast::YFX)) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_xfx {
|
macro_rules! is_xfx {
|
||||||
($x:expr) => ( ($x & XFX) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::XFX) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_xfy {
|
macro_rules! is_xfy {
|
||||||
($x:expr) => ( ($x & XFY) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::XFY) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_yfx {
|
macro_rules! is_yfx {
|
||||||
($x:expr) => ( ($x & YFX) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::YFX) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_yf {
|
macro_rules! is_yf {
|
||||||
($x:expr) => ( ($x & YF) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::YF) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_xf {
|
macro_rules! is_xf {
|
||||||
($x:expr) => ( ($x & XF) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::XF) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_fx {
|
macro_rules! is_fx {
|
||||||
($x:expr) => ( ($x & FX) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::FX) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! is_fy {
|
macro_rules! is_fy {
|
||||||
($x:expr) => ( ($x & FY) != 0 )
|
($x:expr) => {
|
||||||
|
($x & $crate::ast::FY) != 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum RegType {
|
pub enum RegType {
|
||||||
Perm(usize),
|
Perm(usize),
|
||||||
Temp(usize)
|
Temp(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RegType {
|
impl Default for RegType {
|
||||||
@@ -144,23 +182,20 @@ impl Default for RegType {
|
|||||||
impl RegType {
|
impl RegType {
|
||||||
pub fn reg_num(self) -> usize {
|
pub fn reg_num(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num
|
RegType::Perm(reg_num) | RegType::Temp(reg_num) => reg_num,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_perm(self) -> bool {
|
pub fn is_perm(self) -> bool {
|
||||||
match self {
|
matches!(self, RegType::Perm(_))
|
||||||
RegType::Perm(_) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for RegType {
|
impl fmt::Display for RegType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&RegType::Perm(val) => write!(f, "Y{}", val),
|
RegType::Perm(val) => write!(f, "Y{}", val),
|
||||||
&RegType::Temp(val) => write!(f, "X{}", val)
|
RegType::Temp(val) => write!(f, "X{}", val),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,13 +203,13 @@ impl fmt::Display for RegType {
|
|||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum VarReg {
|
pub enum VarReg {
|
||||||
ArgAndNorm(RegType, usize),
|
ArgAndNorm(RegType, usize),
|
||||||
Norm(RegType)
|
Norm(RegType),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VarReg {
|
impl VarReg {
|
||||||
pub fn norm(self) -> RegType {
|
pub fn norm(self) -> RegType {
|
||||||
match self {
|
match self {
|
||||||
VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg
|
VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,12 +217,10 @@ impl VarReg {
|
|||||||
impl fmt::Display for VarReg {
|
impl fmt::Display for VarReg {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
|
VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
|
||||||
&VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
|
VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
|
||||||
&VarReg::ArgAndNorm(RegType::Perm(reg), arg) =>
|
VarReg::ArgAndNorm(RegType::Perm(reg), arg) => write!(f, "Y{} A{}", reg, arg),
|
||||||
write!(f, "Y{} A{}", reg, arg),
|
VarReg::ArgAndNorm(RegType::Temp(reg), arg) => write!(f, "X{} A{}", reg, arg),
|
||||||
&VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
|
|
||||||
write!(f, "X{} A{}", reg, arg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,28 +233,30 @@ impl Default for VarReg {
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! temp_v {
|
macro_rules! temp_v {
|
||||||
($x:expr) => (
|
($x:expr) => {
|
||||||
RegType::Temp($x)
|
$crate::ast::RegType::Temp($x)
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! perm_v {
|
macro_rules! perm_v {
|
||||||
($x:expr) => (
|
($x:expr) => {
|
||||||
RegType::Perm($x)
|
$crate::ast::RegType::Perm($x)
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum GenContext {
|
pub enum GenContext {
|
||||||
Head, Mid(usize), Last(usize) // Mid & Last: chunk_num
|
Head,
|
||||||
|
Mid(usize),
|
||||||
|
Last(usize), // Mid & Last: chunk_num
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenContext {
|
impl GenContext {
|
||||||
pub fn chunk_num(self) -> usize {
|
pub fn chunk_num(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
GenContext::Head => 0,
|
GenContext::Head => 0,
|
||||||
GenContext::Mid(cn) | GenContext::Last(cn) => cn
|
GenContext::Mid(cn) | GenContext::Last(cn) => cn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,43 +282,35 @@ pub type OpDir = HashMap<OpDirKey, OpDirValue>;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct MachineFlags {
|
pub struct MachineFlags {
|
||||||
pub double_quotes: DoubleQuotes
|
pub double_quotes: DoubleQuotes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MachineFlags {
|
impl Default for MachineFlags {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
MachineFlags { double_quotes: DoubleQuotes::default() }
|
MachineFlags {
|
||||||
|
double_quotes: DoubleQuotes::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum DoubleQuotes {
|
pub enum DoubleQuotes {
|
||||||
Atom, Chars, Codes
|
Atom,
|
||||||
|
Chars,
|
||||||
|
Codes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DoubleQuotes {
|
impl DoubleQuotes {
|
||||||
pub fn is_chars(self) -> bool {
|
pub fn is_chars(self) -> bool {
|
||||||
if let DoubleQuotes::Chars = self {
|
matches!(self, DoubleQuotes::Chars)
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_atom(self) -> bool {
|
pub fn is_atom(self) -> bool {
|
||||||
if let DoubleQuotes::Atom = self {
|
matches!(self, DoubleQuotes::Atom)
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_codes(self) -> bool {
|
pub fn is_codes(self) -> bool {
|
||||||
if let DoubleQuotes::Codes = self {
|
matches!(self, DoubleQuotes::Codes)
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,10 +323,10 @@ impl Default for DoubleQuotes {
|
|||||||
pub fn default_op_dir() -> OpDir {
|
pub fn default_op_dir() -> OpDir {
|
||||||
let mut op_dir = OpDir::new();
|
let mut op_dir = OpDir::new();
|
||||||
|
|
||||||
op_dir.insert((clause_name!(":-"), Fixity::In), OpDirValue::new(XFX, 1200));
|
op_dir.insert((clause_name!(":-"), Fixity::In), OpDirValue::new(XFX, 1200));
|
||||||
op_dir.insert((clause_name!(":-"), Fixity::Pre), OpDirValue::new(FX, 1200));
|
op_dir.insert((clause_name!(":-"), Fixity::Pre), OpDirValue::new(FX, 1200));
|
||||||
op_dir.insert((clause_name!("?-"), Fixity::Pre), OpDirValue::new(FX, 1200));
|
op_dir.insert((clause_name!("?-"), Fixity::Pre), OpDirValue::new(FX, 1200));
|
||||||
op_dir.insert((clause_name!(","), Fixity::In), OpDirValue::new(XFY, 1000));
|
op_dir.insert((clause_name!(","), Fixity::In), OpDirValue::new(XFY, 1000));
|
||||||
|
|
||||||
op_dir
|
op_dir
|
||||||
}
|
}
|
||||||
@@ -307,7 +334,7 @@ pub fn default_op_dir() -> OpDir {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ArithmeticError {
|
pub enum ArithmeticError {
|
||||||
NonEvaluableFunctor(Constant, usize),
|
NonEvaluableFunctor(Constant, usize),
|
||||||
UninstantiatedVar
|
UninstantiatedVar,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -321,47 +348,35 @@ pub enum ParserError {
|
|||||||
MissingQuote(usize, usize),
|
MissingQuote(usize, usize),
|
||||||
NonPrologChar(usize, usize),
|
NonPrologChar(usize, usize),
|
||||||
ParseBigInt(usize, usize),
|
ParseBigInt(usize, usize),
|
||||||
Utf8Error(usize, usize)
|
Utf8Error(usize, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParserError {
|
impl ParserError {
|
||||||
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||||
match self {
|
match self {
|
||||||
&ParserError::BackQuotedString(line_num, col_num)
|
&ParserError::BackQuotedString(line_num, col_num)
|
||||||
| &ParserError::UnexpectedChar(_, line_num, col_num)
|
| &ParserError::UnexpectedChar(_, line_num, col_num)
|
||||||
| &ParserError::IncompleteReduction(line_num, col_num)
|
| &ParserError::IncompleteReduction(line_num, col_num)
|
||||||
| &ParserError::MissingQuote(line_num, col_num)
|
| &ParserError::MissingQuote(line_num, col_num)
|
||||||
| &ParserError::NonPrologChar(line_num, col_num)
|
| &ParserError::NonPrologChar(line_num, col_num)
|
||||||
| &ParserError::ParseBigInt(line_num, col_num)
|
| &ParserError::ParseBigInt(line_num, col_num)
|
||||||
| &ParserError::Utf8Error(line_num, col_num) =>
|
| &ParserError::Utf8Error(line_num, col_num) => Some((line_num, col_num)),
|
||||||
Some((line_num, col_num)),
|
_ => None,
|
||||||
_ =>
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
&ParserError::BackQuotedString(..) =>
|
ParserError::BackQuotedString(..) => "back_quoted_string",
|
||||||
"back_quoted_string",
|
ParserError::UnexpectedChar(..) => "unexpected_char",
|
||||||
&ParserError::UnexpectedChar(..) =>
|
ParserError::UnexpectedEOF => "unexpected_end_of_file",
|
||||||
"unexpected_char",
|
ParserError::IncompleteReduction(..) => "incomplete_reduction",
|
||||||
&ParserError::UnexpectedEOF =>
|
ParserError::InvalidSingleQuotedCharacter(..) => "invalid_single_quoted_character",
|
||||||
"unexpected_end_of_file",
|
ParserError::IO(_) => "input_output_error",
|
||||||
&ParserError::IncompleteReduction(..) =>
|
ParserError::MissingQuote(..) => "missing_quote",
|
||||||
"incomplete_reduction",
|
ParserError::NonPrologChar(..) => "non_prolog_character",
|
||||||
&ParserError::InvalidSingleQuotedCharacter(..) =>
|
ParserError::ParseBigInt(..) => "cannot_parse_big_int",
|
||||||
"invalid_single_quoted_character",
|
ParserError::Utf8Error(..) => "utf8_conversion_error",
|
||||||
&ParserError::IO(_) =>
|
|
||||||
"input_output_error",
|
|
||||||
&ParserError::MissingQuote(..) =>
|
|
||||||
"missing_quote",
|
|
||||||
&ParserError::NonPrologChar(..) =>
|
|
||||||
"non_prolog_character",
|
|
||||||
&ParserError::ParseBigInt(..) =>
|
|
||||||
"cannot_parse_big_int",
|
|
||||||
&ParserError::Utf8Error(..) =>
|
|
||||||
"utf8_conversion_error",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,39 +397,38 @@ impl From<&IOError> for ParserError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct CompositeOpDir<'a, 'b> {
|
pub struct CompositeOpDir<'a, 'b> {
|
||||||
pub primary_op_dir: Option<&'b OpDir>,
|
pub primary_op_dir: Option<&'b OpDir>,
|
||||||
pub secondary_op_dir: &'a OpDir,
|
pub secondary_op_dir: &'a OpDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> CompositeOpDir<'a, 'b>
|
impl<'a, 'b> CompositeOpDir<'a, 'b> {
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(secondary_op_dir: &'a OpDir, primary_op_dir: Option<&'b OpDir>) -> Self {
|
pub fn new(secondary_op_dir: &'a OpDir, primary_op_dir: Option<&'b OpDir>) -> Self {
|
||||||
CompositeOpDir { primary_op_dir, secondary_op_dir }
|
CompositeOpDir {
|
||||||
|
primary_op_dir,
|
||||||
|
secondary_op_dir,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn get(&self, name: ClauseName, fixity: Fixity) -> Option<&OpDirValue> {
|
||||||
fn get(&self, name: ClauseName, fixity: Fixity) -> Option<&OpDirValue>
|
let entry = if let Some(ref primary_op_dir) = &self.primary_op_dir {
|
||||||
{
|
primary_op_dir.get(&(name.clone(), fixity))
|
||||||
let entry =
|
} else {
|
||||||
if let Some(ref primary_op_dir) = &self.primary_op_dir {
|
None
|
||||||
primary_op_dir.get(&(name.clone(), fixity))
|
};
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
entry.or_else(move || self.secondary_op_dir.get(&(name, fixity)))
|
entry.or_else(move || self.secondary_op_dir.get(&(name, fixity)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||||
pub enum Fixity {
|
pub enum Fixity {
|
||||||
In, Post, Pre
|
In,
|
||||||
|
Post,
|
||||||
|
Pre,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
@@ -496,28 +510,21 @@ pub enum Constant {
|
|||||||
impl fmt::Display for Constant {
|
impl fmt::Display for Constant {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&Constant::Atom(ref atom, _) =>
|
Constant::Atom(ref atom, _) => {
|
||||||
if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) {
|
if atom.as_str().chars().any(|c| "`.$'\" ".contains(c)) {
|
||||||
write!(f, "'{}'", atom.as_str())
|
write!(f, "'{}'", atom.as_str())
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", atom.as_str())
|
write!(f, "{}", atom.as_str())
|
||||||
},
|
}
|
||||||
&Constant::Char(c) =>
|
}
|
||||||
write!(f, "'{}'", c as u32),
|
Constant::Char(c) => write!(f, "'{}'", *c as u32),
|
||||||
&Constant::EmptyList =>
|
Constant::EmptyList => write!(f, "[]"),
|
||||||
write!(f, "[]"),
|
Constant::Fixnum(n) => write!(f, "{}", n),
|
||||||
&Constant::Fixnum(n) =>
|
Constant::Integer(ref n) => write!(f, "{}", n),
|
||||||
write!(f, "{}", n),
|
Constant::Rational(ref n) => write!(f, "{}", n),
|
||||||
&Constant::Integer(ref n) =>
|
Constant::Float(ref n) => write!(f, "{}", n),
|
||||||
write!(f, "{}", n),
|
Constant::String(ref s) => write!(f, "\"{}\"", &s),
|
||||||
&Constant::Rational(ref n) =>
|
Constant::Usize(integer) => write!(f, "u{}", integer),
|
||||||
write!(f, "{}", n),
|
|
||||||
&Constant::Float(ref n) =>
|
|
||||||
write!(f, "{}", n),
|
|
||||||
&Constant::String(ref s) =>
|
|
||||||
write!(f, "\"{}\"", &s),
|
|
||||||
&Constant::Usize(integer) =>
|
|
||||||
write!(f, "u{}", integer),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -526,37 +533,27 @@ impl PartialEq for Constant {
|
|||||||
fn eq(&self, other: &Constant) -> bool {
|
fn eq(&self, other: &Constant) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&Constant::Atom(ref atom, _), &Constant::Char(c))
|
(&Constant::Atom(ref atom, _), &Constant::Char(c))
|
||||||
| (&Constant::Char(c), &Constant::Atom(ref atom, _)) => {
|
| (&Constant::Char(c), &Constant::Atom(ref atom, _)) => {
|
||||||
atom.is_char() && Some(c) == atom.as_str().chars().next()
|
atom.is_char() && atom.as_str().starts_with(c)
|
||||||
},
|
}
|
||||||
(&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) =>
|
(&Constant::Atom(ref a1, _), &Constant::Atom(ref a2, _)) => a1.as_str() == a2.as_str(),
|
||||||
a1.as_str() == a2.as_str(),
|
(&Constant::Char(c1), &Constant::Char(c2)) => c1 == c2,
|
||||||
(&Constant::Char(c1), &Constant::Char(c2)) =>
|
(&Constant::Fixnum(n1), &Constant::Fixnum(n2)) => n1 == n2,
|
||||||
c1 == c2,
|
(&Constant::Fixnum(n1), &Constant::Integer(ref n2))
|
||||||
(&Constant::Fixnum(n1), &Constant::Fixnum(n2)) =>
|
| (&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => {
|
||||||
n1 == n2,
|
|
||||||
(&Constant::Fixnum(n1), &Constant::Integer(ref n2)) |
|
|
||||||
(&Constant::Integer(ref n2), &Constant::Fixnum(n1)) => {
|
|
||||||
if let Some(n2) = n2.to_isize() {
|
if let Some(n2) = n2.to_isize() {
|
||||||
n1 == n2
|
n1 == n2
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&Constant::Integer(ref n1), &Constant::Integer(ref n2)) =>
|
(&Constant::Integer(ref n1), &Constant::Integer(ref n2)) => n1 == n2,
|
||||||
n1 == n2,
|
(&Constant::Rational(ref n1), &Constant::Rational(ref n2)) => n1 == n2,
|
||||||
(&Constant::Rational(ref n1), &Constant::Rational(ref n2)) =>
|
(&Constant::Float(ref n1), &Constant::Float(ref n2)) => n1 == n2,
|
||||||
n1 == n2,
|
(&Constant::String(ref s1), &Constant::String(ref s2)) => s1 == s2,
|
||||||
(&Constant::Float(ref n1), &Constant::Float(ref n2)) =>
|
(&Constant::EmptyList, &Constant::EmptyList) => true,
|
||||||
n1 == n2,
|
(&Constant::Usize(u1), &Constant::Usize(u2)) => u1 == u2,
|
||||||
(&Constant::String(ref s1), &Constant::String(ref s2)) => {
|
_ => false,
|
||||||
&s1 == &s2
|
|
||||||
}
|
|
||||||
(&Constant::EmptyList, &Constant::EmptyList) =>
|
|
||||||
true,
|
|
||||||
(&Constant::Usize(u1), &Constant::Usize(u2)) =>
|
|
||||||
u1 == u2,
|
|
||||||
_ => false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,10 +561,10 @@ impl PartialEq for Constant {
|
|||||||
impl Eq for Constant {}
|
impl Eq for Constant {}
|
||||||
|
|
||||||
impl Constant {
|
impl Constant {
|
||||||
pub fn to_atom(self) -> Option<ClauseName> {
|
pub fn to_atom(&self) -> Option<ClauseName> {
|
||||||
match self {
|
match self {
|
||||||
Constant::Atom(a, _) => Some(a.defrock_brackets()),
|
Constant::Atom(a, _) => Some(a.defrock_brackets()),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -575,7 +572,7 @@ impl Constant {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ClauseName {
|
pub enum ClauseName {
|
||||||
BuiltIn(&'static str),
|
BuiltIn(&'static str),
|
||||||
User(TabledRc<Atom>)
|
User(TabledRc<Atom>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ClauseName {
|
impl fmt::Display for ClauseName {
|
||||||
@@ -620,20 +617,22 @@ impl ClauseName {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn owning_module(&self) -> Self {
|
pub fn owning_module(&self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
&ClauseName::User(ref name) => {
|
ClauseName::User(ref name) => {
|
||||||
let module = name.owning_module();
|
let module = name.owning_module();
|
||||||
ClauseName::User(TabledRc { atom: module.clone(),
|
ClauseName::User(TabledRc {
|
||||||
table: TabledData::new(module) })
|
atom: module.clone(),
|
||||||
},
|
table: TabledData::new(module),
|
||||||
_ => clause_name!("user")
|
})
|
||||||
|
}
|
||||||
|
_ => clause_name!("user"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_rc(&self) -> Rc<String> {
|
pub fn to_rc(&self) -> Rc<String> {
|
||||||
match self {
|
match self {
|
||||||
&ClauseName::BuiltIn(s) => Rc::new(s.to_string()),
|
ClauseName::BuiltIn(s) => Rc::new(s.to_string()),
|
||||||
&ClauseName::User(ref rc) => rc.inner()
|
ClauseName::User(ref rc) => rc.inner(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,52 +659,46 @@ impl ClauseName {
|
|||||||
pub fn has_table_of(&self, other: &ClauseName) -> bool {
|
pub fn has_table_of(&self, other: &ClauseName) -> bool {
|
||||||
match self {
|
match self {
|
||||||
ClauseName::BuiltIn(_) => {
|
ClauseName::BuiltIn(_) => {
|
||||||
if let ClauseName::BuiltIn(_) = other {
|
matches!(other, ClauseName::BuiltIn(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClauseName::User(ref name) => {
|
|
||||||
other.has_table(&name.table)
|
|
||||||
}
|
}
|
||||||
|
ClauseName::User(ref name) => other.has_table(&name.table),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
&ClauseName::BuiltIn(s) => s,
|
ClauseName::BuiltIn(s) => s,
|
||||||
&ClauseName::User(ref name) => name.as_ref()
|
ClauseName::User(ref name) => name.as_ref(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_char(&self) -> bool {
|
pub fn is_char(&self) -> bool {
|
||||||
!self.as_str().is_empty() && self.as_str().chars().skip(1).next().is_none()
|
!self.as_str().is_empty() && self.as_str().chars().nth(1).is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn defrock_brackets(self) -> Self {
|
pub fn defrock_brackets(&self) -> Self {
|
||||||
fn defrock_brackets(s: &str) -> &str {
|
fn defrock_brackets(s: &str) -> &str {
|
||||||
if s.starts_with('(') && s.ends_with(')') {
|
if s.starts_with('(') && s.ends_with(')') {
|
||||||
&s[1 .. s.len() - 1]
|
&s[1..s.len() - 1]
|
||||||
} else {
|
} else {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
ClauseName::BuiltIn(s) =>
|
ClauseName::BuiltIn(s) => ClauseName::BuiltIn(defrock_brackets(s)),
|
||||||
ClauseName::BuiltIn(defrock_brackets(s)),
|
ClauseName::User(s) => {
|
||||||
ClauseName::User(s) =>
|
|
||||||
ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table))
|
ClauseName::User(tabled_rc!(defrock_brackets(s.as_str()).to_owned(), s.table))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<str> for ClauseName {
|
impl AsRef<str> for ClauseName {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(self: &Self) -> &str {
|
fn as_ref(&self) -> &str {
|
||||||
self.as_str()
|
self.as_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -713,41 +706,45 @@ impl AsRef<str> for ClauseName {
|
|||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
pub enum Term {
|
pub enum Term {
|
||||||
AnonVar,
|
AnonVar,
|
||||||
Clause(Cell<RegType>, ClauseName, Vec<Box<Term>>, Option<SharedOpDesc>),
|
Clause(
|
||||||
|
Cell<RegType>,
|
||||||
|
ClauseName,
|
||||||
|
Vec<Box<Term>>,
|
||||||
|
Option<SharedOpDesc>,
|
||||||
|
),
|
||||||
Cons(Cell<RegType>, Box<Term>, Box<Term>),
|
Cons(Cell<RegType>, Box<Term>, Box<Term>),
|
||||||
Constant(Cell<RegType>, Constant),
|
Constant(Cell<RegType>, Constant),
|
||||||
Var(Cell<VarReg>, Rc<Var>)
|
Var(Cell<VarReg>, Rc<Var>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Term {
|
impl Term {
|
||||||
pub fn shared_op_desc(&self) -> Option<SharedOpDesc> {
|
pub fn shared_op_desc(&self) -> Option<SharedOpDesc> {
|
||||||
match self {
|
match self {
|
||||||
&Term::Clause(_, _, _, ref spec) => spec.clone(),
|
Term::Clause(_, _, _, ref spec) => spec.clone(),
|
||||||
&Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(),
|
Term::Constant(_, Constant::Atom(_, ref spec)) => spec.clone(),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_constant(self) -> Option<Constant> {
|
pub fn into_constant(self) -> Option<Constant> {
|
||||||
match self {
|
match self {
|
||||||
Term::Constant(_, c) => Some(c),
|
Term::Constant(_, c) => Some(c),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn first_arg(&self) -> Option<&Term> {
|
pub fn first_arg(&self) -> Option<&Term> {
|
||||||
match self {
|
match self {
|
||||||
&Term::Clause(_, _, ref terms, _) =>
|
Term::Clause(_, _, ref terms, _) => terms.first().map(|bt| bt.as_ref()),
|
||||||
terms.first().map(|bt| bt.as_ref()),
|
_ => None,
|
||||||
_ => None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_name(&mut self, new_name: ClauseName) {
|
pub fn set_name(&mut self, new_name: ClauseName) {
|
||||||
match self {
|
match self {
|
||||||
Term::Constant(_, Constant::Atom(ref mut atom, _))
|
Term::Constant(_, Constant::Atom(ref mut atom, _))
|
||||||
| Term::Clause(_, ref mut atom, ..) => {
|
| Term::Clause(_, ref mut atom, ..) => {
|
||||||
*atom = new_name;
|
*atom = new_name;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -755,22 +752,23 @@ impl Term {
|
|||||||
|
|
||||||
pub fn name(&self) -> Option<ClauseName> {
|
pub fn name(&self) -> Option<ClauseName> {
|
||||||
match self {
|
match self {
|
||||||
&Term::Constant(_, Constant::Atom(ref atom, _))
|
&Term::Constant(_, Constant::Atom(ref atom, _)) | &Term::Clause(_, ref atom, ..) => {
|
||||||
| &Term::Clause(_, ref atom, ..) => Some(atom.clone()),
|
Some(atom.clone())
|
||||||
_ => None
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
|
Term::Clause(_, _, ref child_terms, ..) => child_terms.len(),
|
||||||
_ => 0
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> {
|
fn unfold_by_str_once(term: &mut Term, s: &str) -> Option<(Term, Term)> {
|
||||||
if let &mut Term::Clause(_, ref name, ref mut subterms, _) = term {
|
if let Term::Clause(_, ref name, ref mut subterms, _) = term {
|
||||||
if name.as_str() == s && subterms.len() == 2 {
|
if name.as_str() == s && subterms.len() == 2 {
|
||||||
let snd = *subterms.pop().unwrap();
|
let snd = *subterms.pop().unwrap();
|
||||||
let fst = *subterms.pop().unwrap();
|
let fst = *subterms.pop().unwrap();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::lexical::parse_lossy;
|
|
||||||
use crate::ordered_float::*;
|
|
||||||
use crate::rug::Integer;
|
use crate::rug::Integer;
|
||||||
|
use lexical::parse_lossy;
|
||||||
|
use ordered_float::*;
|
||||||
|
|
||||||
use ast::*;
|
use crate::ast::*;
|
||||||
use tabled_rc::*;
|
use crate::tabled_rc::*;
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -11,13 +11,13 @@ use std::io::Read;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
macro_rules! is_not_eof {
|
macro_rules! is_not_eof {
|
||||||
($c:expr) => (
|
($c:expr) => {
|
||||||
match $c {
|
match $c {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(ParserError::UnexpectedEOF) => return Ok(true),
|
Err($crate::ast::ParserError::UnexpectedEOF) => return Ok(true),
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! consume_chars_with {
|
macro_rules! consume_chars_with {
|
||||||
@@ -26,27 +26,27 @@ macro_rules! consume_chars_with {
|
|||||||
match $e {
|
match $e {
|
||||||
Ok(Some(c)) => $token.push(c),
|
Ok(Some(c)) => $token.push(c),
|
||||||
Ok(None) => continue,
|
Ok(None) => continue,
|
||||||
Err(ParserError::UnexpectedChar(..)) => break,
|
Err($crate::ast::ParserError::UnexpectedChar(..)) => break,
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
Constant(Constant),
|
Constant(Constant),
|
||||||
Var(Rc<Atom>),
|
Var(Rc<Atom>),
|
||||||
Open, // '('
|
Open, // '('
|
||||||
OpenCT, // '('
|
OpenCT, // '('
|
||||||
Close, // ')'
|
Close, // ')'
|
||||||
OpenList, // '['
|
OpenList, // '['
|
||||||
CloseList, // ']'
|
CloseList, // ']'
|
||||||
OpenCurly, // '{'
|
OpenCurly, // '{'
|
||||||
CloseCurly, // '}'
|
CloseCurly, // '}'
|
||||||
HeadTailSeparator, // '|'
|
HeadTailSeparator, // '|'
|
||||||
Comma, // ','
|
Comma, // ','
|
||||||
End
|
End,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Lexer<'a, R: Read> {
|
pub struct Lexer<'a, R: Read> {
|
||||||
@@ -54,17 +54,17 @@ pub struct Lexer<'a, R: Read> {
|
|||||||
pub(crate) reader: &'a mut ParsingStream<R>,
|
pub(crate) reader: &'a mut ParsingStream<R>,
|
||||||
pub(crate) flags: MachineFlags,
|
pub(crate) flags: MachineFlags,
|
||||||
pub(crate) line_num: usize,
|
pub(crate) line_num: usize,
|
||||||
pub(crate) col_num: usize
|
pub(crate) col_num: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: Read + fmt::Debug> fmt::Debug for Lexer<'a, R> {
|
impl<'a, R: Read + fmt::Debug> fmt::Debug for Lexer<'a, R> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Lexer")
|
f.debug_struct("Lexer")
|
||||||
.field("atom_tbl", &self.atom_tbl)
|
.field("atom_tbl", &self.atom_tbl)
|
||||||
.field("reader", &"&'a mut ParsingStream<R>") // Hacky solution.
|
.field("reader", &"&'a mut ParsingStream<R>") // Hacky solution.
|
||||||
.field("line_num", &self.line_num)
|
.field("line_num", &self.line_num)
|
||||||
.field("col_num", &self.col_num)
|
.field("col_num", &self.col_num)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,13 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
src: &'a mut ParsingStream<R>,
|
src: &'a mut ParsingStream<R>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Lexer { atom_tbl, flags, reader: src, line_num: 0, col_num: 0 }
|
Lexer {
|
||||||
|
atom_tbl,
|
||||||
|
flags,
|
||||||
|
reader: src,
|
||||||
|
line_num: 0,
|
||||||
|
col_num: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_char(&mut self, c: char) {
|
fn return_char(&mut self, c: char) {
|
||||||
@@ -128,8 +134,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_line_comment(&mut self) -> Result<(), ParserError>
|
fn single_line_comment(&mut self) -> Result<(), ParserError> {
|
||||||
{
|
|
||||||
loop {
|
loop {
|
||||||
if self.reader.peek().is_none() || new_line_char!(self.skip_char()?) {
|
if self.reader.peek().is_none() || new_line_char!(self.skip_char()?) {
|
||||||
break;
|
break;
|
||||||
@@ -229,8 +234,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_single_quoted_item(&mut self) -> Result<Option<char>, ParserError>
|
fn get_single_quoted_item(&mut self) -> Result<Option<char>, ParserError> {
|
||||||
{
|
|
||||||
if backslash_char!(self.lookahead_char()?) {
|
if backslash_char!(self.lookahead_char()?) {
|
||||||
let c = self.skip_char()?;
|
let c = self.skip_char()?;
|
||||||
|
|
||||||
@@ -264,14 +268,13 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_double_quoted_item(&mut self) -> Result<Option<char>, ParserError>
|
fn get_double_quoted_item(&mut self) -> Result<Option<char>, ParserError> {
|
||||||
{
|
|
||||||
if backslash_char!(self.lookahead_char()?) {
|
if backslash_char!(self.lookahead_char()?) {
|
||||||
let c = self.skip_char()?;
|
let c = self.skip_char()?;
|
||||||
|
|
||||||
if new_line_char!(self.lookahead_char()?) {
|
if new_line_char!(self.lookahead_char()?) {
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
return Ok(None)
|
return Ok(None);
|
||||||
} else {
|
} else {
|
||||||
self.return_char(c);
|
self.return_char(c);
|
||||||
}
|
}
|
||||||
@@ -299,8 +302,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_control_escape_sequence(&mut self) -> Result<char, ParserError>
|
fn get_control_escape_sequence(&mut self) -> Result<char, ParserError> {
|
||||||
{
|
|
||||||
let escaped = match self.lookahead_char()? {
|
let escaped = match self.lookahead_char()? {
|
||||||
'a' => '\u{07}', // UTF-8 alert
|
'a' => '\u{07}', // UTF-8 alert
|
||||||
'b' => '\u{08}', // UTF-8 backspace
|
'b' => '\u{08}', // UTF-8 backspace
|
||||||
@@ -309,20 +311,18 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
't' => '\t',
|
't' => '\t',
|
||||||
'n' => '\n',
|
'n' => '\n',
|
||||||
'r' => '\r',
|
'r' => '\r',
|
||||||
c => return Err(ParserError::UnexpectedChar(c, self.line_num, self.col_num))
|
c => return Err(ParserError::UnexpectedChar(c, self.line_num, self.col_num)),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
return Ok(escaped);
|
return Ok(escaped);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_octal_escape_sequence(&mut self) -> Result<char, ParserError>
|
fn get_octal_escape_sequence(&mut self) -> Result<char, ParserError> {
|
||||||
{
|
|
||||||
self.escape_sequence_to_char(|c| octal_digit_char!(c), 8)
|
self.escape_sequence_to_char(|c| octal_digit_char!(c), 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_hexadecimal_escape_sequence(&mut self) -> Result<char, ParserError>
|
fn get_hexadecimal_escape_sequence(&mut self) -> Result<char, ParserError> {
|
||||||
{
|
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
let c = self.lookahead_char()?;
|
let c = self.lookahead_char()?;
|
||||||
|
|
||||||
@@ -354,12 +354,13 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
|
|
||||||
if backslash_char!(c) {
|
if backslash_char!(c) {
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
u32::from_str_radix(&token, radix)
|
u32::from_str_radix(&token, radix).map_or_else(
|
||||||
.map_or_else(
|
|_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)),
|
||||||
|_| Err(ParserError::ParseBigInt(self.line_num, self.col_num)),
|
|n| {
|
||||||
|n| char::try_from(n)
|
char::try_from(n)
|
||||||
.map_err(|_| ParserError::Utf8Error(self.line_num, self.col_num))
|
.map_err(|_| ParserError::Utf8Error(self.line_num, self.col_num))
|
||||||
)
|
},
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// on failure, restore the token characters and backslash.
|
// on failure, restore the token characters and backslash.
|
||||||
self.reader.put_back_all(token.chars().map(Ok));
|
self.reader.put_back_all(token.chars().map(Ok));
|
||||||
@@ -423,11 +424,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
Integer::from_str_radix(&token, 16)
|
Integer::from_str_radix(&token, 16)
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.line_num,
|
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.return_char('x');
|
self.return_char('x');
|
||||||
@@ -449,11 +447,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
Integer::from_str_radix(&token, 8)
|
Integer::from_str_radix(&token, 8)
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.line_num,
|
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.return_char('o');
|
self.return_char('o');
|
||||||
@@ -475,11 +470,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
Integer::from_str_radix(&token, 2)
|
Integer::from_str_radix(&token, 2)
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.line_num,
|
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.return_char('b');
|
self.return_char('b');
|
||||||
@@ -525,18 +517,20 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
if single_quote_char!(self.lookahead_char()?) {
|
if single_quote_char!(self.lookahead_char()?) {
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
|
|
||||||
if !token.is_empty() && token.chars().skip(1).next().is_none() {
|
if !token.is_empty() && token.chars().nth(1).is_none() {
|
||||||
if let Some(c) = token.chars().next() {
|
if let Some(c) = token.chars().next() {
|
||||||
return Ok(Token::Constant(Constant::Char(c)));
|
return Ok(Token::Constant(Constant::Char(c)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ParserError::InvalidSingleQuotedCharacter(self.lookahead_char()?))
|
return Err(ParserError::InvalidSingleQuotedCharacter(
|
||||||
|
self.lookahead_char()?,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match self.get_back_quoted_string() {
|
match self.get_back_quoted_string() {
|
||||||
Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)),
|
Ok(_) => return Err(ParserError::BackQuotedString(self.line_num, self.col_num)),
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,12 +569,10 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
isize::from_str_radix(&token, 10)
|
isize::from_str_radix(&token, 10)
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token.parse::<Integer>()
|
token
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.parse::<Integer>()
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
self.line_num,
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
} else if decimal_digit_char!(self.lookahead_char()?) {
|
} else if decimal_digit_char!(self.lookahead_char()?) {
|
||||||
token.push('.');
|
token.push('.');
|
||||||
@@ -599,7 +591,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
|
|
||||||
let c = match self.lookahead_char() {
|
let c = match self.lookahead_char() {
|
||||||
Err(_) => return Ok(self.vacate_with_float(token)),
|
Err(_) => return Ok(self.vacate_with_float(token)),
|
||||||
Ok(c) => c
|
Ok(c) => c,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !sign_char!(c) && !decimal_digit_char!(c) {
|
if !sign_char!(c) && !decimal_digit_char!(c) {
|
||||||
@@ -613,8 +605,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.return_char(token.pop().unwrap());
|
self.return_char(token.pop().unwrap());
|
||||||
return Ok(self.vacate_with_float(token));
|
return Ok(self.vacate_with_float(token));
|
||||||
},
|
}
|
||||||
Ok(c) => c
|
Ok(c) => c,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !decimal_digit_char!(c) {
|
if !decimal_digit_char!(c) {
|
||||||
@@ -645,70 +637,65 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
isize::from_str_radix(&token, 10)
|
isize::from_str_radix(&token, 10)
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token.parse::<Integer>()
|
token
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.parse::<Integer>()
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
self.line_num,
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if token.starts_with('0') && token.len() == 1 {
|
if token.starts_with('0') && token.len() == 1 {
|
||||||
if c == 'x' {
|
if c == 'x' {
|
||||||
self.hexadecimal_constant()
|
self.hexadecimal_constant().or_else(|e| {
|
||||||
.or_else(|e| {
|
if let ParserError::ParseBigInt(..) = e {
|
||||||
if let ParserError::ParseBigInt(..) = e {
|
isize::from_str_radix(&token, 10)
|
||||||
isize::from_str_radix(&token, 10)
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.or_else(|_| {
|
||||||
.or_else(|_| {
|
token
|
||||||
token.parse::<Integer>()
|
.parse::<Integer>()
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map_err(|_| {
|
||||||
self.line_num,
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
self.col_num,
|
})
|
||||||
))
|
})
|
||||||
})
|
} else {
|
||||||
} else {
|
Err(e)
|
||||||
Err(e)
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
} else if c == 'o' {
|
} else if c == 'o' {
|
||||||
self.octal_constant()
|
self.octal_constant().or_else(|e| {
|
||||||
.or_else(|e| {
|
if let ParserError::ParseBigInt(..) = e {
|
||||||
if let ParserError::ParseBigInt(..) = e {
|
isize::from_str_radix(&token, 10)
|
||||||
isize::from_str_radix(&token, 10)
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.or_else(|_| {
|
||||||
.or_else(|_| {
|
token
|
||||||
token.parse::<Integer>()
|
.parse::<Integer>()
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map_err(|_| {
|
||||||
self.line_num,
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
self.col_num,
|
})
|
||||||
))
|
})
|
||||||
})
|
} else {
|
||||||
} else {
|
Err(e)
|
||||||
Err(e)
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
} else if c == 'b' {
|
} else if c == 'b' {
|
||||||
self.binary_constant()
|
self.binary_constant().or_else(|e| {
|
||||||
.or_else(|e| {
|
if let ParserError::ParseBigInt(..) = e {
|
||||||
if let ParserError::ParseBigInt(..) = e {
|
isize::from_str_radix(&token, 10)
|
||||||
isize::from_str_radix(&token, 10)
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.or_else(|_| {
|
||||||
.or_else(|_| {
|
token
|
||||||
token.parse::<Integer>()
|
.parse::<Integer>()
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map_err(|_| {
|
||||||
self.line_num,
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
self.col_num,
|
})
|
||||||
))
|
})
|
||||||
})
|
} else {
|
||||||
} else {
|
Err(e)
|
||||||
Err(e)
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
} else if single_quote_char!(c) {
|
} else if single_quote_char!(c) {
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
|
|
||||||
@@ -726,45 +713,39 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.get_single_quoted_char()
|
self.get_single_quoted_char()
|
||||||
.and_then(|c| {
|
.map(|c| Token::Constant(Constant::Fixnum(c as isize)))
|
||||||
Ok(Token::Constant(Constant::Fixnum(c as isize)))
|
|
||||||
})
|
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
self.return_char(c);
|
self.return_char(c);
|
||||||
|
|
||||||
isize::from_str_radix(&token, 10)
|
isize::from_str_radix(&token, 10)
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token.parse::<Integer>()
|
token
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.parse::<Integer>()
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
self.line_num,
|
.map_err(|_| {
|
||||||
self.col_num,
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
))
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
isize::from_str_radix(&token, 10)
|
isize::from_str_radix(&token, 10)
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token.parse::<Integer>()
|
token
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.parse::<Integer>()
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
self.line_num,
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isize::from_str_radix(&token, 10)
|
isize::from_str_radix(&token, 10)
|
||||||
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
.map(|n| Token::Constant(Constant::Fixnum(n)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token.parse::<Integer>()
|
token
|
||||||
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
.parse::<Integer>()
|
||||||
.map_err(|_| ParserError::ParseBigInt(
|
.map(|n| Token::Constant(Constant::Integer(Rc::new(n))))
|
||||||
self.line_num,
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
self.col_num,
|
|
||||||
))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -781,18 +762,19 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
Ok(c) if layout_char!(c) || new_line_char!(c) => {
|
Ok(c) if layout_char!(c) || new_line_char!(c) => {
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
layout_inserted = true;
|
layout_inserted = true;
|
||||||
},
|
}
|
||||||
Ok(c) if end_line_comment_char!(c) => {
|
Ok(c) if end_line_comment_char!(c) => {
|
||||||
self.single_line_comment()?;
|
self.single_line_comment()?;
|
||||||
layout_inserted = true;
|
layout_inserted = true;
|
||||||
},
|
}
|
||||||
Ok(c) if comment_1_char!(c) =>
|
Ok(c) if comment_1_char!(c) => {
|
||||||
if self.bracketed_comment()? {
|
if self.bracketed_comment()? {
|
||||||
layout_inserted = true;
|
layout_inserted = true;
|
||||||
} else {
|
} else {
|
||||||
more_layout = false;
|
more_layout = false;
|
||||||
},
|
}
|
||||||
_ => more_layout = false
|
}
|
||||||
|
_ => more_layout = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !more_layout {
|
if !more_layout {
|
||||||
@@ -825,8 +807,11 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
|
|
||||||
if c == '(' {
|
if c == '(' {
|
||||||
self.skip_char()?;
|
self.skip_char()?;
|
||||||
return Ok(if layout_inserted { Token::Open }
|
return Ok(if layout_inserted {
|
||||||
else { Token::OpenCT });
|
Token::Open
|
||||||
|
} else {
|
||||||
|
Token::OpenCT
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if c == '.' {
|
if c == '.' {
|
||||||
@@ -839,7 +824,7 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Ok(Token::End);
|
return Ok(Token::End);
|
||||||
},
|
}
|
||||||
Err(ParserError::UnexpectedEOF) => {
|
Err(ParserError::UnexpectedEOF) => {
|
||||||
return Ok(Token::End);
|
return Ok(Token::End);
|
||||||
}
|
}
|
||||||
@@ -891,8 +876,8 @@ impl<'a, R: Read> Lexer<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.name_token(c)
|
self.name_token(c)
|
||||||
},
|
}
|
||||||
Err(e) => Err(e)
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
extern crate lexical;
|
|
||||||
extern crate ordered_float;
|
|
||||||
#[cfg(feature = "rug")]
|
|
||||||
extern crate rug;
|
|
||||||
#[cfg(feature = "num-rug-adapter")]
|
#[cfg(feature = "num-rug-adapter")]
|
||||||
extern crate num_rug_adapter as rug;
|
use num_rug_adapter as rug;
|
||||||
extern crate unicode_reader;
|
#[cfg(feature = "rug")]
|
||||||
|
use rug;
|
||||||
|
|
||||||
#[macro_use] pub mod tabled_rc;
|
#[macro_use]
|
||||||
#[macro_use] pub mod ast;
|
pub mod tabled_rc;
|
||||||
#[macro_use] pub mod macros;
|
#[macro_use]
|
||||||
|
pub mod ast;
|
||||||
|
#[macro_use]
|
||||||
|
pub mod macros;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod put_back_n;
|
pub mod put_back_n;
|
||||||
|
|
||||||
|
|||||||
@@ -1,187 +1,246 @@
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! char_class {
|
macro_rules! char_class {
|
||||||
($c: expr, [$head:expr]) => ($c == $head);
|
($c: expr, [$head:expr]) => ($c == $head);
|
||||||
($c: expr, [$head:expr $(, $cs:expr)+]) => ($c == $head || char_class!($c, [$($cs),*]));
|
($c: expr, [$head:expr $(, $cs:expr)+]) => ($c == $head || $crate::char_class!($c, [$($cs),*]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! symbolic_control_char {
|
macro_rules! symbolic_control_char {
|
||||||
($c: expr) => (char_class!($c, ['a', 'b', 'f', 'n', 'r', 't', 'v', '0']))
|
($c: expr) => {
|
||||||
|
$crate::char_class!($c, ['a', 'b', 'f', 'n', 'r', 't', 'v', '0'])
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! space_char {
|
macro_rules! space_char {
|
||||||
($c: expr) => ($c == ' ')
|
($c: expr) => {
|
||||||
|
$c == ' '
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! layout_char {
|
macro_rules! layout_char {
|
||||||
($c: expr) => (char_class!($c, [' ', '\n', '\t', '\u{0B}', '\u{0C}']))
|
($c: expr) => {
|
||||||
|
$crate::char_class!($c, [' ', '\n', '\t', '\u{0B}', '\u{0C}'])
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! symbolic_hexadecimal_char {
|
macro_rules! symbolic_hexadecimal_char {
|
||||||
($c: expr) => ($c == 'x')
|
($c: expr) => {
|
||||||
|
$c == 'x'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! octal_digit_char {
|
macro_rules! octal_digit_char {
|
||||||
($c: expr) => ($c >= '0' && $c <= '7')
|
($c: expr) => {
|
||||||
|
('0'..='7').contains(&$c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! binary_digit_char {
|
macro_rules! binary_digit_char {
|
||||||
($c: expr) => ($c >= '0' && $c <= '1')
|
($c: expr) => {
|
||||||
|
$c >= '0' && $c <= '1'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! hexadecimal_digit_char {
|
macro_rules! hexadecimal_digit_char {
|
||||||
($c: expr) => ($c >= '0' && $c <= '9' ||
|
($c: expr) => {
|
||||||
$c >= 'A' && $c <= 'F' ||
|
('0'..='9').contains(&$c) || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c)
|
||||||
$c >= 'a' && $c <= 'f')
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! exponent_char {
|
macro_rules! exponent_char {
|
||||||
($c: expr) => ($c == 'e' || $c == 'E')
|
($c: expr) => {
|
||||||
|
$c == 'e' || $c == 'E'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sign_char {
|
macro_rules! sign_char {
|
||||||
($c: expr) => ($c == '-' || $c == '+')
|
($c: expr) => {
|
||||||
|
$c == '-' || $c == '+'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! new_line_char {
|
macro_rules! new_line_char {
|
||||||
($c: expr) => ($c == '\n')
|
($c: expr) => {
|
||||||
|
$c == '\n'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! end_line_comment_char {
|
macro_rules! end_line_comment_char {
|
||||||
($c: expr) => ($c == '%')
|
($c: expr) => {
|
||||||
|
$c == '%'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! comment_1_char {
|
macro_rules! comment_1_char {
|
||||||
($c: expr) => ($c == '/')
|
($c: expr) => {
|
||||||
|
$c == '/'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! comment_2_char {
|
macro_rules! comment_2_char {
|
||||||
($c: expr) => ($c == '*')
|
($c: expr) => {
|
||||||
|
$c == '*'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! capital_letter_char {
|
macro_rules! capital_letter_char {
|
||||||
($c: expr) => ($c >= 'A' && $c <= 'Z')
|
($c: expr) => {
|
||||||
|
('A'..='Z').contains(&$c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! small_letter_char {
|
macro_rules! small_letter_char {
|
||||||
($c: expr) => ($c >= 'a' && $c <= 'z')
|
($c: expr) => {
|
||||||
|
('a'..='z').contains(&$c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! variable_indicator_char {
|
macro_rules! variable_indicator_char {
|
||||||
($c: expr) => ($c == '_')
|
($c: expr) => {
|
||||||
|
$c == '_'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! graphic_char {
|
macro_rules! graphic_char {
|
||||||
($c: expr) => (char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':',
|
($c: expr) => ($crate::char_class!($c, ['#', '$', '&', '*', '+', '-', '.', '/', ':',
|
||||||
'<', '=', '>', '?', '@', '^', '~']))
|
'<', '=', '>', '?', '@', '^', '~']))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! graphic_token_char {
|
macro_rules! graphic_token_char {
|
||||||
($c: expr) => (graphic_char!($c) || backslash_char!($c))
|
($c: expr) => {
|
||||||
|
$crate::graphic_char!($c) || $crate::backslash_char!($c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! alpha_char {
|
macro_rules! alpha_char {
|
||||||
($c: expr) =>
|
($c: expr) => {
|
||||||
(match $c {
|
match $c {
|
||||||
'a' ..= 'z' => true,
|
'a'..='z' => true,
|
||||||
'A' ..= 'Z' => true,
|
'A'..='Z' => true,
|
||||||
'_' => true,
|
'_' => true,
|
||||||
'\u{00A0}' ..= '\u{00BF}' => true,
|
'\u{00A0}'..='\u{00BF}' => true,
|
||||||
'\u{00C0}' ..= '\u{00D6}' => true,
|
'\u{00C0}'..='\u{00D6}' => true,
|
||||||
'\u{00D8}' ..= '\u{00F6}' => true,
|
'\u{00D8}'..='\u{00F6}' => true,
|
||||||
'\u{00F8}' ..= '\u{00FF}' => true,
|
'\u{00F8}'..='\u{00FF}' => true,
|
||||||
'\u{0100}' ..= '\u{017F}' => true, // Latin Extended-A
|
'\u{0100}'..='\u{017F}' => true, // Latin Extended-A
|
||||||
'\u{0180}' ..= '\u{024F}' => true, // Latin Extended-B
|
'\u{0180}'..='\u{024F}' => true, // Latin Extended-B
|
||||||
'\u{0250}' ..= '\u{02AF}' => true, // IPA Extensions
|
'\u{0250}'..='\u{02AF}' => true, // IPA Extensions
|
||||||
'\u{02B0}' ..= '\u{02FF}' => true, // Spacing Modifier Letters
|
'\u{02B0}'..='\u{02FF}' => true, // Spacing Modifier Letters
|
||||||
'\u{0300}' ..= '\u{036F}' => true, // Combining Diacritical Marks
|
'\u{0300}'..='\u{036F}' => true, // Combining Diacritical Marks
|
||||||
'\u{0370}' ..= '\u{03FF}' => true, // Greek/Coptic
|
'\u{0370}'..='\u{03FF}' => true, // Greek/Coptic
|
||||||
'\u{0400}' ..= '\u{04FF}' => true, // Cyrillic
|
'\u{0400}'..='\u{04FF}' => true, // Cyrillic
|
||||||
'\u{0500}' ..= '\u{052F}' => true, // Cyrillic Supplement
|
'\u{0500}'..='\u{052F}' => true, // Cyrillic Supplement
|
||||||
'\u{0530}' ..= '\u{058F}' => true, // Armenian
|
'\u{0530}'..='\u{058F}' => true, // Armenian
|
||||||
'\u{0590}' ..= '\u{05FF}' => true, // Hebrew
|
'\u{0590}'..='\u{05FF}' => true, // Hebrew
|
||||||
'\u{0600}' ..= '\u{06FF}' => true, // Arabic
|
'\u{0600}'..='\u{06FF}' => true, // Arabic
|
||||||
'\u{0700}' ..= '\u{074F}' => true, // Syriac
|
'\u{0700}'..='\u{074F}' => true, // Syriac
|
||||||
_ => false
|
_ => false,
|
||||||
})
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! decimal_digit_char {
|
macro_rules! decimal_digit_char {
|
||||||
($c: expr) => ($c >= '0' && $c <= '9')
|
($c: expr) => {
|
||||||
|
('0'..='9').contains(&$c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! decimal_point_char {
|
macro_rules! decimal_point_char {
|
||||||
($c: expr) => ($c == '.')
|
($c: expr) => {
|
||||||
|
$c == '.'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! alpha_numeric_char {
|
macro_rules! alpha_numeric_char {
|
||||||
($c: expr) => (alpha_char!($c) || decimal_digit_char!($c))
|
($c: expr) => {
|
||||||
|
$crate::alpha_char!($c) || $crate::decimal_digit_char!($c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! cut_char {
|
macro_rules! cut_char {
|
||||||
($c: expr) => ($c == '!')
|
($c: expr) => {
|
||||||
|
$c == '!'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! semicolon_char {
|
macro_rules! semicolon_char {
|
||||||
($c: expr) => ($c == ';')
|
($c: expr) => {
|
||||||
|
$c == ';'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! backslash_char {
|
macro_rules! backslash_char {
|
||||||
($c: expr) => ($c == '\\')
|
($c: expr) => {
|
||||||
|
$c == '\\'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! single_quote_char {
|
macro_rules! single_quote_char {
|
||||||
($c: expr) => ($c == '\'')
|
($c: expr) => {
|
||||||
|
$c == '\''
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! double_quote_char {
|
macro_rules! double_quote_char {
|
||||||
($c: expr) => ($c == '"')
|
($c: expr) => {
|
||||||
|
$c == '"'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! back_quote_char {
|
macro_rules! back_quote_char {
|
||||||
($c: expr) => ($c == '`')
|
($c: expr) => {
|
||||||
|
$c == '`'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! meta_char {
|
macro_rules! meta_char {
|
||||||
($c: expr) => ( char_class!($c, ['\\', '\'', '"', '`']) )
|
($c: expr) => {
|
||||||
|
$crate::char_class!($c, ['\\', '\'', '"', '`'])
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! solo_char {
|
macro_rules! solo_char {
|
||||||
($c: expr) => ( char_class!($c, ['!', '(', ')', ',', ';', '[', ']',
|
($c: expr) => {
|
||||||
'{', '}', '|', '%']) )
|
$crate::char_class!($c, ['!', '(', ')', ',', ';', '[', ']', '{', '}', '|', '%'])
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! prolog_char {
|
macro_rules! prolog_char {
|
||||||
($c: expr) => (graphic_char!($c) || alpha_numeric_char!($c) || solo_char!($c) ||
|
($c: expr) => {
|
||||||
layout_char!($c) || meta_char!($c))
|
$crate::graphic_char!($c)
|
||||||
|
|| $crate::alpha_numeric_char!($c)
|
||||||
|
|| $crate::solo_char!($c)
|
||||||
|
|| $crate::layout_char!($c)
|
||||||
|
|| $crate::meta_char!($c)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use ast::*;
|
use crate::ast::*;
|
||||||
use lexer::*;
|
use crate::lexer::*;
|
||||||
use tabled_rc::*;
|
use crate::tabled_rc::*;
|
||||||
|
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use rug::ops::NegAssign;
|
use crate::rug::ops::NegAssign;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@@ -16,25 +16,30 @@ enum TokenType {
|
|||||||
Term,
|
Term,
|
||||||
Open,
|
Open,
|
||||||
OpenCT,
|
OpenCT,
|
||||||
OpenList, // '['
|
OpenList, // '['
|
||||||
OpenCurly, // '{'
|
OpenCurly, // '{'
|
||||||
HeadTailSeparator, // '|'
|
HeadTailSeparator, // '|'
|
||||||
Comma, // ','
|
Comma, // ','
|
||||||
Close,
|
Close,
|
||||||
CloseList, // ']'
|
CloseList, // ']'
|
||||||
CloseCurly, // '}'
|
CloseCurly, // '}'
|
||||||
End
|
End,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenType {
|
impl TokenType {
|
||||||
fn is_sep(self) -> bool {
|
fn is_sep(self) -> bool {
|
||||||
match self {
|
matches!(
|
||||||
TokenType::HeadTailSeparator | TokenType::OpenCT | TokenType::Open |
|
self,
|
||||||
TokenType::Close | TokenType::OpenList | TokenType::CloseList |
|
TokenType::HeadTailSeparator
|
||||||
TokenType::OpenCurly | TokenType::CloseCurly | TokenType::Comma
|
| TokenType::OpenCT
|
||||||
=> true,
|
| TokenType::Open
|
||||||
_ => false
|
| TokenType::Close
|
||||||
}
|
| TokenType::OpenList
|
||||||
|
| TokenType::CloseList
|
||||||
|
| TokenType::OpenCurly
|
||||||
|
| TokenType::CloseCurly
|
||||||
|
| TokenType::Comma
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,12 +47,14 @@ impl TokenType {
|
|||||||
struct TokenDesc {
|
struct TokenDesc {
|
||||||
tt: TokenType,
|
tt: TokenType,
|
||||||
priority: usize,
|
priority: usize,
|
||||||
spec: u32
|
spec: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub
|
pub fn get_clause_spec(
|
||||||
fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> Option<SharedOpDesc>
|
name: ClauseName,
|
||||||
{
|
arity: usize,
|
||||||
|
op_dir: &CompositeOpDir,
|
||||||
|
) -> Option<SharedOpDesc> {
|
||||||
match arity {
|
match arity {
|
||||||
1 => {
|
1 => {
|
||||||
/* This is a clause with an operator principal functor. Prefix operators
|
/* This is a clause with an operator principal functor. Prefix operators
|
||||||
@@ -60,20 +67,25 @@ fn get_clause_spec(name: ClauseName, arity: usize, op_dir: &CompositeOpDir) -> O
|
|||||||
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::Post) {
|
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::Post) {
|
||||||
return Some(cell.clone());
|
return Some(cell.clone());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
2 =>
|
2 => {
|
||||||
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::In) {
|
if let Some(OpDirValue(cell)) = op_dir.get(name, Fixity::In) {
|
||||||
return Some(cell.clone());
|
return Some(cell.clone());
|
||||||
},
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc>
|
pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc> {
|
||||||
{
|
let mut op_desc = OpDesc {
|
||||||
let mut op_desc = OpDesc { pre: 0, inf: 0, post: 0, spec: 0 };
|
pre: 0,
|
||||||
|
inf: 0,
|
||||||
|
post: 0,
|
||||||
|
spec: 0,
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(OpDirValue(cell)) = op_dir.get(name.clone(), Fixity::Pre) {
|
if let Some(OpDirValue(cell)) = op_dir.get(name.clone(), Fixity::Pre) {
|
||||||
let (pri, spec) = cell.get();
|
let (pri, spec) = cell.get();
|
||||||
@@ -111,8 +123,7 @@ pub fn get_op_desc(name: ClauseName, op_dir: &CompositeOpDir) -> Option<OpDesc>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool
|
fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool {
|
||||||
{
|
|
||||||
d2.priority <= priority
|
d2.priority <= priority
|
||||||
&& is_term!(d3.spec)
|
&& is_term!(d3.spec)
|
||||||
&& is_term!(d1.spec)
|
&& is_term!(d1.spec)
|
||||||
@@ -120,18 +131,15 @@ fn affirm_xfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b
|
|||||||
&& d1.priority < d2.priority
|
&& d1.priority < d2.priority
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affirm_yfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool
|
fn affirm_yfx(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool {
|
||||||
{
|
|
||||||
d2.priority <= priority
|
d2.priority <= priority
|
||||||
&& ((is_term!(d3.spec) && d3.priority < d2.priority)
|
&& ((is_term!(d3.spec) && d3.priority < d2.priority)
|
||||||
|| (is_lterm!(d3.spec) && d3.priority == d2.priority))
|
|| (is_lterm!(d3.spec) && d3.priority == d2.priority))
|
||||||
&& is_term!(d1.spec)
|
&& is_term!(d1.spec)
|
||||||
&& d1.priority < d2.priority
|
&& d1.priority < d2.priority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool {
|
||||||
fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> bool
|
|
||||||
{
|
|
||||||
d2.priority < priority
|
d2.priority < priority
|
||||||
&& is_term!(d3.spec)
|
&& is_term!(d3.spec)
|
||||||
&& d3.priority < d2.priority
|
&& d3.priority < d2.priority
|
||||||
@@ -139,49 +147,35 @@ fn affirm_xfy(priority: usize, d2: TokenDesc, d3: TokenDesc, d1: TokenDesc) -> b
|
|||||||
&& d1.priority <= d2.priority
|
&& d1.priority <= d2.priority
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affirm_yf(d1: TokenDesc, d2: TokenDesc) -> bool
|
fn affirm_yf(d1: TokenDesc, d2: TokenDesc) -> bool {
|
||||||
{
|
|
||||||
let is_valid_lterm = is_lterm!(d2.spec) && d2.priority == d1.priority;
|
let is_valid_lterm = is_lterm!(d2.spec) && d2.priority == d1.priority;
|
||||||
(is_term!(d2.spec) && d2.priority < d1.priority) || is_valid_lterm
|
(is_term!(d2.spec) && d2.priority < d1.priority) || is_valid_lterm
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affirm_xf(d1: TokenDesc, d2: TokenDesc) -> bool
|
fn affirm_xf(d1: TokenDesc, d2: TokenDesc) -> bool {
|
||||||
{
|
|
||||||
is_term!(d2.spec) && d2.priority < d1.priority
|
is_term!(d2.spec) && d2.priority < d1.priority
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affirm_fy(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool
|
fn affirm_fy(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool {
|
||||||
{
|
|
||||||
d2.priority < priority && is_term!(d1.spec) && d1.priority <= d2.priority
|
d2.priority < priority && is_term!(d1.spec) && d1.priority <= d2.priority
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affirm_fx(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool
|
fn affirm_fx(priority: usize, d1: TokenDesc, d2: TokenDesc) -> bool {
|
||||||
{
|
|
||||||
d2.priority <= priority && is_term!(d1.spec) && d1.priority < d2.priority
|
d2.priority <= priority && is_term!(d1.spec) && d1.priority < d2.priority
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sep_to_atom(tt: TokenType) -> Option<ClauseName>
|
fn sep_to_atom(tt: TokenType) -> Option<ClauseName> {
|
||||||
{
|
|
||||||
match tt {
|
match tt {
|
||||||
TokenType::Open | TokenType::OpenCT =>
|
TokenType::Open | TokenType::OpenCT => Some(clause_name!("(")),
|
||||||
Some(clause_name!("(")),
|
TokenType::Close => Some(clause_name!(")")),
|
||||||
TokenType::Close =>
|
TokenType::OpenList => Some(clause_name!("[")),
|
||||||
Some(clause_name!(")")),
|
TokenType::CloseList => Some(clause_name!("]")),
|
||||||
TokenType::OpenList =>
|
TokenType::OpenCurly => Some(clause_name!("{")),
|
||||||
Some(clause_name!("[")),
|
TokenType::CloseCurly => Some(clause_name!("}")),
|
||||||
TokenType::CloseList =>
|
TokenType::HeadTailSeparator => Some(clause_name!("|")),
|
||||||
Some(clause_name!("]")),
|
TokenType::Comma => Some(clause_name!(",")),
|
||||||
TokenType::OpenCurly =>
|
TokenType::End => Some(clause_name!(".")),
|
||||||
Some(clause_name!("{")),
|
_ => None,
|
||||||
TokenType::CloseCurly =>
|
|
||||||
Some(clause_name!("}")),
|
|
||||||
TokenType::HeadTailSeparator =>
|
|
||||||
Some(clause_name!("|")),
|
|
||||||
TokenType::Comma =>
|
|
||||||
Some(clause_name!(",")),
|
|
||||||
TokenType::End =>
|
|
||||||
Some(clause_name!(".")),
|
|
||||||
_ => None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +184,7 @@ pub struct OpDesc {
|
|||||||
pub pre: usize,
|
pub pre: usize,
|
||||||
pub inf: usize,
|
pub inf: usize,
|
||||||
pub post: usize,
|
pub post: usize,
|
||||||
pub spec: Specifier
|
pub spec: Specifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -201,8 +195,7 @@ pub struct Parser<'a, R: Read> {
|
|||||||
terms: Vec<Term>,
|
terms: Vec<Term>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_tokens<'a, R: Read>(lexer: &mut Lexer<'a, R>) -> Result<Vec<Token>, ParserError>
|
fn read_tokens<R: Read>(lexer: &mut Lexer<R>) -> Result<Vec<Token>, ParserError> {
|
||||||
{
|
|
||||||
let mut tokens = vec![];
|
let mut tokens = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@@ -227,10 +220,12 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
atom_tbl: TabledData<Atom>,
|
atom_tbl: TabledData<Atom>,
|
||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Parser { lexer: Lexer::new(atom_tbl, flags, stream),
|
Parser {
|
||||||
tokens: vec![],
|
lexer: Lexer::new(atom_tbl, flags, stream),
|
||||||
stack: Vec::new(),
|
tokens: vec![],
|
||||||
terms: Vec::new() }
|
stack: Vec::new(),
|
||||||
|
terms: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -255,50 +250,46 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
fn get_term_name(&mut self, td: TokenDesc) -> Option<(ClauseName, Option<SharedOpDesc>)> {
|
fn get_term_name(&mut self, td: TokenDesc) -> Option<(ClauseName, Option<SharedOpDesc>)> {
|
||||||
match td.tt {
|
match td.tt {
|
||||||
TokenType::HeadTailSeparator => {
|
TokenType::HeadTailSeparator => Some((
|
||||||
Some((clause_name!("|"), Some(SharedOpDesc::new(td.priority, td.spec))))
|
clause_name!("|"),
|
||||||
}
|
Some(SharedOpDesc::new(td.priority, td.spec)),
|
||||||
TokenType::Comma => {
|
)),
|
||||||
Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY))))
|
TokenType::Comma => Some((clause_name!(","), Some(SharedOpDesc::new(1000, XFY)))),
|
||||||
}
|
TokenType::Term => match self.terms.pop() {
|
||||||
TokenType::Term => {
|
Some(Term::Constant(_, Constant::Atom(atom, spec))) => Some((atom, spec)),
|
||||||
match self.terms.pop() {
|
Some(term) => {
|
||||||
Some(Term::Constant(_, Constant::Atom(atom, spec))) =>
|
self.terms.push(term);
|
||||||
Some((atom, spec)),
|
None
|
||||||
Some(term) => {
|
|
||||||
self.terms.push(term);
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => None
|
|
||||||
}
|
}
|
||||||
}
|
_ => None,
|
||||||
_ => {
|
},
|
||||||
None
|
_ => None,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_binary_op(&mut self, td: TokenDesc, spec: Specifier)
|
fn push_binary_op(&mut self, td: TokenDesc, spec: Specifier) {
|
||||||
{
|
|
||||||
if let Some(arg2) = self.terms.pop() {
|
if let Some(arg2) = self.terms.pop() {
|
||||||
if let Some((name, shared_op_desc)) = self.get_term_name(td) {
|
if let Some((name, shared_op_desc)) = self.get_term_name(td) {
|
||||||
if let Some(arg1) = self.terms.pop() {
|
if let Some(arg1) = self.terms.pop() {
|
||||||
let term = Term::Clause(Cell::default(),
|
let term = Term::Clause(
|
||||||
name,
|
Cell::default(),
|
||||||
vec![Box::new(arg1), Box::new(arg2)],
|
name,
|
||||||
shared_op_desc);
|
vec![Box::new(arg1), Box::new(arg2)],
|
||||||
|
shared_op_desc,
|
||||||
|
);
|
||||||
|
|
||||||
self.terms.push(term);
|
self.terms.push(term);
|
||||||
self.stack.push(TokenDesc { tt: TokenType::Term,
|
self.stack.push(TokenDesc {
|
||||||
priority: td.priority,
|
tt: TokenType::Term,
|
||||||
spec });
|
priority: td.priority,
|
||||||
|
spec,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32)
|
fn push_unary_op(&mut self, td: TokenDesc, spec: Specifier, assoc: u32) {
|
||||||
{
|
|
||||||
if let Some(mut arg1) = self.terms.pop() {
|
if let Some(mut arg1) = self.terms.pop() {
|
||||||
if let Some(mut name) = self.terms.pop() {
|
if let Some(mut name) = self.terms.pop() {
|
||||||
if is_postfix!(assoc) {
|
if is_postfix!(assoc) {
|
||||||
@@ -306,52 +297,61 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Term::Constant(_, Constant::Atom(name, shared_op_desc)) = name {
|
if let Term::Constant(_, Constant::Atom(name, shared_op_desc)) = name {
|
||||||
let term = Term::Clause(Cell::default(), name, vec![Box::new(arg1)],
|
let term =
|
||||||
shared_op_desc);
|
Term::Clause(Cell::default(), name, vec![Box::new(arg1)], shared_op_desc);
|
||||||
|
|
||||||
self.terms.push(term);
|
self.terms.push(term);
|
||||||
self.stack.push(TokenDesc { tt: TokenType::Term,
|
self.stack.push(TokenDesc {
|
||||||
priority: td.priority,
|
tt: TokenType::Term,
|
||||||
spec });
|
priority: td.priority,
|
||||||
|
spec,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn promote_atom_op(&mut self, atom: ClauseName, priority: usize, assoc: u32,
|
fn promote_atom_op(
|
||||||
op_dir_val: Option<&OpDirValue>)
|
&mut self,
|
||||||
{
|
atom: ClauseName,
|
||||||
|
priority: usize,
|
||||||
|
assoc: u32,
|
||||||
|
op_dir_val: Option<&OpDirValue>,
|
||||||
|
) {
|
||||||
let spec = op_dir_val.map(|op_dir_val| op_dir_val.shared_op_desc());
|
let spec = op_dir_val.map(|op_dir_val| op_dir_val.shared_op_desc());
|
||||||
|
|
||||||
self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, spec)));
|
self.terms
|
||||||
self.stack.push(TokenDesc { tt: TokenType::Term, priority, spec: assoc });
|
.push(Term::Constant(Cell::default(), Constant::Atom(atom, spec)));
|
||||||
|
self.stack.push(TokenDesc {
|
||||||
|
tt: TokenType::Term,
|
||||||
|
priority,
|
||||||
|
spec: assoc,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shift(&mut self, token: Token, priority: usize, spec: Specifier)
|
fn shift(&mut self, token: Token, priority: usize, spec: Specifier) {
|
||||||
{
|
|
||||||
let tt = match token {
|
let tt = match token {
|
||||||
Token::Constant(Constant::String(s))
|
Token::Constant(Constant::String(s)) if self.lexer.flags.double_quotes.is_codes() => {
|
||||||
if self.lexer.flags.double_quotes.is_codes() => {
|
let mut list = Term::Constant(Cell::default(), Constant::EmptyList);
|
||||||
let mut list = Term::Constant(Cell::default(), Constant::EmptyList);
|
|
||||||
|
|
||||||
for c in s.chars().rev() {
|
for c in s.chars().rev() {
|
||||||
list = Term::Cons(
|
list = Term::Cons(
|
||||||
|
Cell::default(),
|
||||||
|
Box::new(Term::Constant(
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
Box::new(Term::Constant(
|
Constant::Fixnum(c as isize),
|
||||||
Cell::default(),
|
)),
|
||||||
Constant::Fixnum(c as isize),
|
Box::new(list),
|
||||||
)),
|
);
|
||||||
Box::new(list),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.terms.push(list);
|
|
||||||
TokenType::Term
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.terms.push(list);
|
||||||
|
TokenType::Term
|
||||||
|
}
|
||||||
Token::Constant(c) => {
|
Token::Constant(c) => {
|
||||||
self.terms.push(Term::Constant(Cell::default(), c));
|
self.terms.push(Term::Constant(Cell::default(), c));
|
||||||
TokenType::Term
|
TokenType::Term
|
||||||
},
|
}
|
||||||
Token::Var(v) => {
|
Token::Var(v) => {
|
||||||
if v.trim() == "_" {
|
if v.trim() == "_" {
|
||||||
self.terms.push(Term::AnonVar);
|
self.terms.push(Term::AnonVar);
|
||||||
@@ -360,7 +360,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TokenType::Term
|
TokenType::Term
|
||||||
},
|
}
|
||||||
Token::Comma => TokenType::Comma,
|
Token::Comma => TokenType::Comma,
|
||||||
Token::Open => TokenType::Open,
|
Token::Open => TokenType::Open,
|
||||||
Token::Close => TokenType::Close,
|
Token::Close => TokenType::Close,
|
||||||
@@ -381,18 +381,13 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
if let Some(desc1) = self.stack.pop() {
|
if let Some(desc1) = self.stack.pop() {
|
||||||
if let Some(desc2) = self.stack.pop() {
|
if let Some(desc2) = self.stack.pop() {
|
||||||
if let Some(desc3) = self.stack.pop() {
|
if let Some(desc3) = self.stack.pop() {
|
||||||
if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1)
|
if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1) {
|
||||||
{
|
|
||||||
self.push_binary_op(desc2, LTERM);
|
self.push_binary_op(desc2, LTERM);
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1) {
|
||||||
else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1)
|
|
||||||
{
|
|
||||||
self.push_binary_op(desc2, LTERM);
|
self.push_binary_op(desc2, LTERM);
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1) {
|
||||||
else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1)
|
|
||||||
{
|
|
||||||
self.push_binary_op(desc2, TERM);
|
self.push_binary_op(desc2, TERM);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -425,12 +420,12 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_arity_in_brackets(&self) -> Option<usize>
|
fn compute_arity_in_brackets(&self) -> Option<usize> {
|
||||||
{
|
|
||||||
let mut arity = 0;
|
let mut arity = 0;
|
||||||
|
|
||||||
for (i, desc) in self.stack.iter().rev().enumerate() {
|
for (i, desc) in self.stack.iter().rev().enumerate() {
|
||||||
if i % 2 == 0 { // expect a term or non-comma operator.
|
if i % 2 == 0 {
|
||||||
|
// expect a term or non-comma operator.
|
||||||
if let TokenType::Comma = desc.tt {
|
if let TokenType::Comma = desc.tt {
|
||||||
return None;
|
return None;
|
||||||
} else if is_term!(desc.spec) || is_op!(desc.spec) || is_negate!(desc.spec) {
|
} else if is_term!(desc.spec) || is_op!(desc.spec) || is_negate!(desc.spec) {
|
||||||
@@ -454,8 +449,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool
|
fn reduce_term(&mut self, op_dir: &CompositeOpDir) -> bool {
|
||||||
{
|
|
||||||
if self.stack.is_empty() {
|
if self.stack.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -464,7 +458,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
let arity = match self.compute_arity_in_brackets() {
|
let arity = match self.compute_arity_in_brackets() {
|
||||||
Some(arity) => arity,
|
Some(arity) => arity,
|
||||||
None => return false
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.stack.len() > 2 * arity {
|
if self.stack.len() > 2 * arity {
|
||||||
@@ -490,9 +484,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
if self.atomize_term(&self.terms[idx - 1]).is_some() {
|
if self.atomize_term(&self.terms[idx - 1]).is_some() {
|
||||||
self.stack.truncate(stack_len + 1);
|
self.stack.truncate(stack_len + 1);
|
||||||
|
|
||||||
let mut subterms: Vec<_> = self.terms.drain(idx ..)
|
let mut subterms: Vec<_> = self.terms.drain(idx..).map(Box::new).collect();
|
||||||
.map(|t| Box::new(t))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(name) = self.terms.pop().and_then(|t| self.atomize_term(&t)) {
|
if let Some(name) = self.terms.pop().and_then(|t| self.atomize_term(&t)) {
|
||||||
// reduce the '.' functor to a cons cell if it applies.
|
// reduce the '.' functor to a cons cell if it applies.
|
||||||
@@ -503,11 +495,15 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
self.terms.push(Term::Cons(Cell::default(), head, tail));
|
self.terms.push(Term::Cons(Cell::default(), head, tail));
|
||||||
} else {
|
} else {
|
||||||
let spec = get_clause_spec(name.clone(), subterms.len(), op_dir);
|
let spec = get_clause_spec(name.clone(), subterms.len(), op_dir);
|
||||||
self.terms.push(Term::Clause(Cell::default(), name, subterms, spec));
|
self.terms
|
||||||
|
.push(Term::Clause(Cell::default(), name, subterms, spec));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(&mut TokenDesc { ref mut priority, ref mut spec,
|
if let Some(&mut TokenDesc {
|
||||||
ref mut tt }) = self.stack.last_mut()
|
ref mut priority,
|
||||||
|
ref mut spec,
|
||||||
|
ref mut tt,
|
||||||
|
}) = self.stack.last_mut()
|
||||||
{
|
{
|
||||||
*tt = TokenType::Term;
|
*tt = TokenType::Term;
|
||||||
*priority = 0;
|
*priority = 0;
|
||||||
@@ -523,7 +519,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn devour_whitespace(&mut self) -> Result<(), ParserError> {
|
pub fn devour_whitespace(&mut self) -> Result<(), ParserError> {
|
||||||
self.lexer.scan_for_layout()?;
|
self.lexer.scan_for_layout()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,8 +527,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
self.stack.clear()
|
self.stack.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_comma_compacted_terms(&mut self, index: usize) -> usize
|
fn expand_comma_compacted_terms(&mut self, index: usize) -> usize {
|
||||||
{
|
|
||||||
if let Some(term) = self.terms.pop() {
|
if let Some(term) = self.terms.pop() {
|
||||||
let op_desc = self.stack[index - 1];
|
let op_desc = self.stack[index - 1];
|
||||||
|
|
||||||
@@ -548,8 +543,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
self.terms.extend(terms.into_iter());
|
self.terms.extend(terms.into_iter());
|
||||||
return arity;
|
return arity;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,12 +553,12 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_arity_in_list(&self) -> Option<usize>
|
fn compute_arity_in_list(&self) -> Option<usize> {
|
||||||
{
|
|
||||||
let mut arity = 0;
|
let mut arity = 0;
|
||||||
|
|
||||||
for (i, desc) in self.stack.iter().rev().enumerate() {
|
for (i, desc) in self.stack.iter().rev().enumerate() {
|
||||||
if i % 2 == 0 { // expect a term or non-comma operator.
|
if i % 2 == 0 {
|
||||||
|
// expect a term or non-comma operator.
|
||||||
if let TokenType::Comma = desc.tt {
|
if let TokenType::Comma = desc.tt {
|
||||||
return None;
|
return None;
|
||||||
} else if is_term!(desc.spec) || is_op!(desc.spec) {
|
} else if is_term!(desc.spec) || is_op!(desc.spec) {
|
||||||
@@ -590,8 +584,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_list(&mut self) -> Result<bool, ParserError>
|
fn reduce_list(&mut self) -> Result<bool, ParserError> {
|
||||||
{
|
|
||||||
if self.stack.is_empty() {
|
if self.stack.is_empty() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
@@ -602,7 +595,8 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
td.tt = TokenType::Term;
|
td.tt = TokenType::Term;
|
||||||
td.priority = 0;
|
td.priority = 0;
|
||||||
|
|
||||||
self.terms.push(Term::Constant(Cell::default(), Constant::EmptyList));
|
self.terms
|
||||||
|
.push(Term::Constant(Cell::default(), Constant::EmptyList));
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -611,7 +605,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
let mut arity = match self.compute_arity_in_list() {
|
let mut arity = match self.compute_arity_in_list() {
|
||||||
Some(arity) => arity,
|
Some(arity) => arity,
|
||||||
None => return Ok(false)
|
None => return Ok(false),
|
||||||
};
|
};
|
||||||
|
|
||||||
// we know that self.stack.len() >= 2 by this point.
|
// we know that self.stack.len() >= 2 by this point.
|
||||||
@@ -621,12 +615,15 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
let end_term = if self.stack[idx].tt != TokenType::HeadTailSeparator {
|
let end_term = if self.stack[idx].tt != TokenType::HeadTailSeparator {
|
||||||
Term::Constant(Cell::default(), Constant::EmptyList)
|
Term::Constant(Cell::default(), Constant::EmptyList)
|
||||||
} else {
|
} else {
|
||||||
let term =
|
let term = match self.terms.pop() {
|
||||||
match self.terms.pop() {
|
Some(term) => term,
|
||||||
Some(term) => term,
|
_ => {
|
||||||
_ => return Err(ParserError::IncompleteReduction(self.lexer.line_num,
|
return Err(ParserError::IncompleteReduction(
|
||||||
self.lexer.col_num))
|
self.lexer.line_num,
|
||||||
};
|
self.lexer.col_num,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if self.stack[idx].priority > 1000 {
|
if self.stack[idx].priority > 1000 {
|
||||||
arity += self.expand_comma_compacted_terms(idx);
|
arity += self.expand_comma_compacted_terms(idx);
|
||||||
@@ -639,15 +636,17 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
let idx = self.terms.len() - arity;
|
let idx = self.terms.len() - arity;
|
||||||
|
|
||||||
let list = self.terms.drain(idx ..)
|
let list = self.terms.drain(idx..).rev().fold(end_term, |acc, t| {
|
||||||
.rev()
|
Term::Cons(Cell::default(), Box::new(t), Box::new(acc))
|
||||||
.fold(end_term, |acc, t| Term::Cons(Cell::default(),
|
});
|
||||||
Box::new(t),
|
|
||||||
Box::new(acc)));
|
|
||||||
|
|
||||||
self.stack.truncate(list_len);
|
self.stack.truncate(list_len);
|
||||||
|
|
||||||
self.stack.push(TokenDesc { tt: TokenType::Term, priority: 0, spec: TERM });
|
self.stack.push(TokenDesc {
|
||||||
|
tt: TokenType::Term,
|
||||||
|
priority: 0,
|
||||||
|
spec: TERM,
|
||||||
|
});
|
||||||
self.terms.push(list);
|
self.terms.push(list);
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
@@ -664,8 +663,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
td.priority = 0;
|
td.priority = 0;
|
||||||
td.spec = TERM;
|
td.spec = TERM;
|
||||||
|
|
||||||
let term = Term::Constant(Cell::default(),
|
let term = Term::Constant(Cell::default(), atom!("{}", self.lexer.atom_tbl));
|
||||||
atom!("{}", self.lexer.atom_tbl));
|
|
||||||
self.terms.push(term);
|
self.terms.push(term);
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
@@ -687,17 +685,19 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
let term = match self.terms.pop() {
|
let term = match self.terms.pop() {
|
||||||
Some(term) => term,
|
Some(term) => term,
|
||||||
_ => return Err(ParserError::IncompleteReduction(
|
_ => {
|
||||||
self.lexer.line_num,
|
return Err(ParserError::IncompleteReduction(
|
||||||
self.lexer.col_num,
|
self.lexer.line_num,
|
||||||
))
|
self.lexer.col_num,
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.terms.push(Term::Clause(
|
self.terms.push(Term::Clause(
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
clause_name!("{}"),
|
clause_name!("{}"),
|
||||||
vec![Box::new(term)],
|
vec![Box::new(term)],
|
||||||
None
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
@@ -722,35 +722,40 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
let idx = self.stack.len() - 2;
|
let idx = self.stack.len() - 2;
|
||||||
|
|
||||||
match self.stack.remove(idx) {
|
let td = self.stack.remove(idx);
|
||||||
td =>
|
match td.tt {
|
||||||
match td.tt {
|
TokenType::Open | TokenType::OpenCT => {
|
||||||
TokenType::Open | TokenType::OpenCT => {
|
if self.stack[idx].tt == TokenType::Comma {
|
||||||
if self.stack[idx].tt == TokenType::Comma {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(atom) = sep_to_atom(self.stack[idx].tt) {
|
|
||||||
self.terms.push(Term::Constant(Cell::default(), Constant::Atom(atom, None)));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.stack[idx].spec = TERM;
|
|
||||||
self.stack[idx].tt = TokenType::Term;
|
|
||||||
self.stack[idx].priority = 0;
|
|
||||||
true
|
|
||||||
},
|
|
||||||
_ => false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(atom) = sep_to_atom(self.stack[idx].tt) {
|
||||||
|
self.terms
|
||||||
|
.push(Term::Constant(Cell::default(), Constant::Atom(atom, None)));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.stack[idx].spec = TERM;
|
||||||
|
self.stack[idx].tt = TokenType::Term;
|
||||||
|
self.stack[idx].priority = 0;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shift_op(&mut self, name: ClauseName, op_dir: &CompositeOpDir) -> Result<bool, ParserError> {
|
fn shift_op(&mut self, name: ClauseName, op_dir: &CompositeOpDir) -> Result<bool, ParserError> {
|
||||||
if let Some(OpDesc { pre, inf, post, spec }) = get_op_desc(name.clone(), op_dir) {
|
if let Some(OpDesc {
|
||||||
|
pre,
|
||||||
|
inf,
|
||||||
|
post,
|
||||||
|
spec,
|
||||||
|
}) = get_op_desc(name.clone(), op_dir)
|
||||||
|
{
|
||||||
if (pre > 0 && inf + post > 0) || is_negate!(spec) {
|
if (pre > 0 && inf + post > 0) || is_negate!(spec) {
|
||||||
match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? {
|
match self.tokens.last().ok_or(ParserError::UnexpectedEOF)? {
|
||||||
// do this when layout hasn't been inserted,
|
// do this when layout hasn't been inserted,
|
||||||
// ie. why we don't match on Token::Open.
|
// ie. why we don't match on Token::Open.
|
||||||
&Token::OpenCT => {
|
Token::OpenCT => {
|
||||||
// can't be prefix, so either inf == 0
|
// can't be prefix, so either inf == 0
|
||||||
// or post == 0.
|
// or post == 0.
|
||||||
self.reduce_op(inf + post);
|
self.reduce_op(inf + post);
|
||||||
@@ -764,7 +769,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
spec & (XFX | XFY | YFX | YF | XF),
|
spec & (XFX | XFY | YFX | YF | XF),
|
||||||
op_dir_val,
|
op_dir_val,
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.reduce_op(inf + post);
|
self.reduce_op(inf + post);
|
||||||
|
|
||||||
@@ -782,11 +787,21 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let op_dir_val = op_dir.get(name.clone(), Fixity::Pre);
|
let op_dir_val = op_dir.get(name.clone(), Fixity::Pre);
|
||||||
self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN), op_dir_val);
|
self.promote_atom_op(
|
||||||
|
name,
|
||||||
|
pre,
|
||||||
|
spec & (FX | FY | NEGATIVE_SIGN),
|
||||||
|
op_dir_val,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let op_dir_val = op_dir.get(name.clone(), Fixity::Pre);
|
let op_dir_val = op_dir.get(name.clone(), Fixity::Pre);
|
||||||
self.promote_atom_op(name, pre, spec & (FX | FY | NEGATIVE_SIGN), op_dir_val);
|
self.promote_atom_op(
|
||||||
|
name,
|
||||||
|
pre,
|
||||||
|
spec & (FX | FY | NEGATIVE_SIGN),
|
||||||
|
op_dir_val,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -807,49 +822,46 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else { // not an operator.
|
} else {
|
||||||
|
// not an operator.
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atomize_term(&self, term: &Term) -> Option<ClauseName> {
|
fn atomize_term(&self, term: &Term) -> Option<ClauseName> {
|
||||||
match term {
|
match term {
|
||||||
&Term::Constant(_, ref c) => self.atomize_constant(c),
|
Term::Constant(_, ref c) => self.atomize_constant(c),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atomize_constant(&self, c: &Constant) -> Option<ClauseName> {
|
fn atomize_constant(&self, c: &Constant) -> Option<ClauseName> {
|
||||||
match c {
|
match c {
|
||||||
&Constant::Atom(ref name, _) => Some(name.clone()),
|
Constant::Atom(ref name, _) => Some(name.clone()),
|
||||||
&Constant::Char(c) =>
|
Constant::Char(c) => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
||||||
Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
Constant::EmptyList => Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
||||||
&Constant::EmptyList =>
|
_ => None,
|
||||||
Some(clause_name!(c.to_string(), self.lexer.atom_tbl)),
|
|
||||||
_ => None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn negate_number<N, Negator, ToConstant>(
|
fn negate_number<N, Negator, ToConstant>(&mut self, n: N, negator: Negator, constr: ToConstant)
|
||||||
&mut self,
|
where
|
||||||
n: N,
|
Negator: Fn(N) -> N,
|
||||||
negator: Negator,
|
ToConstant: Fn(N) -> Constant,
|
||||||
constr: ToConstant
|
|
||||||
)
|
|
||||||
where Negator: Fn(N) -> N,
|
|
||||||
ToConstant: Fn(N) -> Constant
|
|
||||||
{
|
{
|
||||||
if let Some(desc) = self.stack.last().cloned() {
|
if let Some(desc) = self.stack.last().cloned() {
|
||||||
if let Some(term) = self.terms.last().cloned() {
|
if let Some(term) = self.terms.last().cloned() {
|
||||||
match term {
|
match term {
|
||||||
Term::Constant(_, Constant::Atom(ref name, _))
|
Term::Constant(_, Constant::Atom(ref name, _))
|
||||||
if name.as_str() == "-" && (is_prefix!(desc.spec) || is_negate!(desc.spec)) => {
|
if name.as_str() == "-"
|
||||||
self.stack.pop();
|
&& (is_prefix!(desc.spec) || is_negate!(desc.spec)) =>
|
||||||
self.terms.pop();
|
{
|
||||||
|
self.stack.pop();
|
||||||
|
self.terms.pop();
|
||||||
|
|
||||||
self.shift(Token::Constant(constr(negator(n))), 0, TERM);
|
self.shift(Token::Constant(constr(negator(n))), 0, TERM);
|
||||||
return;
|
return;
|
||||||
},
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -860,42 +872,37 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
fn shift_token(&mut self, token: Token, op_dir: &CompositeOpDir) -> Result<(), ParserError> {
|
fn shift_token(&mut self, token: Token, op_dir: &CompositeOpDir) -> Result<(), ParserError> {
|
||||||
fn negate_rc<T: NegAssign>(mut t: Rc<T>) -> Rc<T> {
|
fn negate_rc<T: NegAssign>(mut t: Rc<T>) -> Rc<T> {
|
||||||
match Rc::get_mut(&mut t) {
|
if let Some(t) = Rc::get_mut(&mut t) {
|
||||||
Some(t) => {
|
t.neg_assign();
|
||||||
t.neg_assign();
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
match token {
|
match token {
|
||||||
Token::Constant(Constant::Fixnum(n)) =>
|
Token::Constant(Constant::Fixnum(n)) => self.negate_number(n, |n| -n, Constant::Fixnum),
|
||||||
self.negate_number(n, |n| -n, Constant::Fixnum),
|
Token::Constant(Constant::Integer(n)) => {
|
||||||
Token::Constant(Constant::Integer(n)) =>
|
self.negate_number(n, negate_rc, Constant::Integer)
|
||||||
self.negate_number(n, negate_rc, Constant::Integer),
|
}
|
||||||
Token::Constant(Constant::Rational(n)) =>
|
Token::Constant(Constant::Rational(n)) => {
|
||||||
self.negate_number(n, negate_rc, Constant::Rational),
|
self.negate_number(n, negate_rc, Constant::Rational)
|
||||||
Token::Constant(Constant::Float(n)) =>
|
}
|
||||||
self.negate_number(
|
Token::Constant(Constant::Float(n)) => {
|
||||||
n,
|
self.negate_number(n, |n| OrderedFloat(-n.into_inner()), Constant::Float)
|
||||||
|n| OrderedFloat(-n.into_inner()),
|
}
|
||||||
|n| Constant::Float(n)
|
Token::Constant(c) => {
|
||||||
),
|
|
||||||
Token::Constant(c) =>
|
|
||||||
if let Some(name) = self.atomize_constant(&c) {
|
if let Some(name) = self.atomize_constant(&c) {
|
||||||
if !self.shift_op(name, op_dir)? {
|
if !self.shift_op(name, op_dir)? {
|
||||||
self.shift(Token::Constant(c), 0, TERM);
|
self.shift(Token::Constant(c), 0, TERM);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.shift(Token::Constant(c), 0, TERM);
|
self.shift(Token::Constant(c), 0, TERM);
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Token::Var(v) => self.shift(Token::Var(v), 0, TERM),
|
Token::Var(v) => self.shift(Token::Var(v), 0, TERM),
|
||||||
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
|
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
|
||||||
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
|
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
|
||||||
Token::Close =>
|
Token::Close => {
|
||||||
if !self.reduce_term(op_dir) {
|
if !self.reduce_term(op_dir) {
|
||||||
if !self.reduce_brackets() {
|
if !self.reduce_brackets() {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(
|
||||||
@@ -903,23 +910,26 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
self.lexer.col_num,
|
self.lexer.col_num,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
|
}
|
||||||
Token::CloseList =>
|
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
|
||||||
|
Token::CloseList => {
|
||||||
if !self.reduce_list()? {
|
if !self.reduce_list()? {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(
|
||||||
self.lexer.line_num,
|
self.lexer.line_num,
|
||||||
self.lexer.col_num,
|
self.lexer.col_num,
|
||||||
));
|
));
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
|
Token::OpenCurly => self.shift(Token::OpenCurly, 1300, DELIMITER),
|
||||||
Token::CloseCurly =>
|
Token::CloseCurly => {
|
||||||
if !self.reduce_curly()? {
|
if !self.reduce_curly()? {
|
||||||
return Err(ParserError::IncompleteReduction(
|
return Err(ParserError::IncompleteReduction(
|
||||||
self.lexer.line_num,
|
self.lexer.line_num,
|
||||||
self.lexer.col_num,
|
self.lexer.col_num,
|
||||||
));
|
));
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Token::HeadTailSeparator => {
|
Token::HeadTailSeparator => {
|
||||||
/* '|' as an operator must have priority > 1000 and can only be infix.
|
/* '|' as an operator must have priority > 1000 and can only be infix.
|
||||||
* See: http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#Res_A78
|
* See: http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#Res_A78
|
||||||
@@ -930,23 +940,25 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
|
|
||||||
self.reduce_op(priority);
|
self.reduce_op(priority);
|
||||||
self.shift(Token::HeadTailSeparator, priority, spec);
|
self.shift(Token::HeadTailSeparator, priority, spec);
|
||||||
},
|
}
|
||||||
Token::Comma => {
|
Token::Comma => {
|
||||||
self.reduce_op(1000);
|
self.reduce_op(1000);
|
||||||
self.shift(Token::Comma, 1000, XFY);
|
self.shift(Token::Comma, 1000, XFY);
|
||||||
},
|
}
|
||||||
Token::End =>
|
Token::End => match self.stack.last().map(|t| t.tt) {
|
||||||
match self.stack.last().map(|t| t.tt) {
|
Some(TokenType::Open)
|
||||||
Some(TokenType::Open)
|
| Some(TokenType::OpenCT)
|
||||||
| Some(TokenType::OpenCT)
|
| Some(TokenType::OpenList)
|
||||||
| Some(TokenType::OpenList)
|
| Some(TokenType::OpenCurly)
|
||||||
| Some(TokenType::OpenCurly)
|
| Some(TokenType::HeadTailSeparator)
|
||||||
| Some(TokenType::HeadTailSeparator)
|
| Some(TokenType::Comma) => {
|
||||||
| Some(TokenType::Comma)
|
return Err(ParserError::IncompleteReduction(
|
||||||
=> return Err(ParserError::IncompleteReduction(self.lexer.line_num,
|
self.lexer.line_num,
|
||||||
self.lexer.col_num)),
|
self.lexer.col_num,
|
||||||
_ => {}
|
))
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -957,8 +969,7 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
self.lexer.eof()
|
self.lexer.eof()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_term(&mut self, op_dir: &CompositeOpDir) -> Result<Term, ParserError>
|
pub fn read_term(&mut self, op_dir: &CompositeOpDir) -> Result<Term, ParserError> {
|
||||||
{
|
|
||||||
self.tokens = read_tokens(&mut self.lexer)?;
|
self.tokens = read_tokens(&mut self.lexer)?;
|
||||||
|
|
||||||
while let Some(token) = self.tokens.pop() {
|
while let Some(token) = self.tokens.pop() {
|
||||||
@@ -968,21 +979,31 @@ impl<'a, R: Read> Parser<'a, R> {
|
|||||||
self.reduce_op(1400);
|
self.reduce_op(1400);
|
||||||
|
|
||||||
if self.terms.len() > 1 || self.stack.len() > 1 {
|
if self.terms.len() > 1 || self.stack.len() > 1 {
|
||||||
return Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num));
|
return Err(ParserError::IncompleteReduction(
|
||||||
|
self.lexer.line_num,
|
||||||
|
self.lexer.col_num,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.terms.pop() {
|
match self.terms.pop() {
|
||||||
Some(term) => if self.terms.is_empty() {
|
Some(term) => {
|
||||||
Ok(term)
|
if self.terms.is_empty() {
|
||||||
} else {
|
Ok(term)
|
||||||
Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num))
|
} else {
|
||||||
},
|
Err(ParserError::IncompleteReduction(
|
||||||
_ => Err(ParserError::IncompleteReduction(self.lexer.line_num, self.lexer.col_num))
|
self.lexer.line_num,
|
||||||
|
self.lexer.col_num,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(ParserError::IncompleteReduction(
|
||||||
|
self.lexer.line_num,
|
||||||
|
self.lexer.col_num,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self, op_dir: &CompositeOpDir) -> Result<Vec<Term>, ParserError>
|
pub fn read(&mut self, op_dir: &CompositeOpDir) -> Result<Vec<Term>, ParserError> {
|
||||||
{
|
|
||||||
let mut terms = Vec::new();
|
let mut terms = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ use std::collections::HashSet;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::{Rc};
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct TabledData<T> {
|
pub struct TabledData<T> {
|
||||||
table: Rc<RefCell<HashSet<Rc<T>>>>,
|
table: Rc<RefCell<HashSet<Rc<T>>>>,
|
||||||
pub(crate) module_name: Rc<String>
|
pub(crate) module_name: Rc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> {
|
impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> {
|
||||||
@@ -22,14 +22,15 @@ impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledData<T> {
|
|||||||
|
|
||||||
impl<T> Clone for TabledData<T> {
|
impl<T> Clone for TabledData<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
TabledData { table: self.table.clone(),
|
TabledData {
|
||||||
module_name: self.module_name.clone() }
|
table: self.table.clone(),
|
||||||
|
module_name: self.module_name.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq> PartialEq for TabledData<T> {
|
impl<T: PartialEq> PartialEq for TabledData<T> {
|
||||||
fn eq(&self, other: &TabledData<T>) -> bool
|
fn eq(&self, other: &TabledData<T>) -> bool {
|
||||||
{
|
|
||||||
Rc::ptr_eq(&self.table, &other.table) && self.module_name == other.module_name
|
Rc::ptr_eq(&self.table, &other.table) && self.module_name == other.module_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +40,7 @@ impl<T: Hash + Eq> TabledData<T> {
|
|||||||
pub fn new(module_name: Rc<String>) -> Self {
|
pub fn new(module_name: Rc<String>) -> Self {
|
||||||
TabledData {
|
TabledData {
|
||||||
table: Rc::new(RefCell::new(HashSet::new())),
|
table: Rc::new(RefCell::new(HashSet::new())),
|
||||||
module_name
|
module_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ impl<T: Hash + Eq> TabledData<T> {
|
|||||||
|
|
||||||
pub struct TabledRc<T: Hash + Eq> {
|
pub struct TabledRc<T: Hash + Eq> {
|
||||||
pub(crate) atom: Rc<T>,
|
pub(crate) atom: Rc<T>,
|
||||||
pub table: TabledData<T>
|
pub table: TabledData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledRc<T> {
|
impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledRc<T> {
|
||||||
@@ -67,27 +68,27 @@ impl<T: Hash + Eq + fmt::Debug> fmt::Debug for TabledRc<T> {
|
|||||||
// from complaining when deriving Clone for StringList.
|
// from complaining when deriving Clone for StringList.
|
||||||
impl<T: Hash + Eq> Clone for TabledRc<T> {
|
impl<T: Hash + Eq> Clone for TabledRc<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
TabledRc { atom: self.atom.clone(), table: self.table.clone() }
|
TabledRc {
|
||||||
|
atom: self.atom.clone(),
|
||||||
|
table: self.table.clone(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Ord + Hash + Eq> PartialOrd for TabledRc<T> {
|
impl<T: Ord + Hash + Eq> PartialOrd for TabledRc<T> {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
{
|
|
||||||
Some(self.atom.cmp(&other.atom))
|
Some(self.atom.cmp(&other.atom))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Ord + Hash + Eq> Ord for TabledRc<T> {
|
impl<T: Ord + Hash + Eq> Ord for TabledRc<T> {
|
||||||
fn cmp(&self, other: &Self) -> Ordering
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
{
|
|
||||||
self.atom.cmp(&other.atom)
|
self.atom.cmp(&other.atom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Hash + Eq> PartialEq for TabledRc<T> {
|
impl<T: Hash + Eq> PartialEq for TabledRc<T> {
|
||||||
fn eq(&self, other: &TabledRc<T>) -> bool
|
fn eq(&self, other: &TabledRc<T>) -> bool {
|
||||||
{
|
|
||||||
self.atom == other.atom
|
self.atom == other.atom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +104,8 @@ impl<T: Hash + Eq> Hash for TabledRc<T> {
|
|||||||
impl<T: Hash + Eq + ToString> TabledRc<T> {
|
impl<T: Hash + Eq + ToString> TabledRc<T> {
|
||||||
pub fn new(atom: T, table: TabledData<T>) -> Self {
|
pub fn new(atom: T, table: TabledData<T>) -> Self {
|
||||||
let atom = match table.borrow_mut().take(&atom) {
|
let atom = match table.borrow_mut().take(&atom) {
|
||||||
Some(atom) => atom.clone(),
|
Some(atom) => atom,
|
||||||
None => Rc::new(atom)
|
None => Rc::new(atom),
|
||||||
};
|
};
|
||||||
|
|
||||||
table.borrow_mut().insert(atom.clone());
|
table.borrow_mut().insert(atom.clone());
|
||||||
@@ -147,7 +148,7 @@ impl<T: Hash + Eq + fmt::Display> fmt::Display for TabledRc<T> {
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! tabled_rc {
|
macro_rules! tabled_rc {
|
||||||
($e:expr, $tbl:expr) => (
|
($e:expr, $tbl:expr) => {
|
||||||
TabledRc::new(String::from($e), $tbl.clone())
|
$crate::tabled_rc::TabledRc::new(String::from($e), $tbl.clone())
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
extern crate prolog_parser_rebis;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::lexer::{Lexer, Token};
|
||||||
use prolog_parser_rebis::ast::*;
|
use prolog_parser::tabled_rc::TabledData;
|
||||||
use prolog_parser_rebis::lexer::{Lexer, Token};
|
|
||||||
use prolog_parser_rebis::tabled_rc::TabledData;
|
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@@ -27,7 +25,7 @@ fn skip_utf8_bom() {
|
|||||||
let mut lexer = Lexer::new(atom_tbl, flags, &mut stream);
|
let mut lexer = Lexer::new(atom_tbl, flags, &mut stream);
|
||||||
match lexer.next_token() {
|
match lexer.next_token() {
|
||||||
Ok(Token::Constant(Constant::Fixnum(4))) => (),
|
Ok(Token::Constant(Constant::Fixnum(4))) => (),
|
||||||
_ => assert!(false)
|
_ => assert!(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +35,6 @@ fn invalid_utf16_bom() {
|
|||||||
let stream = parsing_stream(bytes);
|
let stream = parsing_stream(bytes);
|
||||||
match stream {
|
match stream {
|
||||||
Err(ParserError::Utf8Error(0, 0)) => (),
|
Err(ParserError::Utf8Error(0, 0)) => (),
|
||||||
_ => assert!(false)
|
_ => assert!(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
extern crate prolog_parser_rebis;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::lexer::{Lexer, Token};
|
||||||
use prolog_parser_rebis::ast::*;
|
use prolog_parser::tabled_rc::TabledData;
|
||||||
use prolog_parser_rebis::lexer::{Lexer, Token};
|
|
||||||
use prolog_parser_rebis::tabled_rc::TabledData;
|
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::temp_v;
|
||||||
|
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -14,8 +15,13 @@ pub trait Allocator<'a> {
|
|||||||
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Vec<Target>)
|
||||||
where
|
where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
fn mark_non_var<Target>(&mut self, _: Level, _: GenContext, _: &'a Cell<RegType>, _: &mut Vec<Target>)
|
fn mark_non_var<Target>(
|
||||||
where
|
&mut self,
|
||||||
|
_: Level,
|
||||||
|
_: GenContext,
|
||||||
|
_: &'a Cell<RegType>,
|
||||||
|
_: &mut Vec<Target>,
|
||||||
|
) where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
fn mark_reserved_var<Target>(
|
fn mark_reserved_var<Target>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -28,8 +34,14 @@ pub trait Allocator<'a> {
|
|||||||
_: bool,
|
_: bool,
|
||||||
) where
|
) where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
fn mark_var<Target>(&mut self, _: Rc<Var>, _: Level, _: &'a Cell<VarReg>, _: GenContext, _: &mut Vec<Target>)
|
fn mark_var<Target>(
|
||||||
where
|
&mut self,
|
||||||
|
_: Rc<Var>,
|
||||||
|
_: Level,
|
||||||
|
_: &'a Cell<VarReg>,
|
||||||
|
_: GenContext,
|
||||||
|
_: &mut Vec<Target>,
|
||||||
|
) where
|
||||||
Target: CompilationTarget<'a>;
|
Target: CompilationTarget<'a>;
|
||||||
|
|
||||||
fn reset(&mut self);
|
fn reset(&mut self);
|
||||||
@@ -47,7 +59,7 @@ pub trait Allocator<'a> {
|
|||||||
fn drain_var_data(
|
fn drain_var_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
vs: VariableFixtures<'a>,
|
vs: VariableFixtures<'a>,
|
||||||
num_of_chunks: usize
|
num_of_chunks: usize,
|
||||||
) -> VariableFixtures<'a> {
|
) -> VariableFixtures<'a> {
|
||||||
let mut perm_vs = VariableFixtures::new();
|
let mut perm_vs = VariableFixtures::new();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::{atom, clause_name};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
@@ -10,9 +11,9 @@ use crate::machine::heap::*;
|
|||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
|
|
||||||
use crate::ordered_float::*;
|
|
||||||
use crate::rug::ops::PowAssign;
|
use crate::rug::ops::PowAssign;
|
||||||
use crate::rug::{Assign, Integer, Rational};
|
use crate::rug::{Assign, Integer, Rational};
|
||||||
|
use ordered_float::*;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cmp::{max, min, Ordering};
|
use std::cmp::{max, min, Ordering};
|
||||||
@@ -267,9 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
|
|
||||||
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
|
fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
|
||||||
match c {
|
match c {
|
||||||
&Constant::Fixnum(n) => self
|
&Constant::Fixnum(n) => self.interm.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
||||||
.interm
|
|
||||||
.push(ArithmeticTerm::Number(Number::Fixnum(n))),
|
|
||||||
&Constant::Integer(ref n) => self
|
&Constant::Integer(ref n) => self
|
||||||
.interm
|
.interm
|
||||||
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
|
.push(ArithmeticTerm::Number(Number::Integer(n.clone()))),
|
||||||
@@ -326,17 +325,11 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
// integer division rounding function -- 9.1.3.1.
|
// integer division rounding function -- 9.1.3.1.
|
||||||
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
|
pub fn rnd_i<'a>(n: &'a Number) -> RefOrOwned<'a, Number> {
|
||||||
match n {
|
match n {
|
||||||
&Number::Integer(_) => {
|
&Number::Integer(_) => RefOrOwned::Borrowed(n),
|
||||||
RefOrOwned::Borrowed(n)
|
&Number::Float(OrderedFloat(f)) => RefOrOwned::Owned(Number::from(
|
||||||
}
|
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0)),
|
||||||
&Number::Float(OrderedFloat(f)) => {
|
)),
|
||||||
RefOrOwned::Owned(Number::from(
|
&Number::Fixnum(n) => RefOrOwned::Owned(Number::from(n)),
|
||||||
Integer::from_f64(f.floor()).unwrap_or_else(|| Integer::from(0))
|
|
||||||
))
|
|
||||||
}
|
|
||||||
&Number::Fixnum(n) => {
|
|
||||||
RefOrOwned::Owned(Number::from(n))
|
|
||||||
}
|
|
||||||
&Number::Rational(ref r) => {
|
&Number::Rational(ref r) => {
|
||||||
let r_ref = r.fract_floor_ref();
|
let r_ref = r.fract_floor_ref();
|
||||||
let (mut fract, mut floor) = (Rational::new(), Integer::new());
|
let (mut fract, mut floor) = (Rational::new(), Integer::new());
|
||||||
@@ -432,31 +425,31 @@ impl Add<Number> for Number {
|
|||||||
Number::from(Integer::from(n1) + Integer::from(n2))
|
Number::from(Integer::from(n1) + Integer::from(n2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
(Number::Fixnum(n1), Number::Integer(n2))
|
||||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Integer::from(n1) + &*n2))
|
Ok(Number::from(Integer::from(n1) + &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
(Number::Fixnum(n1), Number::Rational(n2))
|
||||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Rational::from(n1) + &*n2))
|
Ok(Number::from(Rational::from(n1) + &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
|
Ok(Number::Float(add_f(float_fn_to_f(n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i
|
Ok(Number::from(Integer::from(&*n1) + &*n2)) // add_i
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
|
(Number::Integer(n1), Number::Float(OrderedFloat(n2)))
|
||||||
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
| (Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||||
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
|
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Rational(n2))
|
(Number::Integer(n1), Number::Rational(n2))
|
||||||
| (Number::Rational(n2), Number::Integer(n1)) => {
|
| (Number::Rational(n2), Number::Integer(n1)) => {
|
||||||
Ok(Number::from(Rational::from(&*n1) + &*n2))
|
Ok(Number::from(Rational::from(&*n1) + &*n2))
|
||||||
}
|
}
|
||||||
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
|
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
|
||||||
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
|
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
|
||||||
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
|
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
|
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
|
||||||
@@ -474,12 +467,13 @@ impl Neg for Number {
|
|||||||
|
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
Number::Fixnum(n) =>
|
Number::Fixnum(n) => {
|
||||||
if let Some(n) = n.checked_neg() {
|
if let Some(n) = n.checked_neg() {
|
||||||
Number::Fixnum(n)
|
Number::Fixnum(n)
|
||||||
} else {
|
} else {
|
||||||
Number::from(-Integer::from(n))
|
Number::from(-Integer::from(n))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
|
Number::Integer(n) => Number::Integer(Rc::new(-Integer::from(&*n))),
|
||||||
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
|
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
|
||||||
Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))),
|
Number::Rational(r) => Number::Rational(Rc::new(-Rational::from(&*r))),
|
||||||
@@ -507,16 +501,16 @@ impl Mul<Number> for Number {
|
|||||||
Number::from(Integer::from(n1) * Integer::from(n2))
|
Number::from(Integer::from(n1) * Integer::from(n2))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) |
|
(Number::Fixnum(n1), Number::Integer(n2))
|
||||||
(Number::Integer(n2), Number::Fixnum(n1)) => {
|
| (Number::Integer(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Integer::from(n1) * &*n2))
|
Ok(Number::from(Integer::from(n1) * &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Rational(n2)) |
|
(Number::Fixnum(n1), Number::Rational(n2))
|
||||||
(Number::Rational(n2), Number::Fixnum(n1)) => {
|
| (Number::Rational(n2), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::from(Rational::from(n1) * &*n2))
|
Ok(Number::from(Rational::from(n1) * &*n2))
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) |
|
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2)))
|
||||||
(Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
| (Number::Float(OrderedFloat(n2)), Number::Fixnum(n1)) => {
|
||||||
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
|
Ok(Number::Float(mul_f(float_fn_to_f(n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
@@ -549,72 +543,50 @@ impl Div<Number> for Number {
|
|||||||
|
|
||||||
fn div(self, rhs: Number) -> Self::Output {
|
fn div(self, rhs: Number) -> Self::Output {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||||
Ok(Number::Float(div_f(
|
float_fn_to_f(n1)?,
|
||||||
float_fn_to_f(n1)?,
|
float_fn_to_f(n2)?,
|
||||||
float_fn_to_f(n2)?,
|
)?)),
|
||||||
)?))
|
(Number::Fixnum(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||||
}
|
float_fn_to_f(n1)?,
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
float_i_to_f(&n2)?,
|
||||||
Ok(Number::Float(div_f(
|
)?)),
|
||||||
float_fn_to_f(n1)?,
|
(Number::Integer(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||||
float_i_to_f(&n2)?,
|
float_i_to_f(&n1)?,
|
||||||
)?))
|
float_fn_to_f(n2)?,
|
||||||
}
|
)?)),
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||||
Ok(Number::Float(div_f(
|
float_fn_to_f(n1)?,
|
||||||
float_i_to_f(&n1)?,
|
float_r_to_f(&n2)?,
|
||||||
float_fn_to_f(n2)?,
|
)?)),
|
||||||
)?))
|
(Number::Rational(n1), Number::Fixnum(n2)) => Ok(Number::Float(div_f(
|
||||||
}
|
float_r_to_f(&n1)?,
|
||||||
(Number::Fixnum(n1), Number::Rational(n2)) => {
|
float_fn_to_f(n2)?,
|
||||||
Ok(Number::Float(div_f(
|
)?)),
|
||||||
float_fn_to_f(n1)?,
|
|
||||||
float_r_to_f(&n2)?,
|
|
||||||
)?))
|
|
||||||
}
|
|
||||||
(Number::Rational(n1), Number::Fixnum(n2)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_r_to_f(&n1)?,
|
|
||||||
float_fn_to_f(n2)?,
|
|
||||||
)?))
|
|
||||||
}
|
|
||||||
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
|
(Number::Fixnum(n1), Number::Float(OrderedFloat(n2))) => {
|
||||||
Ok(Number::Float(div_f(
|
Ok(Number::Float(div_f(float_fn_to_f(n1)?, n2)?))
|
||||||
float_fn_to_f(n1)?,
|
|
||||||
n2,
|
|
||||||
)?))
|
|
||||||
}
|
}
|
||||||
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
|
(Number::Float(OrderedFloat(n1)), Number::Fixnum(n2)) => {
|
||||||
Ok(Number::Float(div_f(
|
Ok(Number::Float(div_f(n1, float_fn_to_f(n2)?)?))
|
||||||
n1,
|
|
||||||
float_fn_to_f(n2)?,
|
|
||||||
)?))
|
|
||||||
}
|
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
|
||||||
Ok(Number::Float(div_f(
|
|
||||||
float_i_to_f(&n1)?,
|
|
||||||
float_i_to_f(&n2)?,
|
|
||||||
)?))
|
|
||||||
}
|
}
|
||||||
|
(Number::Integer(n1), Number::Integer(n2)) => Ok(Number::Float(div_f(
|
||||||
|
float_i_to_f(&n1)?,
|
||||||
|
float_i_to_f(&n2)?,
|
||||||
|
)?)),
|
||||||
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
|
(Number::Integer(n1), Number::Float(OrderedFloat(n2))) => {
|
||||||
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
|
Ok(Number::Float(div_f(float_i_to_f(&n1)?, n2)?))
|
||||||
}
|
}
|
||||||
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
(Number::Float(OrderedFloat(n2)), Number::Integer(n1)) => {
|
||||||
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
|
Ok(Number::Float(div_f(n2, float_i_to_f(&n1)?)?))
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Rational(n2)) => {
|
(Number::Integer(n1), Number::Rational(n2)) => Ok(Number::Float(div_f(
|
||||||
Ok(Number::Float(div_f(
|
float_i_to_f(&n1)?,
|
||||||
float_i_to_f(&n1)?,
|
float_r_to_f(&n2)?,
|
||||||
float_r_to_f(&n2)?,
|
)?)),
|
||||||
)?))
|
(Number::Rational(n2), Number::Integer(n1)) => Ok(Number::Float(div_f(
|
||||||
}
|
float_r_to_f(&n2)?,
|
||||||
(Number::Rational(n2), Number::Integer(n1)) => {
|
float_i_to_f(&n1)?,
|
||||||
Ok(Number::Float(div_f(
|
)?)),
|
||||||
float_r_to_f(&n2)?,
|
|
||||||
float_i_to_f(&n1)?,
|
|
||||||
)?))
|
|
||||||
}
|
|
||||||
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
|
(Number::Rational(n1), Number::Float(OrderedFloat(n2))) => {
|
||||||
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
|
Ok(Number::Float(div_f(float_r_to_f(&n1)?, n2)?))
|
||||||
}
|
}
|
||||||
@@ -727,12 +699,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
|||||||
|
|
||||||
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
|
fn try_from((addr, heap): (Addr, &'a Heap)) -> Result<Number, Self::Error> {
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Fixnum(n) => {
|
Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||||
Ok(Number::from(n))
|
Addr::Float(n) => Ok(Number::Float(n)),
|
||||||
}
|
|
||||||
Addr::Float(n) => {
|
|
||||||
Ok(Number::Float(n))
|
|
||||||
}
|
|
||||||
Addr::Usize(n) => {
|
Addr::Usize(n) => {
|
||||||
if let Ok(n) = isize::try_from(n) {
|
if let Ok(n) = isize::try_from(n) {
|
||||||
Ok(Number::from(n))
|
Ok(Number::from(n))
|
||||||
@@ -740,12 +708,8 @@ impl<'a> TryFrom<(Addr, &'a Heap)> for Number {
|
|||||||
Ok(Number::from(Integer::from(n)))
|
Ok(Number::from(Integer::from(n)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => Number::try_from(&heap[h]),
|
||||||
Number::try_from(&heap[h])
|
_ => Err(()),
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -755,35 +719,21 @@ impl<'a> TryFrom<&'a HeapCellValue> for Number {
|
|||||||
|
|
||||||
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
|
fn try_from(value: &'a HeapCellValue) -> Result<Number, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
HeapCellValue::Addr(addr) => {
|
HeapCellValue::Addr(addr) => match addr {
|
||||||
match addr {
|
&Addr::Fixnum(n) => Ok(Number::from(n)),
|
||||||
&Addr::Fixnum(n) => {
|
&Addr::Float(n) => Ok(Number::Float(n)),
|
||||||
|
&Addr::Usize(n) => {
|
||||||
|
if let Ok(n) = isize::try_from(n) {
|
||||||
Ok(Number::from(n))
|
Ok(Number::from(n))
|
||||||
}
|
} else {
|
||||||
&Addr::Float(n) => {
|
Ok(Number::from(Integer::from(n)))
|
||||||
Ok(Number::Float(n))
|
|
||||||
}
|
|
||||||
&Addr::Usize(n) => {
|
|
||||||
if let Ok(n) = isize::try_from(n) {
|
|
||||||
Ok(Number::from(n))
|
|
||||||
} else {
|
|
||||||
Ok(Number::from(Integer::from(n)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => Err(()),
|
||||||
HeapCellValue::Integer(n) => {
|
},
|
||||||
Ok(Number::Integer(n.clone()))
|
HeapCellValue::Integer(n) => Ok(Number::Integer(n.clone())),
|
||||||
}
|
HeapCellValue::Rational(n) => Ok(Number::Rational(n.clone())),
|
||||||
HeapCellValue::Rational(n) => {
|
_ => Err(()),
|
||||||
Ok(Number::Rational(n.clone()))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::{clause_name, temp_v};
|
||||||
|
|
||||||
use crate::forms::Number;
|
use crate::forms::Number;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::rug::rand::RandState;
|
use crate::rug::rand::RandState;
|
||||||
|
|
||||||
use crate::ref_thread_local::RefThreadLocal;
|
use ref_thread_local::{ref_thread_local, RefThreadLocal};
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
@@ -150,11 +151,6 @@ impl InlinedClauseType {
|
|||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub enum SystemClauseType {
|
pub enum SystemClauseType {
|
||||||
// AbolishClause,
|
|
||||||
// AbolishModuleClause,
|
|
||||||
// AssertDynamicPredicateToBack,
|
|
||||||
// AssertDynamicPredicateToFront,
|
|
||||||
// AtEndOfExpansion,
|
|
||||||
AtomChars,
|
AtomChars,
|
||||||
AtomCodes,
|
AtomCodes,
|
||||||
AtomLength,
|
AtomLength,
|
||||||
@@ -189,8 +185,6 @@ pub enum SystemClauseType {
|
|||||||
DynamicModuleResolution(usize),
|
DynamicModuleResolution(usize),
|
||||||
EnqueueAttributeGoal,
|
EnqueueAttributeGoal,
|
||||||
EnqueueAttributedVar,
|
EnqueueAttributedVar,
|
||||||
// ExpandGoal,
|
|
||||||
// ExpandTerm,
|
|
||||||
FetchGlobalVar,
|
FetchGlobalVar,
|
||||||
FetchGlobalVarWithOffset,
|
FetchGlobalVarWithOffset,
|
||||||
FirstStream,
|
FirstStream,
|
||||||
@@ -207,16 +201,13 @@ pub enum SystemClauseType {
|
|||||||
GetAttrVarQueueDelimiter,
|
GetAttrVarQueueDelimiter,
|
||||||
GetAttrVarQueueBeyond,
|
GetAttrVarQueueBeyond,
|
||||||
GetBValue,
|
GetBValue,
|
||||||
// GetClause,
|
|
||||||
GetContinuationChunk,
|
GetContinuationChunk,
|
||||||
// GetModuleClause,
|
|
||||||
GetNextDBRef,
|
GetNextDBRef,
|
||||||
GetNextOpDBRef,
|
GetNextOpDBRef,
|
||||||
IsPartialString,
|
IsPartialString,
|
||||||
LookupDBRef,
|
LookupDBRef,
|
||||||
LookupOpDBRef,
|
LookupOpDBRef,
|
||||||
Halt,
|
Halt,
|
||||||
// ModuleHeadIsDynamic,
|
|
||||||
GetLiftedHeapFromOffset,
|
GetLiftedHeapFromOffset,
|
||||||
GetLiftedHeapFromOffsetDiff,
|
GetLiftedHeapFromOffsetDiff,
|
||||||
GetSCCCleaner,
|
GetSCCCleaner,
|
||||||
@@ -225,10 +216,7 @@ pub enum SystemClauseType {
|
|||||||
InstallInferenceCounter,
|
InstallInferenceCounter,
|
||||||
LiftedHeapLength,
|
LiftedHeapLength,
|
||||||
LoadLibraryAsStream,
|
LoadLibraryAsStream,
|
||||||
// ModuleAssertDynamicPredicateToFront,
|
|
||||||
// ModuleAssertDynamicPredicateToBack,
|
|
||||||
ModuleExists,
|
ModuleExists,
|
||||||
// ModuleRetractClause,
|
|
||||||
NextEP,
|
NextEP,
|
||||||
NoSuchPredicate,
|
NoSuchPredicate,
|
||||||
NumberToChars,
|
NumberToChars,
|
||||||
@@ -254,7 +242,6 @@ pub enum SystemClauseType {
|
|||||||
ResetContinuationMarker,
|
ResetContinuationMarker,
|
||||||
ResetGlobalVarAtKey,
|
ResetGlobalVarAtKey,
|
||||||
ResetGlobalVarAtOffset,
|
ResetGlobalVarAtOffset,
|
||||||
// RetractClause,
|
|
||||||
RestoreCutPolicy,
|
RestoreCutPolicy,
|
||||||
SetCutPoint(RegType),
|
SetCutPoint(RegType),
|
||||||
SetInput,
|
SetInput,
|
||||||
@@ -324,11 +311,6 @@ pub enum SystemClauseType {
|
|||||||
impl SystemClauseType {
|
impl SystemClauseType {
|
||||||
pub fn name(&self) -> ClauseName {
|
pub fn name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
// &SystemClauseType::AbolishClause => clause_name!("$abolish_clause"),
|
|
||||||
// &SystemClauseType::AbolishModuleClause => clause_name!("$abolish_module_clause"),
|
|
||||||
// &SystemClauseType::AssertDynamicPredicateToBack => clause_name!("$assertz"),
|
|
||||||
// &SystemClauseType::AssertDynamicPredicateToFront => clause_name!("$asserta"),
|
|
||||||
// &SystemClauseType::AtEndOfExpansion => clause_name!("$at_end_of_expansion"),
|
|
||||||
&SystemClauseType::AtomChars => clause_name!("$atom_chars"),
|
&SystemClauseType::AtomChars => clause_name!("$atom_chars"),
|
||||||
&SystemClauseType::AtomCodes => clause_name!("$atom_codes"),
|
&SystemClauseType::AtomCodes => clause_name!("$atom_codes"),
|
||||||
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
|
&SystemClauseType::AtomLength => clause_name!("$atom_length"),
|
||||||
@@ -341,7 +323,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
|
||||||
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
|
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
|
||||||
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
|
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
|
||||||
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
|
&SystemClauseType::CopyTermWithoutAttrVars => {
|
||||||
|
clause_name!("$copy_term_without_attr_vars")
|
||||||
|
}
|
||||||
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
||||||
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
||||||
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
&SystemClauseType::CurrentHostname => clause_name!("$current_hostname"),
|
||||||
@@ -356,52 +340,70 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
&SystemClauseType::WorkingDirectory => clause_name!("$working_directory"),
|
||||||
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
&SystemClauseType::PathCanonical => clause_name!("$path_canonical"),
|
||||||
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
&SystemClauseType::FileTime => clause_name!("$file_time"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) =>
|
&SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate) => {
|
||||||
clause_name!("$add_dynamic_predicate"),
|
clause_name!("$add_dynamic_predicate")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) =>
|
}
|
||||||
clause_name!("$add_goal_expansion_clause"),
|
&SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) =>
|
clause_name!("$add_goal_expansion_clause")
|
||||||
clause_name!("$add_term_expansion_clause"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) =>
|
&SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause) => {
|
||||||
clause_name!("$clause_to_evacuable"),
|
clause_name!("$add_term_expansion_clause")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) =>
|
}
|
||||||
clause_name!("$conclude_load"),
|
&SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) =>
|
clause_name!("$clause_to_evacuable")
|
||||||
clause_name!("$declare_module"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) =>
|
&SystemClauseType::REPL(REPLCodePtr::ConcludeLoad) => clause_name!("$conclude_load"),
|
||||||
clause_name!("$load_compiled_library"),
|
&SystemClauseType::REPL(REPLCodePtr::DeclareModule) => clause_name!("$declare_module"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) =>
|
&SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary) => {
|
||||||
clause_name!("$push_load_state_payload"),
|
clause_name!("$load_compiled_library")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UserAsserta) =>
|
}
|
||||||
clause_name!("$asserta"),
|
&SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UserAssertz) =>
|
clause_name!("$push_load_state_payload")
|
||||||
clause_name!("$assertz"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UserRetract) =>
|
&SystemClauseType::REPL(REPLCodePtr::Asserta) => clause_name!("$asserta"),
|
||||||
clause_name!("$retract_clause"),
|
&SystemClauseType::REPL(REPLCodePtr::Assertz) => clause_name!("$assertz"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) =>
|
&SystemClauseType::REPL(REPLCodePtr::Retract) => clause_name!("$retract_clause"),
|
||||||
clause_name!("$use_module"),
|
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) =>
|
&SystemClauseType::REPL(REPLCodePtr::PushLoadContext) => {
|
||||||
clause_name!("$push_load_context"),
|
clause_name!("$push_load_context")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) =>
|
}
|
||||||
clause_name!("$pop_load_context"),
|
&SystemClauseType::REPL(REPLCodePtr::PopLoadContext) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) =>
|
clause_name!("$pop_load_context")
|
||||||
clause_name!("$pop_load_state_payload"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) =>
|
&SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload) => {
|
||||||
clause_name!("$prolog_lc_source"),
|
clause_name!("$pop_load_state_payload")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) =>
|
}
|
||||||
clause_name!("$prolog_lc_file"),
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextSource) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) =>
|
clause_name!("$prolog_lc_source")
|
||||||
clause_name!("$prolog_lc_dir"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) =>
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextFile) => {
|
||||||
clause_name!("$prolog_lc_module"),
|
clause_name!("$prolog_lc_file")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) =>
|
}
|
||||||
clause_name!("$prolog_lc_stream"),
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory) => {
|
||||||
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) =>
|
clause_name!("$prolog_lc_dir")
|
||||||
clause_name!("$cpp_meta_predicate_property"),
|
}
|
||||||
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) =>
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextModule) => {
|
||||||
clause_name!("$cpp_built_in_property"),
|
clause_name!("$prolog_lc_module")
|
||||||
&SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates) =>
|
}
|
||||||
clause_name!("$compile_pending_predicates"),
|
&SystemClauseType::REPL(REPLCodePtr::LoadContextStream) => {
|
||||||
|
clause_name!("$prolog_lc_stream")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty) => {
|
||||||
|
clause_name!("$cpp_meta_predicate_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) => {
|
||||||
|
clause_name!("$cpp_built_in_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) => {
|
||||||
|
clause_name!("$cpp_dynamic_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) => {
|
||||||
|
clause_name!("$cpp_multifile_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) => {
|
||||||
|
clause_name!("$cpp_discontiguous_property")
|
||||||
|
}
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::AbolishClause) => clause_name!("$abolish_clause"),
|
||||||
&SystemClauseType::Close => clause_name!("$close"),
|
&SystemClauseType::Close => clause_name!("$close"),
|
||||||
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
&SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"),
|
||||||
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
&SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"),
|
||||||
@@ -410,8 +412,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
||||||
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
||||||
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
||||||
&SystemClauseType::FetchGlobalVarWithOffset =>
|
&SystemClauseType::FetchGlobalVarWithOffset => {
|
||||||
clause_name!("$fetch_global_var_with_offset"),
|
clause_name!("$fetch_global_var_with_offset")
|
||||||
|
}
|
||||||
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
||||||
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
||||||
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
||||||
@@ -437,13 +440,13 @@ impl SystemClauseType {
|
|||||||
clause_name!("$get_lh_from_offset_diff")
|
clause_name!("$get_lh_from_offset_diff")
|
||||||
}
|
}
|
||||||
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
&SystemClauseType::GetBValue => clause_name!("$get_b_value"),
|
||||||
// &SystemClauseType::GetClause => clause_name!("$get_clause"),
|
// &SystemClauseType::GetClause => clause_name!("$get_clause"),
|
||||||
&SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"),
|
&SystemClauseType::GetNextDBRef => clause_name!("$get_next_db_ref"),
|
||||||
&SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"),
|
&SystemClauseType::GetNextOpDBRef => clause_name!("$get_next_op_db_ref"),
|
||||||
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
|
&SystemClauseType::LookupDBRef => clause_name!("$lookup_db_ref"),
|
||||||
&SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"),
|
&SystemClauseType::LookupOpDBRef => clause_name!("$lookup_op_db_ref"),
|
||||||
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
&SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
|
||||||
// &SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
|
// &SystemClauseType::GetModuleClause => clause_name!("$get_module_clause"),
|
||||||
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
&SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
|
||||||
&SystemClauseType::Halt => clause_name!("$halt"),
|
&SystemClauseType::Halt => clause_name!("$halt"),
|
||||||
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
|
&SystemClauseType::HeadIsDynamic => clause_name!("$head_is_dynamic"),
|
||||||
@@ -468,7 +471,7 @@ impl SystemClauseType {
|
|||||||
// &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
|
// &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
|
||||||
// clause_name!("$module_assertz")
|
// clause_name!("$module_assertz")
|
||||||
// }
|
// }
|
||||||
// &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
|
// &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
|
||||||
&SystemClauseType::ModuleExists => clause_name!("$module_exists"),
|
&SystemClauseType::ModuleExists => clause_name!("$module_exists"),
|
||||||
&SystemClauseType::NextStream => clause_name!("$next_stream"),
|
&SystemClauseType::NextStream => clause_name!("$next_stream"),
|
||||||
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
|
&SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
|
||||||
@@ -520,7 +523,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
||||||
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
||||||
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
||||||
&SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"),
|
&SystemClauseType::ResetGlobalVarAtOffset => {
|
||||||
|
clause_name!("$reset_global_var_at_offset")
|
||||||
|
}
|
||||||
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
|
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
|
||||||
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
||||||
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
||||||
@@ -534,7 +539,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
|
&SystemClauseType::SocketServerAccept => clause_name!("$socket_server_accept"),
|
||||||
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
|
&SystemClauseType::SocketServerClose => clause_name!("$socket_server_close"),
|
||||||
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
||||||
&SystemClauseType::TermAttributedVariables => clause_name!("$term_attributed_variables"),
|
&SystemClauseType::TermAttributedVariables => {
|
||||||
|
clause_name!("$term_attributed_variables")
|
||||||
|
}
|
||||||
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
||||||
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
||||||
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
||||||
@@ -555,7 +562,9 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
&SystemClauseType::Ed25519Sign => clause_name!("$ed25519_sign"),
|
||||||
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
&SystemClauseType::Ed25519Verify => clause_name!("$ed25519_verify"),
|
||||||
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
|
&SystemClauseType::Ed25519NewKeyPair => clause_name!("$ed25519_new_keypair"),
|
||||||
&SystemClauseType::Ed25519KeyPairPublicKey => clause_name!("$ed25519_keypair_public_key"),
|
&SystemClauseType::Ed25519KeyPairPublicKey => {
|
||||||
|
clause_name!("$ed25519_keypair_public_key")
|
||||||
|
}
|
||||||
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
|
&SystemClauseType::Curve25519ScalarMult => clause_name!("$curve25519_scalar_mult"),
|
||||||
&SystemClauseType::LoadHTML => clause_name!("$load_html"),
|
&SystemClauseType::LoadHTML => clause_name!("$load_html"),
|
||||||
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
&SystemClauseType::LoadXML => clause_name!("$load_xml"),
|
||||||
@@ -569,21 +578,21 @@ impl SystemClauseType {
|
|||||||
|
|
||||||
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
|
||||||
match (name, arity) {
|
match (name, arity) {
|
||||||
// ("$abolish_clause", 2) => Some(SystemClauseType::AbolishClause),
|
("$abolish_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::AbolishClause)),
|
||||||
("$add_dynamic_predicate", 3) =>
|
("$add_dynamic_predicate", 3) => {
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate)),
|
Some(SystemClauseType::REPL(REPLCodePtr::AddDynamicPredicate))
|
||||||
("$add_goal_expansion_clause", 4) =>
|
}
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause)),
|
("$add_goal_expansion_clause", 4) => {
|
||||||
("$add_term_expansion_clause", 3) =>
|
Some(SystemClauseType::REPL(REPLCodePtr::AddGoalExpansionClause))
|
||||||
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause)),
|
}
|
||||||
// ("$at_end_of_expansion", 0) => Some(SystemClauseType::AtEndOfExpansion),
|
("$add_term_expansion_clause", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::AddTermExpansionClause))
|
||||||
|
}
|
||||||
("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
|
("$atom_chars", 2) => Some(SystemClauseType::AtomChars),
|
||||||
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
|
("$atom_codes", 2) => Some(SystemClauseType::AtomCodes),
|
||||||
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
|
("$atom_length", 2) => Some(SystemClauseType::AtomLength),
|
||||||
// ("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause),
|
// ("$abolish_module_clause", 3) => Some(SystemClauseType::AbolishModuleClause),
|
||||||
("$bind_from_register", 2) => Some(SystemClauseType::BindFromRegister),
|
("$bind_from_register", 2) => Some(SystemClauseType::BindFromRegister),
|
||||||
// ("$module_asserta", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToFront),
|
|
||||||
// ("$module_assertz", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToBack),
|
|
||||||
("$call_continuation", 1) => Some(SystemClauseType::CallContinuation),
|
("$call_continuation", 1) => Some(SystemClauseType::CallContinuation),
|
||||||
("$char_code", 2) => Some(SystemClauseType::CharCode),
|
("$char_code", 2) => Some(SystemClauseType::CharCode),
|
||||||
("$char_type", 2) => Some(SystemClauseType::CharType),
|
("$char_type", 2) => Some(SystemClauseType::CharType),
|
||||||
@@ -616,10 +625,10 @@ impl SystemClauseType {
|
|||||||
("$peek_char", 2) => Some(SystemClauseType::PeekChar),
|
("$peek_char", 2) => Some(SystemClauseType::PeekChar),
|
||||||
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
||||||
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
||||||
// ("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
|
|
||||||
// ("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
|
|
||||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||||
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
|
("$fetch_global_var_with_offset", 3) => {
|
||||||
|
Some(SystemClauseType::FetchGlobalVarWithOffset)
|
||||||
|
}
|
||||||
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
||||||
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
||||||
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
||||||
@@ -628,18 +637,10 @@ impl SystemClauseType {
|
|||||||
("$points_to_cont_reset_marker", 1) => {
|
("$points_to_cont_reset_marker", 1) => {
|
||||||
Some(SystemClauseType::PointsToContinuationResetMarker)
|
Some(SystemClauseType::PointsToContinuationResetMarker)
|
||||||
}
|
}
|
||||||
("$put_byte", 2) => {
|
("$put_byte", 2) => Some(SystemClauseType::PutByte),
|
||||||
Some(SystemClauseType::PutByte)
|
("$put_char", 2) => Some(SystemClauseType::PutChar),
|
||||||
}
|
("$put_chars", 2) => Some(SystemClauseType::PutChars),
|
||||||
("$put_char", 2) => {
|
("$put_code", 2) => Some(SystemClauseType::PutCode),
|
||||||
Some(SystemClauseType::PutChar)
|
|
||||||
}
|
|
||||||
("$put_chars", 2) => {
|
|
||||||
Some(SystemClauseType::PutChars)
|
|
||||||
}
|
|
||||||
("$put_code", 2) => {
|
|
||||||
Some(SystemClauseType::PutCode)
|
|
||||||
}
|
|
||||||
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState),
|
||||||
("$truncate_if_no_lh_growth", 1) => {
|
("$truncate_if_no_lh_growth", 1) => {
|
||||||
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
|
||||||
@@ -649,8 +650,6 @@ impl SystemClauseType {
|
|||||||
}
|
}
|
||||||
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
|
("$get_attr_list", 2) => Some(SystemClauseType::GetAttributedVariableList),
|
||||||
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
|
||||||
// ("$get_clause", 2) => Some(SystemClauseType::GetClause),
|
|
||||||
// ("$get_module_clause", 3) => Some(SystemClauseType::GetModuleClause),
|
|
||||||
("$get_lh_from_offset", 2) => Some(SystemClauseType::GetLiftedHeapFromOffset),
|
("$get_lh_from_offset", 2) => Some(SystemClauseType::GetLiftedHeapFromOffset),
|
||||||
("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
("$get_lh_from_offset_diff", 3) => Some(SystemClauseType::GetLiftedHeapFromOffsetDiff),
|
||||||
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
|
||||||
@@ -664,8 +663,6 @@ impl SystemClauseType {
|
|||||||
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
|
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
|
||||||
("$current_time", 1) => Some(SystemClauseType::CurrentTime),
|
("$current_time", 1) => Some(SystemClauseType::CurrentTime),
|
||||||
("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
|
("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
|
||||||
// ("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
|
|
||||||
// ("$module_head_is_dynamic", 2) => Some(SystemClauseType::ModuleHeadIsDynamic),
|
|
||||||
("$no_such_predicate", 2) => Some(SystemClauseType::NoSuchPredicate),
|
("$no_such_predicate", 2) => Some(SystemClauseType::NoSuchPredicate),
|
||||||
("$number_to_chars", 2) => Some(SystemClauseType::NumberToChars),
|
("$number_to_chars", 2) => Some(SystemClauseType::NumberToChars),
|
||||||
("$number_to_codes", 2) => Some(SystemClauseType::NumberToCodes),
|
("$number_to_codes", 2) => Some(SystemClauseType::NumberToCodes),
|
||||||
@@ -700,7 +697,6 @@ impl SystemClauseType {
|
|||||||
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
|
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
|
||||||
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
|
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
|
||||||
("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
|
("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
|
||||||
// ("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
|
|
||||||
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
|
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
|
||||||
("$set_ball", 1) => Some(SystemClauseType::SetBall),
|
("$set_ball", 1) => Some(SystemClauseType::SetBall),
|
||||||
("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
|
("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
|
||||||
@@ -713,7 +709,9 @@ impl SystemClauseType {
|
|||||||
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
||||||
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
||||||
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
||||||
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
|
("$store_global_var_with_offset", 2) => {
|
||||||
|
Some(SystemClauseType::StoreGlobalVarWithOffset)
|
||||||
|
}
|
||||||
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
||||||
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||||
@@ -730,15 +728,21 @@ impl SystemClauseType {
|
|||||||
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
("$working_directory", 2) => Some(SystemClauseType::WorkingDirectory),
|
||||||
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
("$path_canonical", 2) => Some(SystemClauseType::PathCanonical),
|
||||||
("$file_time", 3) => Some(SystemClauseType::FileTime),
|
("$file_time", 3) => Some(SystemClauseType::FileTime),
|
||||||
("$clause_to_evacuable", 3) => Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable)),
|
("$clause_to_evacuable", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::ClauseToEvacuable))
|
||||||
|
}
|
||||||
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
|
("$conclude_load", 1) => Some(SystemClauseType::REPL(REPLCodePtr::ConcludeLoad)),
|
||||||
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
("$use_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)),
|
||||||
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
("$declare_module", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DeclareModule)),
|
||||||
("$load_compiled_library", 2) => Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary)),
|
("$load_compiled_library", 2) => {
|
||||||
("$push_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadCompiledLibrary))
|
||||||
("$asserta", 4) => Some(SystemClauseType::REPL(REPLCodePtr::UserAsserta)),
|
}
|
||||||
("$assertz", 4) => Some(SystemClauseType::REPL(REPLCodePtr::UserAssertz)),
|
("$push_load_state_payload", 1) => {
|
||||||
("$retract_clause", 3) => Some(SystemClauseType::REPL(REPLCodePtr::UserRetract)),
|
Some(SystemClauseType::REPL(REPLCodePtr::PushLoadStatePayload))
|
||||||
|
}
|
||||||
|
("$asserta", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Asserta)),
|
||||||
|
("$assertz", 5) => Some(SystemClauseType::REPL(REPLCodePtr::Assertz)),
|
||||||
|
("$retract_clause", 4) => Some(SystemClauseType::REPL(REPLCodePtr::Retract)),
|
||||||
("$variant", 2) => Some(SystemClauseType::Variant),
|
("$variant", 2) => Some(SystemClauseType::Variant),
|
||||||
("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions),
|
("$wam_instructions", 4) => Some(SystemClauseType::WAMInstructions),
|
||||||
("$write_term", 7) => Some(SystemClauseType::WriteTerm),
|
("$write_term", 7) => Some(SystemClauseType::WriteTerm),
|
||||||
@@ -764,16 +768,38 @@ impl SystemClauseType {
|
|||||||
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
("$chars_base64", 4) => Some(SystemClauseType::CharsBase64),
|
||||||
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
("$load_library_as_stream", 3) => Some(SystemClauseType::LoadLibraryAsStream),
|
||||||
("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
|
("$push_load_context", 2) => Some(SystemClauseType::REPL(REPLCodePtr::PushLoadContext)),
|
||||||
("$pop_load_state_payload", 1) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload)),
|
("$pop_load_state_payload", 1) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::PopLoadStatePayload))
|
||||||
|
}
|
||||||
("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
|
("$pop_load_context", 0) => Some(SystemClauseType::REPL(REPLCodePtr::PopLoadContext)),
|
||||||
("$prolog_lc_source", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource)),
|
("$prolog_lc_source", 1) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextSource))
|
||||||
|
}
|
||||||
("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
|
("$prolog_lc_file", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextFile)),
|
||||||
("$prolog_lc_dir", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory)),
|
("$prolog_lc_dir", 1) => {
|
||||||
("$prolog_lc_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextDirectory))
|
||||||
("$prolog_lc_stream", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream)),
|
}
|
||||||
("$cpp_meta_predicate_property", 4) => Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty)),
|
("$prolog_lc_module", 1) => {
|
||||||
("$cpp_built_in_property", 2) => Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty)),
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextModule))
|
||||||
("$compile_pending_predicates", 1) => Some(SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates)),
|
}
|
||||||
|
("$prolog_lc_stream", 1) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream))
|
||||||
|
}
|
||||||
|
("$cpp_meta_predicate_property", 4) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty))
|
||||||
|
}
|
||||||
|
("$cpp_built_in_property", 2) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty))
|
||||||
|
}
|
||||||
|
("$cpp_dynamic_property", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty))
|
||||||
|
}
|
||||||
|
("$cpp_multifile_property", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty))
|
||||||
|
}
|
||||||
|
("$cpp_discontiguous_property", 3) => {
|
||||||
|
Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -852,10 +878,10 @@ impl ClauseType {
|
|||||||
match self {
|
match self {
|
||||||
&ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
|
&ClauseType::Op(_, ref spec, _) => Some(spec.clone()),
|
||||||
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
|
&ClauseType::Inlined(InlinedClauseType::CompareNumber(..))
|
||||||
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
|
| &ClauseType::BuiltIn(BuiltInClauseType::Is(..))
|
||||||
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
|
| &ClauseType::BuiltIn(BuiltInClauseType::CompareTerm(_))
|
||||||
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
|
| &ClauseType::BuiltIn(BuiltInClauseType::NotEq)
|
||||||
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
|
| &ClauseType::BuiltIn(BuiltInClauseType::Eq) => Some(SharedOpDesc::new(700, XFX)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -863,7 +889,7 @@ impl ClauseType {
|
|||||||
pub fn name(&self) -> ClauseName {
|
pub fn name(&self) -> ClauseName {
|
||||||
match self {
|
match self {
|
||||||
&ClauseType::BuiltIn(ref built_in) => built_in.name(),
|
&ClauseType::BuiltIn(ref built_in) => built_in.name(),
|
||||||
&ClauseType::CallN => clause_name!("call"),
|
&ClauseType::CallN => clause_name!("$call"),
|
||||||
&ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()),
|
&ClauseType::Inlined(ref inlined) => clause_name!(inlined.name()),
|
||||||
&ClauseType::Op(ref name, ..) => name.clone(),
|
&ClauseType::Op(ref name, ..) => name.clone(),
|
||||||
&ClauseType::Named(ref name, ..) => name.clone(),
|
&ClauseType::Named(ref name, ..) => name.clone(),
|
||||||
@@ -882,7 +908,7 @@ impl ClauseType {
|
|||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
if let Some(spec) = spec {
|
if let Some(spec) = spec {
|
||||||
ClauseType::Op(name, spec, CodeIndex::default())
|
ClauseType::Op(name, spec, CodeIndex::default())
|
||||||
} else if name.as_str() == "call" {
|
} else if name.as_str() == "$call" {
|
||||||
ClauseType::CallN
|
ClauseType::CallN
|
||||||
} else {
|
} else {
|
||||||
ClauseType::Named(name, arity, CodeIndex::default())
|
ClauseType::Named(name, arity, CodeIndex::default())
|
||||||
|
|||||||
195
src/codegen.rs
195
src/codegen.rs
@@ -1,6 +1,7 @@
|
|||||||
/// Code generation to WAM-like instructions.
|
/// Code generation to WAM-like instructions.
|
||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
use prolog_parser::tabled_rc::TabledData;
|
||||||
|
use prolog_parser::{perm_v, temp_v};
|
||||||
|
|
||||||
use crate::allocator::*;
|
use crate::allocator::*;
|
||||||
use crate::arithmetic::*;
|
use crate::arithmetic::*;
|
||||||
@@ -14,7 +15,7 @@ use crate::targets::*;
|
|||||||
|
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
|
|
||||||
use crate::indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
@@ -66,18 +67,14 @@ impl<'a> ConjunctInfo<'a> {
|
|||||||
self.has_deep_cut as usize
|
self.has_deep_cut as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_unsafe_vars(
|
fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
|
||||||
&self,
|
|
||||||
mut unsafe_var_marker: UnsafeVarMarker,
|
|
||||||
code: &mut Code,
|
|
||||||
) {
|
|
||||||
if code.is_empty() {
|
if code.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut code_index = 0;
|
let mut code_index = 0;
|
||||||
|
|
||||||
for phase in 0 .. {
|
for phase in 0.. {
|
||||||
while let Line::Query(ref query_instr) = &code[code_index] {
|
while let Line::Query(ref query_instr) = &code[code_index] {
|
||||||
if !unsafe_var_marker.mark_safe_vars(query_instr) {
|
if !unsafe_var_marker.mark_safe_vars(query_instr) {
|
||||||
unsafe_var_marker.mark_phase(query_instr, phase);
|
unsafe_var_marker.mark_phase(query_instr, phase);
|
||||||
@@ -95,7 +92,7 @@ impl<'a> ConjunctInfo<'a> {
|
|||||||
|
|
||||||
code_index = 0;
|
code_index = 0;
|
||||||
|
|
||||||
for phase in 0 .. {
|
for phase in 0.. {
|
||||||
while let Line::Query(ref mut query_instr) = &mut code[code_index] {
|
while let Line::Query(ref mut query_instr) = &mut code[code_index] {
|
||||||
unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
|
unsafe_var_marker.mark_unsafe_vars(query_instr, phase);
|
||||||
code_index += 1;
|
code_index += 1;
|
||||||
@@ -173,7 +170,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code: &mut Code,
|
code: &mut Code,
|
||||||
) -> RegType {
|
) -> RegType {
|
||||||
let mut target = Vec::new();
|
let mut target = Vec::new();
|
||||||
self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
|
self.marker
|
||||||
|
.mark_var(name, Level::Shallow, vr, term_loc, &mut target);
|
||||||
|
|
||||||
if !target.is_empty() {
|
if !target.is_empty() {
|
||||||
code.extend(target.into_iter().map(Line::Query));
|
code.extend(target.into_iter().map(Line::Query));
|
||||||
@@ -191,9 +189,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code: &mut Code,
|
code: &mut Code,
|
||||||
) -> RegType {
|
) -> RegType {
|
||||||
match self.marker.bindings().get(&name) {
|
match self.marker.bindings().get(&name) {
|
||||||
Some(&VarData::Temp(_, t, _)) if t != 0 => {
|
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
|
||||||
RegType::Temp(t)
|
|
||||||
}
|
|
||||||
Some(&VarData::Perm(p)) if p != 0 => {
|
Some(&VarData::Perm(p)) if p != 0 => {
|
||||||
if let GenContext::Last(_) = term_loc {
|
if let GenContext::Last(_) = term_loc {
|
||||||
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
|
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
|
||||||
@@ -202,9 +198,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
RegType::Perm(p)
|
RegType::Perm(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => self.mark_var_in_non_callable(name, term_loc, vr, code),
|
||||||
self.mark_var_in_non_callable(name, term_loc, vr, code)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +225,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
target: &mut Vec<Target>,
|
target: &mut Vec<Target>,
|
||||||
) {
|
) {
|
||||||
if is_exposed || self.get_var_count(var.as_ref()) > 1 {
|
if is_exposed || self.get_var_count(var.as_ref()) > 1 {
|
||||||
self.marker.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
|
self.marker
|
||||||
|
.mark_var(var.clone(), Level::Deep, cell, term_loc, target);
|
||||||
} else {
|
} else {
|
||||||
Self::add_or_increment_void_instr(target);
|
Self::add_or_increment_void_instr(target);
|
||||||
}
|
}
|
||||||
@@ -252,7 +247,8 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
Self::add_or_increment_void_instr(target);
|
Self::add_or_increment_void_instr(target);
|
||||||
}
|
}
|
||||||
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
|
&Term::Cons(ref cell, _, _) | &Term::Clause(ref cell, _, _, _) => {
|
||||||
self.marker.mark_non_var(Level::Deep, term_loc, cell, target);
|
self.marker
|
||||||
|
.mark_non_var(Level::Deep, term_loc, cell, target);
|
||||||
target.push(Target::clause_arg_to_instr(cell.get()));
|
target.push(Target::clause_arg_to_instr(cell.get()));
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref constant) => {
|
&Term::Constant(_, ref constant) => {
|
||||||
@@ -264,7 +260,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_target<Target, Iter>(
|
fn compile_target<Target, Iter>(
|
||||||
&mut self,
|
&mut self,
|
||||||
iter: Iter,
|
iter: Iter,
|
||||||
term_loc: GenContext,
|
term_loc: GenContext,
|
||||||
@@ -334,13 +330,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
self.marker
|
||||||
|
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||||
}
|
}
|
||||||
TermRef::Var(lvl @ Level::Shallow, cell, var) => {
|
TermRef::Var(lvl @ Level::Shallow, cell, var) => {
|
||||||
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
self.marker
|
||||||
}
|
.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
|
||||||
_ => {
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,8 +350,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
|
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
|
||||||
for (i, chunked_term) in chunked_terms.iter().enumerate() {
|
for (i, chunked_term) in chunked_terms.iter().enumerate() {
|
||||||
let term_loc = match chunked_term {
|
let term_loc = match chunked_term {
|
||||||
&ChunkedTerm::HeadClause(..) =>
|
&ChunkedTerm::HeadClause(..) => GenContext::Head,
|
||||||
GenContext::Head,
|
|
||||||
&ChunkedTerm::BodyTerm(_) => {
|
&ChunkedTerm::BodyTerm(_) => {
|
||||||
if i < chunked_terms.len() - 1 {
|
if i < chunked_terms.len() - 1 {
|
||||||
GenContext::Mid(chunk_num)
|
GenContext::Mid(chunk_num)
|
||||||
@@ -391,8 +387,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
&QueryTerm::Clause(_, ref ct, ref terms, false) => {
|
||||||
code.push(call_clause!(ct.clone(), terms.len(), pvs));
|
code.push(call_clause!(ct.clone(), terms.len(), pvs));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,8 +402,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
|
&mut ControlInstruction::JmpBy(_, _, _, ref mut last_call) => {
|
||||||
*last_call = true;
|
*last_call = true;
|
||||||
}
|
}
|
||||||
&mut ControlInstruction::Proceed => {
|
&mut ControlInstruction::Proceed => {}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
dealloc_index += 1;
|
dealloc_index += 1;
|
||||||
}
|
}
|
||||||
@@ -416,8 +410,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
Some(&mut Line::Cut(CutInstruction::Cut(_))) => {
|
||||||
dealloc_index += 1;
|
dealloc_index += 1;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dealloc_index
|
dealloc_index
|
||||||
@@ -437,23 +430,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
let (mut lcode, at_1) = self.call_arith_eval(terms[0].as_ref(), 1)?;
|
||||||
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
let (mut rcode, at_2) = self.call_arith_eval(terms[1].as_ref(), 2)?;
|
||||||
|
|
||||||
let at_1 =
|
let at_1 = if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
|
||||||
if let &Term::Var(ref vr, ref name) = terms[0].as_ref() {
|
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code))
|
||||||
ArithmeticTerm::Reg(
|
} else {
|
||||||
self.mark_non_callable(name.clone(), 1, term_loc, vr, code)
|
at_1.unwrap_or(interm!(1))
|
||||||
)
|
};
|
||||||
} else {
|
|
||||||
at_1.unwrap_or(interm!(1))
|
|
||||||
};
|
|
||||||
|
|
||||||
let at_2 =
|
let at_2 = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
||||||
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
|
||||||
ArithmeticTerm::Reg(
|
} else {
|
||||||
self.mark_non_callable(name.clone(), 2, term_loc, vr, code)
|
at_2.unwrap_or(interm!(2))
|
||||||
)
|
};
|
||||||
} else {
|
|
||||||
at_2.unwrap_or(interm!(2))
|
|
||||||
};
|
|
||||||
|
|
||||||
code.append(&mut lcode);
|
code.append(&mut lcode);
|
||||||
code.append(&mut rcode);
|
code.append(&mut rcode);
|
||||||
@@ -461,9 +448,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code.push(compare_number_instr!(cmp, at_1, at_2));
|
code.push(compare_number_instr!(cmp, at_1, at_2));
|
||||||
}
|
}
|
||||||
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsAtom(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Char(_)) |
|
&Term::Constant(_, Constant::Char(_))
|
||||||
&Term::Constant(_, Constant::EmptyList) |
|
| &Term::Constant(_, Constant::EmptyList)
|
||||||
&Term::Constant(_, Constant::Atom(..)) => {
|
| &Term::Constant(_, Constant::Atom(..)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -528,11 +515,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsNumber(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Float(_)) |
|
&Term::Constant(_, Constant::Float(_))
|
||||||
&Term::Constant(_, Constant::Rational(_)) |
|
| &Term::Constant(_, Constant::Rational(_))
|
||||||
&Term::Constant(_, Constant::Integer(_)) |
|
| &Term::Constant(_, Constant::Integer(_))
|
||||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
| &Term::Constant(_, Constant::Fixnum(_))
|
||||||
&Term::Constant(_, Constant::Usize(_)) => {
|
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -558,9 +545,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Integer(_)) |
|
&Term::Constant(_, Constant::Integer(_))
|
||||||
&Term::Constant(_, Constant::Fixnum(_)) |
|
| &Term::Constant(_, Constant::Fixnum(_))
|
||||||
&Term::Constant(_, Constant::Usize(_)) => {
|
| &Term::Constant(_, Constant::Usize(_)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -615,14 +602,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
let mut target = vec![];
|
let mut target = vec![];
|
||||||
|
|
||||||
self.marker.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
|
self.marker
|
||||||
|
.mark_var(name.clone(), Level::Shallow, vr, term_loc, &mut target);
|
||||||
|
|
||||||
if !target.is_empty() {
|
if !target.is_empty() {
|
||||||
code.extend(target.into_iter().map(Line::Query));
|
code.extend(target.into_iter().map(Line::Query));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref c @ Constant::Integer(_)) |
|
&Term::Constant(_, ref c @ Constant::Integer(_))
|
||||||
&Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
| &Term::Constant(_, ref c @ Constant::Fixnum(_)) => {
|
||||||
code.push(Line::Query(put_constant!(
|
code.push(Line::Query(put_constant!(
|
||||||
Level::Shallow,
|
Level::Shallow,
|
||||||
c.clone(),
|
c.clone(),
|
||||||
@@ -655,14 +643,11 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let at =
|
let at = if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
||||||
if let &Term::Var(ref vr, ref name) = terms[1].as_ref() {
|
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
|
||||||
ArithmeticTerm::Reg(
|
} else {
|
||||||
self.mark_non_callable(name.clone(), 2, term_loc, vr, code)
|
at.unwrap_or(interm!(1))
|
||||||
)
|
};
|
||||||
} else {
|
|
||||||
at.unwrap_or(interm!(1))
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(if use_default_call_policy {
|
Ok(if use_default_call_policy {
|
||||||
code.push(is_call_by_default!(temp_v!(1), at));
|
code.push(is_call_by_default!(temp_v!(1), at));
|
||||||
@@ -721,24 +706,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
|
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
|
||||||
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
|
self.compile_get_level_and_unify(code, cell, var.clone(), term_loc)
|
||||||
}
|
}
|
||||||
&QueryTerm::UnblockedCut(ref cell) => {
|
&QueryTerm::UnblockedCut(ref cell) => self.compile_unblocked_cut(code, cell),
|
||||||
self.compile_unblocked_cut(code, cell)
|
&QueryTerm::BlockedCut => code.push(if chunk_num == 0 {
|
||||||
}
|
Line::Cut(CutInstruction::NeckCut)
|
||||||
&QueryTerm::BlockedCut => {
|
} else {
|
||||||
code.push(if chunk_num == 0 {
|
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
||||||
Line::Cut(CutInstruction::NeckCut)
|
}),
|
||||||
} else {
|
|
||||||
Line::Cut(CutInstruction::Cut(perm_v!(1)))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
&QueryTerm::Clause(
|
&QueryTerm::Clause(
|
||||||
_,
|
_,
|
||||||
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
ClauseType::BuiltIn(BuiltInClauseType::Is(..)),
|
||||||
ref terms,
|
ref terms,
|
||||||
use_default_call_policy,
|
use_default_call_policy,
|
||||||
) => {
|
) => self.compile_is_call(terms, code, term_loc, use_default_call_policy)?,
|
||||||
self.compile_is_call(terms, code, term_loc, use_default_call_policy)?
|
|
||||||
}
|
|
||||||
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
|
&QueryTerm::Clause(_, ClauseType::Inlined(ref ct), ref terms, _) => {
|
||||||
self.compile_inlined(ct, terms, term_loc, code)?
|
self.compile_inlined(ct, terms, term_loc, code)?
|
||||||
}
|
}
|
||||||
@@ -772,7 +751,12 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_cleanup(&mut self, code: &mut Code, conjunct_info: &ConjunctInfo, toc: &'a QueryTerm) {
|
fn compile_cleanup(
|
||||||
|
&mut self,
|
||||||
|
code: &mut Code,
|
||||||
|
conjunct_info: &ConjunctInfo,
|
||||||
|
toc: &'a QueryTerm,
|
||||||
|
) {
|
||||||
// add a proceed to bookend any trailing cuts.
|
// add a proceed to bookend any trailing cuts.
|
||||||
match toc {
|
match toc {
|
||||||
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
&QueryTerm::BlockedCut | &QueryTerm::UnblockedCut(..) => code.push(proceed!()),
|
||||||
@@ -786,7 +770,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
if conjunct_info.allocates() {
|
if conjunct_info.allocates() {
|
||||||
let offset = self.global_jmp_by_locs_offset;
|
let offset = self.global_jmp_by_locs_offset;
|
||||||
|
|
||||||
if let Some(jmp_by_offset) = self.jmp_by_locs[offset ..].last_mut() {
|
if let Some(jmp_by_offset) = self.jmp_by_locs[offset..].last_mut() {
|
||||||
if *jmp_by_offset == dealloc_index {
|
if *jmp_by_offset == dealloc_index {
|
||||||
*jmp_by_offset += 1;
|
*jmp_by_offset += 1;
|
||||||
}
|
}
|
||||||
@@ -905,32 +889,32 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
self.add_conditional_call(code, term, num_perm_vars_left);
|
self.add_conditional_call(code, term, num_perm_vars_left);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
|
pub fn compile_query(&mut self, query: &'a Vec<QueryTerm>) -> Result<Code, CompilationError> {
|
||||||
let iter = ChunkedIterator::from_term_sequence(query);
|
let iter = ChunkedIterator::from_term_sequence(query);
|
||||||
let conjunct_info = self.collect_var_data(iter);
|
let conjunct_info = self.collect_var_data(iter);
|
||||||
|
|
||||||
let mut code = Vec::new();
|
let mut code = Vec::new();
|
||||||
self.compile_seq_prelude(&conjunct_info, &mut code);
|
self.compile_seq_prelude(&conjunct_info, &mut code);
|
||||||
|
|
||||||
let iter = ChunkedIterator::from_term_sequence(query);
|
let iter = ChunkedIterator::from_term_sequence(query);
|
||||||
self.compile_seq(iter, &conjunct_info, &mut code, true)?;
|
self.compile_seq(iter, &conjunct_info, &mut code, true)?;
|
||||||
|
|
||||||
conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code);
|
conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code);
|
||||||
|
|
||||||
if let Some(query_term) = query.last() {
|
if let Some(query_term) = query.last() {
|
||||||
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(code)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Ok(code)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn increment_jmp_by_locs_by(&mut self, incr: usize) {
|
fn increment_jmp_by_locs_by(&mut self, incr: usize) {
|
||||||
let offset = self.global_jmp_by_locs_offset;
|
let offset = self.global_jmp_by_locs_offset;
|
||||||
|
|
||||||
for loc in &mut self.jmp_by_locs[offset ..] {
|
for loc in &mut self.jmp_by_locs[offset..] {
|
||||||
*loc += incr;
|
*loc += incr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1077,7 +1061,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
|
|
||||||
if skip_stub_try_me_else {
|
if skip_stub_try_me_else {
|
||||||
// skip the TryMeElse(0) also.
|
// skip the TryMeElse(0) also.
|
||||||
self.increment_jmp_by_locs_by(2);
|
self.increment_jmp_by_locs_by(2);
|
||||||
} else {
|
} else {
|
||||||
self.increment_jmp_by_locs_by(1);
|
self.increment_jmp_by_locs_by(1);
|
||||||
}
|
}
|
||||||
@@ -1105,7 +1089,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
|
|
||||||
for (l, r) in split_pred {
|
for (l, r) in split_pred {
|
||||||
let skel_lower_bound = self.skeleton.clauses.len();
|
let skel_lower_bound = self.skeleton.clauses.len();
|
||||||
let code_segment = self.compile_pred_subseq(&clauses[l .. r], optimal_index)?;
|
let code_segment = self.compile_pred_subseq(&clauses[l..r], optimal_index)?;
|
||||||
let clause_start_offset = code.len();
|
let clause_start_offset = code.len();
|
||||||
|
|
||||||
if multi_seq {
|
if multi_seq {
|
||||||
@@ -1123,11 +1107,10 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
if self.is_extensible {
|
if self.is_extensible {
|
||||||
let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some();
|
let segment_is_indexed = to_indexing_line(&code_segment[0]).is_some();
|
||||||
|
|
||||||
for clause_index_info in self.skeleton.clauses[skel_lower_bound ..].iter_mut() {
|
for clause_index_info in self.skeleton.clauses[skel_lower_bound..].iter_mut() {
|
||||||
clause_index_info.clause_start +=
|
clause_index_info.clause_start +=
|
||||||
clause_start_offset + 2 * (segment_is_indexed as usize);
|
clause_start_offset + 2 * (segment_is_indexed as usize);
|
||||||
clause_index_info.opt_arg_index_key +=
|
clause_index_info.opt_arg_index_key += clause_start_offset + 1;
|
||||||
clause_start_offset + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::temp_v;
|
||||||
|
|
||||||
use crate::allocator::*;
|
use crate::allocator::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
@@ -293,9 +294,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
|
|||||||
|
|
||||||
(pr, true)
|
(pr, true)
|
||||||
}
|
}
|
||||||
r => {
|
r => (r, false),
|
||||||
(r, false)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::instructions::*;
|
use crate::instructions::*;
|
||||||
use crate::iterators::*;
|
use crate::iterators::*;
|
||||||
|
|
||||||
use crate::indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
@@ -83,18 +83,17 @@ impl TempVarData {
|
|||||||
type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
|
type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VariableFixtures<'a>{
|
pub struct VariableFixtures<'a> {
|
||||||
perm_vars: IndexMap<Rc<Var>, VariableFixture<'a>>,
|
perm_vars: IndexMap<Rc<Var>, VariableFixture<'a>>,
|
||||||
last_chunk_temp_vars: IndexSet<Rc<Var>>
|
last_chunk_temp_vars: IndexSet<Rc<Var>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> VariableFixtures<'a> {
|
impl<'a> VariableFixtures<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
VariableFixtures {
|
VariableFixtures {
|
||||||
perm_vars: IndexMap::new(),
|
perm_vars: IndexMap::new(),
|
||||||
last_chunk_temp_vars: IndexSet::new()
|
last_chunk_temp_vars: IndexSet::new(),
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, var: Rc<Var>, vs: VariableFixture<'a>) {
|
pub fn insert(&mut self, var: Rc<Var>, vs: VariableFixture<'a>) {
|
||||||
@@ -262,34 +261,32 @@ impl UnsafeVarMarker {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
UnsafeVarMarker {
|
UnsafeVarMarker {
|
||||||
unsafe_vars: IndexMap::new(),
|
unsafe_vars: IndexMap::new(),
|
||||||
safe_vars: IndexSet::new()
|
safe_vars: IndexSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_safe_vars(safe_vars: IndexSet<RegType>) -> Self {
|
pub fn from_safe_vars(safe_vars: IndexSet<RegType>) -> Self {
|
||||||
UnsafeVarMarker {
|
UnsafeVarMarker {
|
||||||
unsafe_vars: IndexMap::new(),
|
unsafe_vars: IndexMap::new(),
|
||||||
safe_vars
|
safe_vars,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) -> bool {
|
pub fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) -> bool {
|
||||||
match query_instr {
|
match query_instr {
|
||||||
&QueryInstruction::PutVariable(r @ RegType::Temp(_), _)
|
&QueryInstruction::PutVariable(r @ RegType::Temp(_), _)
|
||||||
| &QueryInstruction::SetVariable(r) => {
|
| &QueryInstruction::SetVariable(r) => {
|
||||||
self.safe_vars.insert(r);
|
self.safe_vars.insert(r);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => {
|
_ => false,
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark_phase(&mut self, query_instr: &QueryInstruction, phase: usize) {
|
pub fn mark_phase(&mut self, query_instr: &QueryInstruction, phase: usize) {
|
||||||
match query_instr {
|
match query_instr {
|
||||||
&QueryInstruction::PutValue(r @ RegType::Perm(_), _)
|
&QueryInstruction::PutValue(r @ RegType::Perm(_), _)
|
||||||
| &QueryInstruction::SetValue(r) => {
|
| &QueryInstruction::SetValue(r) => {
|
||||||
let p = self.unsafe_vars.entry(r).or_insert(0);
|
let p = self.unsafe_vars.entry(r).or_insert(0);
|
||||||
*p = phase;
|
*p = phase;
|
||||||
}
|
}
|
||||||
|
|||||||
170
src/forms.rs
170
src/forms.rs
@@ -1,13 +1,14 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::parser::OpDesc;
|
use prolog_parser::parser::OpDesc;
|
||||||
|
use prolog_parser::{clause_name, is_infix, is_postfix};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::ordered_float::OrderedFloat;
|
|
||||||
use crate::rug::{Integer, Rational};
|
use crate::rug::{Integer, Rational};
|
||||||
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use crate::indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
|
||||||
use slice_deque::*;
|
use slice_deque::*;
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ pub enum TopLevel {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum AppendOrPrepend {
|
pub enum AppendOrPrepend {
|
||||||
Append,
|
Append,
|
||||||
Prepend
|
Prepend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppendOrPrepend {
|
impl AppendOrPrepend {
|
||||||
@@ -115,12 +116,8 @@ impl ListingSource {
|
|||||||
pub trait ClauseInfo {
|
pub trait ClauseInfo {
|
||||||
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
|
fn is_consistent(&self, clauses: &Vec<PredicateClause>) -> bool {
|
||||||
match clauses.first() {
|
match clauses.first() {
|
||||||
Some(cl) => {
|
Some(cl) => self.name() == cl.name() && self.arity() == cl.arity(),
|
||||||
self.name() == cl.name() && self.arity() == cl.arity()
|
None => true,
|
||||||
}
|
|
||||||
None => {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,38 +137,25 @@ impl ClauseInfo for Term {
|
|||||||
_ => Some(clause_name!(":-")),
|
_ => Some(clause_name!(":-")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Some(name.clone()),
|
||||||
Some(name.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
Term::Constant(_, Constant::Atom(ref name, _)) => Some(name.clone()),
|
||||||
Some(name.clone())
|
_ => None,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Term::Clause(_, ref name, ref terms, _) =>
|
Term::Clause(_, ref name, ref terms, _) => match name.as_str() {
|
||||||
match name.as_str() {
|
":-" => match terms.len() {
|
||||||
":-" => {
|
1 => 0,
|
||||||
match terms.len() {
|
2 => terms[0].arity(),
|
||||||
1 => 0,
|
_ => terms.len(),
|
||||||
2 => terms[0].arity(),
|
|
||||||
_ => terms.len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
terms.len()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => terms.len(),
|
||||||
0
|
},
|
||||||
}
|
_ => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,23 +173,15 @@ impl ClauseInfo for Rule {
|
|||||||
impl ClauseInfo for PredicateClause {
|
impl ClauseInfo for PredicateClause {
|
||||||
fn name(&self) -> Option<ClauseName> {
|
fn name(&self) -> Option<ClauseName> {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => {
|
&PredicateClause::Fact(ref term, ..) => term.name(),
|
||||||
term.name()
|
&PredicateClause::Rule(ref rule, ..) => rule.name(),
|
||||||
}
|
|
||||||
&PredicateClause::Rule(ref rule, ..) => {
|
|
||||||
rule.name()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => {
|
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||||
term.arity()
|
&PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
||||||
}
|
|
||||||
&PredicateClause::Rule(ref rule, ..) => {
|
|
||||||
rule.arity()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,11 +198,9 @@ impl PredicateClause {
|
|||||||
// TODO: add this to `Term` in `prolog_parser` like `first_arg`.
|
// TODO: add this to `Term` in `prolog_parser` like `first_arg`.
|
||||||
pub fn args(&self) -> Option<&[Box<Term>]> {
|
pub fn args(&self) -> Option<&[Box<Term>]> {
|
||||||
match *self {
|
match *self {
|
||||||
PredicateClause::Fact(ref term, ..) => {
|
PredicateClause::Fact(ref term, ..) => match term {
|
||||||
match term {
|
Term::Clause(_, _, args, _) => Some(&args),
|
||||||
Term::Clause(_, _, args, _) => Some(&args),
|
_ => None,
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
PredicateClause::Rule(ref rule, ..) => {
|
PredicateClause::Rule(ref rule, ..) => {
|
||||||
if rule.head.1.is_empty() {
|
if rule.head.1.is_empty() {
|
||||||
@@ -240,14 +214,11 @@ impl PredicateClause {
|
|||||||
|
|
||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => {
|
&PredicateClause::Fact(ref term, ..) => term.arity(),
|
||||||
term.arity()
|
|
||||||
}
|
|
||||||
&PredicateClause::Rule(ref rule, ..) => {
|
&PredicateClause::Rule(ref rule, ..) => {
|
||||||
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
|
if rule.head.0.as_str() == ":" && rule.head.1.len() == 2 {
|
||||||
match (rule.head.1)[0].as_ref() {
|
match (rule.head.1)[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::Atom(..)) => {
|
&Term::Constant(_, Constant::Atom(..)) => {}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@@ -321,7 +292,7 @@ pub enum Declaration {
|
|||||||
pub struct OpDecl {
|
pub struct OpDecl {
|
||||||
pub prec: usize,
|
pub prec: usize,
|
||||||
pub spec: Specifier,
|
pub spec: Specifier,
|
||||||
pub name: ClauseName
|
pub name: ClauseName,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpDecl {
|
impl OpDecl {
|
||||||
@@ -345,7 +316,7 @@ impl OpDecl {
|
|||||||
XFY | XFX | YFX => Fixity::In,
|
XFY | XFX | YFX => Fixity::In,
|
||||||
XF | YF => Fixity::Post,
|
XF | YF => Fixity::Post,
|
||||||
FX | FY => Fixity::Pre,
|
FX | FY => Fixity::Pre,
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,12 +327,12 @@ impl OpDecl {
|
|||||||
Some(cell) => {
|
Some(cell) => {
|
||||||
return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
|
return Some(cell.shared_op_desc().replace((self.prec, self.spec)));
|
||||||
}
|
}
|
||||||
None => {
|
None => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op_dir.insert(key, OpDirValue::new(self.spec, self.prec))
|
op_dir
|
||||||
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
.insert(key, OpDirValue::new(self.spec, self.prec))
|
||||||
|
.map(|op_dir_value| op_dir_value.shared_op_desc().get())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn submit(
|
pub fn submit(
|
||||||
@@ -419,11 +390,7 @@ pub fn fetch_op_spec_from_existing(
|
|||||||
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
spec.or_else(|| fetch_op_spec(name, arity, op_dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_op_spec(
|
pub fn fetch_op_spec(name: ClauseName, arity: usize, op_dir: &OpDir) -> Option<SharedOpDesc> {
|
||||||
name: ClauseName,
|
|
||||||
arity: usize,
|
|
||||||
op_dir: &OpDir,
|
|
||||||
) -> Option<SharedOpDesc> {
|
|
||||||
match arity {
|
match arity {
|
||||||
2 => op_dir
|
2 => op_dir
|
||||||
.get(&(name, Fixity::In))
|
.get(&(name, Fixity::In))
|
||||||
@@ -451,9 +418,7 @@ pub fn fetch_op_spec(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +464,6 @@ impl Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Number {
|
pub enum Number {
|
||||||
Float(OrderedFloat<f64>),
|
Float(OrderedFloat<f64>),
|
||||||
@@ -559,7 +523,6 @@ impl Into<HeapCellValue> for Number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Number {
|
impl Number {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_positive(&self) -> bool {
|
pub fn is_positive(&self) -> bool {
|
||||||
@@ -594,12 +557,13 @@ impl Number {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn abs(self) -> Self {
|
pub fn abs(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Number::Fixnum(n) =>
|
Number::Fixnum(n) => {
|
||||||
if let Some(n) = n.checked_abs() {
|
if let Some(n) = n.checked_abs() {
|
||||||
Number::from(n)
|
Number::from(n)
|
||||||
} else {
|
} else {
|
||||||
Number::from(Integer::from(n).abs())
|
Number::from(Integer::from(n).abs())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
|
Number::Integer(n) => Number::from(Integer::from(n.abs_ref())),
|
||||||
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
|
Number::Float(f) => Number::Float(OrderedFloat(f.abs())),
|
||||||
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
|
Number::Rational(r) => Number::from(Rational::from(r.abs_ref())),
|
||||||
@@ -624,15 +588,13 @@ impl OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn arg_num(&self) -> usize {
|
pub fn arg_num(&self) -> usize {
|
||||||
match &self {
|
match &self {
|
||||||
OptArgIndexKey::Constant(arg_num, ..) |
|
OptArgIndexKey::Constant(arg_num, ..)
|
||||||
OptArgIndexKey::Structure(arg_num, ..) |
|
| OptArgIndexKey::Structure(arg_num, ..)
|
||||||
OptArgIndexKey::List(arg_num, _) => {
|
| OptArgIndexKey::List(arg_num, _) => {
|
||||||
// these are always at least 1.
|
// these are always at least 1.
|
||||||
*arg_num
|
*arg_num
|
||||||
}
|
}
|
||||||
OptArgIndexKey::None => {
|
OptArgIndexKey::None => 0,
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,27 +606,22 @@ impl OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn switch_on_term_loc(&self) -> Option<usize> {
|
pub fn switch_on_term_loc(&self) -> Option<usize> {
|
||||||
match &self {
|
match &self {
|
||||||
OptArgIndexKey::Constant(_, loc, ..) |
|
OptArgIndexKey::Constant(_, loc, ..)
|
||||||
OptArgIndexKey::Structure(_, loc, ..) |
|
| OptArgIndexKey::Structure(_, loc, ..)
|
||||||
OptArgIndexKey::List(_, loc) => {
|
| OptArgIndexKey::List(_, loc) => Some(*loc),
|
||||||
Some(*loc)
|
OptArgIndexKey::None => None,
|
||||||
}
|
|
||||||
OptArgIndexKey::None => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_switch_on_term_loc(&mut self, value: usize) {
|
pub fn set_switch_on_term_loc(&mut self, value: usize) {
|
||||||
match self {
|
match self {
|
||||||
OptArgIndexKey::Constant(_, ref mut loc, ..) |
|
OptArgIndexKey::Constant(_, ref mut loc, ..)
|
||||||
OptArgIndexKey::Structure(_, ref mut loc, ..) |
|
| OptArgIndexKey::Structure(_, ref mut loc, ..)
|
||||||
OptArgIndexKey::List(_, ref mut loc) => {
|
| OptArgIndexKey::List(_, ref mut loc) => {
|
||||||
*loc = value;
|
*loc = value;
|
||||||
}
|
}
|
||||||
OptArgIndexKey::None => {
|
OptArgIndexKey::None => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -673,13 +630,12 @@ impl AddAssign<usize> for OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, n: usize) {
|
fn add_assign(&mut self, n: usize) {
|
||||||
match self {
|
match self {
|
||||||
OptArgIndexKey::Constant(_, ref mut o, ..) |
|
OptArgIndexKey::Constant(_, ref mut o, ..)
|
||||||
OptArgIndexKey::List(_, ref mut o) |
|
| OptArgIndexKey::List(_, ref mut o)
|
||||||
OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
| OptArgIndexKey::Structure(_, ref mut o, ..) => {
|
||||||
*o += n;
|
*o += n;
|
||||||
}
|
}
|
||||||
OptArgIndexKey::None => {
|
OptArgIndexKey::None => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -755,5 +711,21 @@ impl PredicateSkeleton {
|
|||||||
clauses: self.clauses,
|
clauses: self.clauses,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pub fn target_pos_of_clause_clause_loc(
|
||||||
|
&self,
|
||||||
|
clause_clause_loc: usize,
|
||||||
|
clause_assert_margin: usize,
|
||||||
|
) -> usize {
|
||||||
|
let search_result = self.clause_clause_locs[0..clause_assert_margin]
|
||||||
|
.binary_search_by(|loc| clause_clause_loc.cmp(&loc));
|
||||||
|
|
||||||
|
search_result.unwrap_or_else(|_| {
|
||||||
|
self.clause_clause_locs[clause_assert_margin..]
|
||||||
|
.binary_search_by(|loc| loc.cmp(&clause_clause_loc))
|
||||||
|
.unwrap()
|
||||||
|
+ clause_assert_margin
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
|
|
||||||
use crate::indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@@ -29,31 +29,21 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
fn follow_heap(&mut self, h: usize) -> Addr {
|
fn follow_heap(&mut self, h: usize) -> Addr {
|
||||||
match &self.machine_st.heap[h] {
|
match &self.machine_st.heap[h] {
|
||||||
&HeapCellValue::NamedStr(arity, _, _) => {
|
&HeapCellValue::NamedStr(arity, _, _) => {
|
||||||
for idx in (1 .. arity + 1).rev() {
|
for idx in (1..arity + 1).rev() {
|
||||||
self.state_stack.push(Addr::HeapCell(h + idx));
|
self.state_stack.push(Addr::HeapCell(h + idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr::Str(h)
|
Addr::Str(h)
|
||||||
}
|
}
|
||||||
&HeapCellValue::Addr(a) => {
|
&HeapCellValue::Addr(a) => self.follow(a),
|
||||||
self.follow(a)
|
HeapCellValue::PartialString(..) => self.follow(Addr::PStrLocation(h, 0)),
|
||||||
}
|
HeapCellValue::Atom(..)
|
||||||
HeapCellValue::PartialString(..) => {
|
| HeapCellValue::DBRef(_)
|
||||||
self.follow(Addr::PStrLocation(h, 0))
|
| HeapCellValue::Integer(_)
|
||||||
}
|
| HeapCellValue::Rational(_) => Addr::Con(h),
|
||||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(_)
|
HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(h),
|
||||||
| HeapCellValue::Integer(_) | HeapCellValue::Rational(_) => {
|
HeapCellValue::Stream(_) => Addr::Stream(h),
|
||||||
Addr::Con(h)
|
HeapCellValue::TcpListener(_) => Addr::TcpListener(h),
|
||||||
}
|
|
||||||
HeapCellValue::LoadStatePayload(_) => {
|
|
||||||
Addr::LoadStatePayload(h)
|
|
||||||
}
|
|
||||||
HeapCellValue::Stream(_) => {
|
|
||||||
Addr::Stream(h)
|
|
||||||
}
|
|
||||||
HeapCellValue::TcpListener(_) => {
|
|
||||||
Addr::TcpListener(h)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +61,12 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
da
|
da
|
||||||
}
|
}
|
||||||
Addr::PStrLocation(h, n) => {
|
Addr::PStrLocation(h, n) => {
|
||||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h]
|
||||||
if let Some(c) = pstr.range_from(n ..).next() {
|
{
|
||||||
|
if let Some(c) = pstr.range_from(n..).next() {
|
||||||
if !pstr.at_end(n + c.len_utf8()) {
|
if !pstr.at_end(n + c.len_utf8()) {
|
||||||
self.state_stack.push(Addr::PStrLocation(h, n + c.len_utf8()));
|
self.state_stack
|
||||||
|
.push(Addr::PStrLocation(h, n + c.len_utf8()));
|
||||||
} else if has_tail {
|
} else if has_tail {
|
||||||
self.state_stack.push(Addr::HeapCell(h + 1));
|
self.state_stack.push(Addr::HeapCell(h + 1));
|
||||||
} else {
|
} else {
|
||||||
@@ -95,8 +87,9 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
self.follow_heap(s) // record terms of structure.
|
self.follow_heap(s) // record terms of structure.
|
||||||
}
|
}
|
||||||
Addr::Con(h) => {
|
Addr::Con(h) => {
|
||||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h] {
|
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &self.machine_st.heap[h]
|
||||||
if let Some(c) = pstr.range_from(0 ..).next() {
|
{
|
||||||
|
if let Some(c) = pstr.range_from(0..).next() {
|
||||||
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
|
self.state_stack.push(Addr::PStrLocation(h, c.len_utf8()));
|
||||||
self.state_stack.push(Addr::Char(c));
|
self.state_stack.push(Addr::Char(c));
|
||||||
|
|
||||||
@@ -110,9 +103,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
Addr::Con(h)
|
Addr::Con(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
da => {
|
da => da,
|
||||||
da
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +116,9 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MutStackHCIterator<'b> where Self: Iterator
|
pub trait MutStackHCIterator<'b>
|
||||||
|
where
|
||||||
|
Self: Iterator,
|
||||||
{
|
{
|
||||||
type MutStack;
|
type MutStack;
|
||||||
|
|
||||||
@@ -178,7 +171,8 @@ impl<'a> Iterator for HCPostOrderIterator<'a> {
|
|||||||
}
|
}
|
||||||
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
&HeapCellValue::Addr(Addr::PStrLocation(h, n)) => {
|
||||||
match &self.machine_st.heap[h] {
|
match &self.machine_st.heap[h] {
|
||||||
&HeapCellValue::PartialString(..) => {// ref pstr, _) => {
|
&HeapCellValue::PartialString(..) => {
|
||||||
|
// ref pstr, _) => {
|
||||||
/*
|
/*
|
||||||
let c = pstr.range_from(n ..).next().unwrap();
|
let c = pstr.range_from(n ..).next().unwrap();
|
||||||
let next_n = n + c.len_utf8();
|
let next_n = n + c.len_utf8();
|
||||||
@@ -215,7 +209,7 @@ impl MachineState {
|
|||||||
HCPostOrderIterator::new(HCPreOrderIterator::new(self, a))
|
HCPostOrderIterator::new(HCPreOrderIterator::new(self, a))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr,) -> HCAcyclicIterator<'a> {
|
pub fn acyclic_pre_order_iter<'a>(&'a self, a: Addr) -> HCAcyclicIterator<'a> {
|
||||||
HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
|
HCAcyclicIterator::new(HCPreOrderIterator::new(self, a))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,8 +264,7 @@ impl<'b, 'a: 'b> MutStackHCIterator<'b> for HCAcyclicIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for HCAcyclicIterator<'a>
|
impl<'a> Iterator for HCAcyclicIterator<'a> {
|
||||||
{
|
|
||||||
type Item = Addr;
|
type Item = Addr;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -315,8 +308,7 @@ impl<'a> HCZippedAcyclicIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for HCZippedAcyclicIterator<'a>
|
impl<'a> Iterator for HCZippedAcyclicIterator<'a> {
|
||||||
{
|
|
||||||
type Item = (Addr, Addr);
|
type Item = (Addr, Addr);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -341,9 +333,7 @@ impl<'a> Iterator for HCZippedAcyclicIterator<'a>
|
|||||||
self.first_to_expire = Ordering::Less;
|
self.first_to_expire = Ordering::Less;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::{
|
||||||
|
alpha_numeric_char, capital_letter_char, clause_name, cut_char, decimal_digit_char,
|
||||||
|
graphic_token_char, is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx,
|
||||||
|
semicolon_char, sign_char, single_quote_char, small_letter_char, solo_char,
|
||||||
|
variable_indicator_char,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -7,14 +13,14 @@ use crate::machine::heap::*;
|
|||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
use crate::machine::streams::*;
|
use crate::machine::streams::*;
|
||||||
use crate::ordered_float::OrderedFloat;
|
|
||||||
use crate::rug::{Integer, Rational};
|
use crate::rug::{Integer, Rational};
|
||||||
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use crate::indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::iter::{FromIterator, once};
|
use std::iter::{once, FromIterator};
|
||||||
use std::net::{IpAddr, TcpListener};
|
use std::net::{IpAddr, TcpListener};
|
||||||
use std::ops::{Range, RangeFrom};
|
use std::ops::{Range, RangeFrom};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -99,10 +105,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parent_spec = DirectedOp::Left(
|
let mut parent_spec = DirectedOp::Left(clause_name!("-"), SharedOpDesc::new(200, FY));
|
||||||
clause_name!("-"),
|
|
||||||
SharedOpDesc::new(200, FY),
|
|
||||||
);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.machine_st.store(self.machine_st.deref(addr)) {
|
match self.machine_st.store(self.machine_st.deref(addr)) {
|
||||||
@@ -154,12 +157,13 @@ fn char_to_string(is_quoted: bool, c: char) -> String {
|
|||||||
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
|
'\u{07}' if is_quoted => "\\a".to_string(), // UTF-8 alert
|
||||||
'"' if is_quoted => "\\\"".to_string(),
|
'"' if is_quoted => "\\\"".to_string(),
|
||||||
'\\' if is_quoted => "\\\\".to_string(),
|
'\\' if is_quoted => "\\\\".to_string(),
|
||||||
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' =>
|
'\'' | '\n' | '\r' | '\t' | '\u{0b}' | '\u{0c}' | '\u{08}' | '\u{07}' | '"' | '\\' => {
|
||||||
c.to_string(),
|
c.to_string()
|
||||||
'\u{a0}' ..= '\u{d6}' => c.to_string(),
|
}
|
||||||
'\u{d8}' ..= '\u{f6}' => c.to_string(),
|
'\u{a0}'..='\u{d6}' => c.to_string(),
|
||||||
'\u{f8}' ..= '\u{74f}' => c.to_string(),
|
'\u{d8}'..='\u{f6}' => c.to_string(),
|
||||||
'\x20' ..= '\x7e' => c.to_string(),
|
'\u{f8}'..='\u{74f}' => c.to_string(),
|
||||||
|
'\x20'..='\x7e' => c.to_string(),
|
||||||
_ => format!("\\x{:x}\\", c as u32),
|
_ => format!("\\x{:x}\\", c as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,25 +275,13 @@ fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp>) -> bool {
|
||||||
if let Some(ref op) = op {
|
if let Some(ref op) = op {
|
||||||
op.is_negative_sign() &&
|
op.is_negative_sign()
|
||||||
iter.leftmost_leaf_has_property(|addr, heap| {
|
&& iter.leftmost_leaf_has_property(|addr, heap| match Number::try_from((addr, heap)) {
|
||||||
match Number::try_from((addr, heap)) {
|
Ok(Number::Fixnum(n)) => n > 0,
|
||||||
Ok(Number::Fixnum(n)) => {
|
Ok(Number::Float(f)) => f > OrderedFloat(0f64),
|
||||||
n > 0
|
Ok(Number::Integer(n)) => &*n > &0,
|
||||||
}
|
Ok(Number::Rational(n)) => &*n > &0,
|
||||||
Ok(Number::Float(f)) => {
|
_ => false,
|
||||||
f > OrderedFloat(0f64)
|
|
||||||
}
|
|
||||||
Ok(Number::Integer(n)) => {
|
|
||||||
&*n > &0
|
|
||||||
}
|
|
||||||
Ok(Number::Rational(n)) => {
|
|
||||||
&*n > &0
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -298,8 +290,8 @@ fn negated_op_needs_bracketing(iter: &HCPreOrderIterator, op: &Option<DirectedOp
|
|||||||
|
|
||||||
fn numbervar(n: Integer) -> Var {
|
fn numbervar(n: Integer) -> Var {
|
||||||
static CHAR_CODES: [char; 26] = [
|
static CHAR_CODES: [char; 26] = [
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
|
||||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
];
|
];
|
||||||
|
|
||||||
let i = n.mod_u(26) as usize;
|
let i = n.mod_u(26) as usize;
|
||||||
@@ -332,9 +324,7 @@ impl MachineState {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,8 +436,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
||||||
fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> bool {
|
|
||||||
if let Some(c) = iter.next() {
|
if let Some(c) = iter.next() {
|
||||||
if small_letter_char!(c) {
|
if small_letter_char!(c) {
|
||||||
iter.all(|c| alpha_numeric_char!(c))
|
iter.all(|c| alpha_numeric_char!(c))
|
||||||
@@ -505,37 +494,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
max_depth: 0,
|
max_depth: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
pub fn from_heap_locs(
|
pub fn from_heap_locs(
|
||||||
machine_st: &'a MachineState,
|
machine_st: &'a MachineState,
|
||||||
op_dir: &'a OpDir,
|
op_dir: &'a OpDir,
|
||||||
output: Outputter,
|
output: Outputter,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut printer = Self::new(machine_st, op_dir, output);
|
let mut printer = Self::new(machine_st, op_dir, output);
|
||||||
|
|
||||||
printer.toplevel_spec = Some(DirectedOp::Right(
|
printer.toplevel_spec = Some(DirectedOp::Right(
|
||||||
clause_name!("="),
|
clause_name!("="),
|
||||||
SharedOpDesc::new(700, XFX),
|
SharedOpDesc::new(700, XFX),
|
||||||
));
|
));
|
||||||
|
|
||||||
printer.heap_locs = reverse_heap_locs(machine_st);
|
printer.heap_locs = reverse_heap_locs(machine_st);
|
||||||
|
|
||||||
printer
|
printer
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
pub fn drop_toplevel_spec(&mut self) {
|
|
||||||
self.toplevel_spec = None;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
#[inline]
|
|
||||||
pub fn see_all_locs(&mut self) {
|
|
||||||
for key in self.heap_locs.keys().cloned() {
|
|
||||||
self.printed_vars.insert(key);
|
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
*/
|
/*
|
||||||
|
pub fn drop_toplevel_spec(&mut self) {
|
||||||
|
self.toplevel_spec = None;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#[inline]
|
||||||
|
pub fn see_all_locs(&mut self) {
|
||||||
|
for key in self.heap_locs.keys().cloned() {
|
||||||
|
self.printed_vars.insert(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ambiguity_check(&self, atom: &str) -> bool {
|
fn ambiguity_check(&self, atom: &str) -> bool {
|
||||||
@@ -555,7 +544,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -579,7 +569,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -587,7 +578,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
|
max_depth,
|
||||||
|
left_directed_op,
|
||||||
|
));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
} else {
|
} else {
|
||||||
match ct.name().as_str() {
|
match ct.name().as_str() {
|
||||||
@@ -602,9 +596,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -612,11 +608,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
let left_directed_op = DirectedOp::Left(ct.name(), spec.clone());
|
||||||
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
let right_directed_op = DirectedOp::Right(ct.name(), spec.clone());
|
||||||
|
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
|
max_depth,
|
||||||
|
left_directed_op,
|
||||||
|
));
|
||||||
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
self.state_stack.push(TokenOrRedirect::Op(ct.name(), spec));
|
||||||
self.state_stack
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
|
max_depth,
|
||||||
|
right_directed_op,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,15 +626,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
) -> bool
|
) -> bool {
|
||||||
{
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
for _ in 0 .. arity {
|
for _ in 0..arity {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
@@ -644,8 +644,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
|
||||||
for _ in 0 .. arity {
|
for _ in 0..arity {
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,12 +663,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
iter: &mut HCPreOrderIterator,
|
iter: &mut HCPreOrderIterator,
|
||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
spec: SharedOpDesc)
|
spec: SharedOpDesc,
|
||||||
{
|
) {
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
|
|
||||||
@@ -676,7 +678,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let op = DirectedOp::Left(name.clone(), spec);
|
let op = DirectedOp::Left(name.clone(), spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::CompositeRedirect(max_depth, op));
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(name));
|
self.state_stack.push(TokenOrRedirect::Atom(name));
|
||||||
}
|
}
|
||||||
@@ -687,14 +690,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
mut max_depth: usize,
|
mut max_depth: usize,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
spec: SharedOpDesc,
|
spec: SharedOpDesc,
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -702,25 +706,32 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
let left_directed_op = DirectedOp::Left(name.clone(), spec.clone());
|
||||||
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
let right_directed_op = DirectedOp::Right(name.clone(), spec.clone());
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, left_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
|
max_depth,
|
||||||
|
left_directed_op,
|
||||||
|
));
|
||||||
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
self.state_stack.push(TokenOrRedirect::BarAsOp);
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(max_depth, right_directed_op));
|
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
||||||
|
max_depth,
|
||||||
|
right_directed_op,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool
|
fn format_curly_braces(&mut self, iter: &mut HCPreOrderIterator, mut max_depth: usize) -> bool {
|
||||||
{
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::RightCurly);
|
self.state_stack.push(TokenOrRedirect::RightCurly);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::RightCurly);
|
self.state_stack.push(TokenOrRedirect::RightCurly);
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
self.state_stack.push(TokenOrRedirect::LeftCurly);
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -795,18 +806,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Lis(h) | Addr::Str(h) => {
|
Addr::Lis(h) | Addr::Str(h) => Some(format!("{}", h)),
|
||||||
Some(format!("{}", h))
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(r) = addr.as_var() {
|
if let Some(r) = addr.as_var() {
|
||||||
match r {
|
match r {
|
||||||
Ref::StackCell(fr, sc) => {
|
Ref::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
|
||||||
Some(format!("_s_{}_{}", fr, sc))
|
Ref::HeapCell(h) | Ref::AttrVar(h) => Some(format!("_{}", h)),
|
||||||
}
|
|
||||||
Ref::HeapCell(h) | Ref::AttrVar(h) => {
|
|
||||||
Some(format!("_{}", h))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -818,8 +823,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
|
fn record_children_as_non_cyclic(&mut self, addr: &Addr) {
|
||||||
match addr {
|
match addr {
|
||||||
&Addr::Lis(l) => {
|
&Addr::Lis(l) => {
|
||||||
let c1 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l)));
|
let c1 = self
|
||||||
let c2 = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(Addr::HeapCell(l)));
|
||||||
|
let c2 = self
|
||||||
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(Addr::HeapCell(l + 1)));
|
||||||
|
|
||||||
if let Some(c) = functor_location(&c1) {
|
if let Some(c) = functor_location(&c1) {
|
||||||
self.non_cyclic_terms.insert(c);
|
self.non_cyclic_terms.insert(c);
|
||||||
@@ -830,18 +839,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Addr::Str(s) => {
|
&Addr::Str(s) => {
|
||||||
let arity =
|
let arity = match &self.machine_st.heap[s] {
|
||||||
match &self.machine_st.heap[s] {
|
HeapCellValue::NamedStr(arity, ..) => arity,
|
||||||
HeapCellValue::NamedStr(arity, ..) => {
|
_ => {
|
||||||
arity
|
unreachable!()
|
||||||
}
|
}
|
||||||
_ => {
|
};
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for i in 1 .. arity + 1 {
|
for i in 1..arity + 1 {
|
||||||
let c = self.machine_st.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
let c = self
|
||||||
|
.machine_st
|
||||||
|
.store(self.machine_st.deref(Addr::HeapCell(s + i)));
|
||||||
|
|
||||||
if let Some(c) = functor_location(&c) {
|
if let Some(c) = functor_location(&c) {
|
||||||
self.non_cyclic_terms.insert(c);
|
self.non_cyclic_terms.insert(c);
|
||||||
@@ -856,15 +864,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.non_cyclic_terms.insert(c);
|
self.non_cyclic_terms.insert(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_seen(
|
fn check_for_seen(&mut self, iter: &mut HCPreOrderIterator) -> Option<Addr> {
|
||||||
&mut self,
|
|
||||||
iter: &mut HCPreOrderIterator,
|
|
||||||
) -> Option<Addr> {
|
|
||||||
iter.stack().last().cloned().and_then(|addr| {
|
iter.stack().last().cloned().and_then(|addr| {
|
||||||
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
let addr = self.machine_st.store(self.machine_st.deref(addr));
|
||||||
|
|
||||||
@@ -889,9 +893,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let offset = match functor_location(&addr) {
|
let offset = match functor_location(&addr) {
|
||||||
Some(offset) => {
|
Some(offset) => offset,
|
||||||
offset
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
return iter.next();
|
return iter.next();
|
||||||
}
|
}
|
||||||
@@ -1036,19 +1038,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let rdiv_ct = clause_name!("rdiv");
|
let rdiv_ct = clause_name!("rdiv");
|
||||||
|
|
||||||
let left_directed_op =
|
let left_directed_op = if spec.prec() > 0 {
|
||||||
if spec.prec() > 0 {
|
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
||||||
Some(DirectedOp::Left(rdiv_ct.clone(), spec.clone()))
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let right_directed_op =
|
let right_directed_op = if spec.prec() > 0 {
|
||||||
if spec.prec() > 0 {
|
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
||||||
Some(DirectedOp::Right(rdiv_ct.clone(), spec.clone()))
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
};
|
||||||
};
|
|
||||||
|
|
||||||
if spec.prec() > 0 {
|
if spec.prec() > 0 {
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack.push(TokenOrRedirect::Number(
|
||||||
@@ -1056,10 +1056,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
left_directed_op,
|
left_directed_op,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Op(
|
self.state_stack
|
||||||
rdiv_ct,
|
.push(TokenOrRedirect::Op(rdiv_ct, spec.clone()));
|
||||||
spec.clone(),
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack.push(TokenOrRedirect::Number(
|
||||||
Number::from(r.numer()),
|
Number::from(r.numer()),
|
||||||
@@ -1068,17 +1066,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack
|
||||||
Number::from(r.denom()),
|
.push(TokenOrRedirect::Number(Number::from(r.denom()), None));
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Number(
|
self.state_stack
|
||||||
Number::from(r.numer()),
|
.push(TokenOrRedirect::Number(Number::from(r.numer()), None));
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
|
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
|
||||||
@@ -1092,8 +1086,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_char(&mut self, is_quoted: bool, c: char)
|
fn print_char(&mut self, is_quoted: bool, c: char) {
|
||||||
{
|
|
||||||
if non_quoted_token(once(c)) {
|
if non_quoted_token(once(c)) {
|
||||||
let c = char_to_string(false, c);
|
let c = char_to_string(false, c);
|
||||||
|
|
||||||
@@ -1120,46 +1113,37 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
fn print_proper_string(&mut self, buf: String, max_depth: usize) {
|
fn print_proper_string(&mut self, buf: String, max_depth: usize) {
|
||||||
self.push_char('"');
|
self.push_char('"');
|
||||||
|
|
||||||
let buf =
|
let buf = if max_depth == 0 {
|
||||||
if max_depth == 0 {
|
String::from_iter(buf.chars().map(|c| char_to_string(self.quoted, c)))
|
||||||
String::from_iter(buf.chars().map(|c| {
|
} else {
|
||||||
char_to_string(self.quoted, c)
|
let mut char_count = 0;
|
||||||
}))
|
let mut buf = String::from_iter(buf.chars().take(max_depth).map(|c| {
|
||||||
} else {
|
char_count += 1;
|
||||||
let mut char_count = 0;
|
char_to_string(self.quoted, c)
|
||||||
let mut buf =
|
}));
|
||||||
String::from_iter(buf.chars().take(max_depth).map(|c| {
|
|
||||||
char_count += 1;
|
|
||||||
char_to_string(self.quoted, c)
|
|
||||||
}));
|
|
||||||
|
|
||||||
if char_count == max_depth {
|
if char_count == max_depth {
|
||||||
buf += " ...";
|
buf += " ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
buf
|
buf
|
||||||
};
|
};
|
||||||
|
|
||||||
self.append_str(&buf);
|
self.append_str(&buf);
|
||||||
self.push_char('"');
|
self.push_char('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_list_like(
|
fn print_list_like(&mut self, iter: &mut HCPreOrderIterator, addr: Addr, mut max_depth: usize) {
|
||||||
&mut self,
|
|
||||||
iter: &mut HCPreOrderIterator,
|
|
||||||
addr: Addr,
|
|
||||||
mut max_depth: usize,
|
|
||||||
) {
|
|
||||||
if self.check_max_depth(&mut max_depth) {
|
if self.check_max_depth(&mut max_depth) {
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
iter.stack().pop();
|
iter.stack().pop();
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut heap_pstr_iter =
|
let mut heap_pstr_iter = self.machine_st.heap_pstr_iter(addr);
|
||||||
self.machine_st.heap_pstr_iter(addr);
|
|
||||||
|
|
||||||
let buf = heap_pstr_iter.to_string();
|
let buf = heap_pstr_iter.to_string();
|
||||||
|
|
||||||
@@ -1184,12 +1168,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let buf_len = buf.len();
|
let buf_len = buf.len();
|
||||||
|
|
||||||
let buf_iter: Box<dyn Iterator<Item=char>> =
|
let buf_iter: Box<dyn Iterator<Item = char>> = if self.max_depth == 0 {
|
||||||
if self.max_depth == 0 {
|
Box::new(buf.chars())
|
||||||
Box::new(buf.chars())
|
} else {
|
||||||
} else {
|
Box::new(buf.chars().take(max_depth))
|
||||||
Box::new(buf.chars().take(max_depth))
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let mut byte_len = 0;
|
let mut byte_len = 0;
|
||||||
|
|
||||||
@@ -1207,14 +1190,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
byte_len += c.len_utf8();
|
byte_len += c.len_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0 .. char_count {
|
for _ in 0..char_count {
|
||||||
self.state_stack.push(TokenOrRedirect::Close);
|
self.state_stack.push(TokenOrRedirect::Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.max_depth > 0 && buf_len > byte_len {
|
if self.max_depth > 0 && buf_len > byte_len {
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
iter.stack().push(end_addr);
|
iter.stack().push(end_addr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1232,15 +1217,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
byte_len += c.len_utf8();
|
byte_len += c.len_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(Rc::new(
|
self.state_stack
|
||||||
Cell::new((switch, 0))
|
.push(TokenOrRedirect::CloseList(Rc::new(Cell::new((switch, 0)))));
|
||||||
)));
|
|
||||||
|
|
||||||
if self.max_depth > 0 && buf_len > byte_len {
|
if self.max_depth > 0 && buf_len > byte_len {
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
self.state_stack
|
||||||
} else {
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.outputter.truncate(self.outputter.len() - ','.len_utf8());
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.outputter
|
||||||
|
.truncate(self.outputter.len() - ','.len_utf8());
|
||||||
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
|
|
||||||
iter.stack().push(end_addr);
|
iter.stack().push(end_addr);
|
||||||
}
|
}
|
||||||
@@ -1268,8 +1255,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let cell = Rc::new(Cell::new((true, 0)));
|
let cell = Rc::new(Cell::new((true, 0)));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
self.state_stack
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(clause_name!("...")));
|
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||||
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::Atom(clause_name!("...")));
|
||||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1277,11 +1266,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let cell = Rc::new(Cell::new((true, max_depth)));
|
let cell = Rc::new(Cell::new((true, max_depth)));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||||
}
|
}
|
||||||
@@ -1298,23 +1290,24 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
) {
|
) {
|
||||||
let add_brackets = if !self.ignore_ops {
|
let add_brackets = if !self.ignore_ops {
|
||||||
negated_operand || if let Some(ref op) = op {
|
negated_operand
|
||||||
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
|| if let Some(ref op) = op {
|
||||||
!iter.immediate_leaf_has_property(|addr, heap| {
|
if self.numbervars && arity == 1 && name.as_str() == "$VAR" {
|
||||||
match heap.index_addr(&addr).as_ref() {
|
!iter.immediate_leaf_has_property(|addr, heap| {
|
||||||
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
match heap.index_addr(&addr).as_ref() {
|
||||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
&HeapCellValue::Integer(ref n) => &**n >= &0,
|
||||||
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
&HeapCellValue::Addr(Addr::Fixnum(n)) => n >= 0,
|
||||||
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
&HeapCellValue::Addr(Addr::Float(f)) => f >= OrderedFloat(0f64),
|
||||||
_ => false
|
&HeapCellValue::Rational(ref r) => &**r >= &0,
|
||||||
}
|
_ => false,
|
||||||
}) && needs_bracketing(&spec, op)
|
}
|
||||||
|
}) && needs_bracketing(&spec, op)
|
||||||
|
} else {
|
||||||
|
needs_bracketing(&spec, op)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
needs_bracketing(&spec, op)
|
is_functor_redirect && spec.prec() >= 1000
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
is_functor_redirect && spec.prec() >= 1000
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
@@ -1344,15 +1337,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
tcp_listener: &TcpListener,
|
tcp_listener: &TcpListener,
|
||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
) {
|
) {
|
||||||
let (ip, port) =
|
let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
|
||||||
if let Some(addr) = tcp_listener.local_addr().ok() {
|
(addr.ip(), Number::from(addr.port() as isize))
|
||||||
(addr.ip(), Number::from(addr.port() as isize))
|
} else {
|
||||||
} else {
|
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
||||||
let disconnected_atom = clause_name!("$disconnected_tcp_listener");
|
self.state_stack
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(disconnected_atom));
|
.push(TokenOrRedirect::Atom(disconnected_atom));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) {
|
if self.format_struct(iter, max_depth, 1, clause_name!("$tcp_listener")) {
|
||||||
let atom = self.state_stack.pop().unwrap();
|
let atom = self.state_stack.pop().unwrap();
|
||||||
@@ -1369,22 +1362,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_stream(
|
fn print_stream(&mut self, iter: &mut HCPreOrderIterator, stream: &Stream, max_depth: usize) {
|
||||||
&mut self,
|
|
||||||
iter: &mut HCPreOrderIterator,
|
|
||||||
stream: &Stream,
|
|
||||||
max_depth: usize,
|
|
||||||
) {
|
|
||||||
if let Some(alias) = &stream.options.alias {
|
if let Some(alias) = &stream.options.alias {
|
||||||
self.print_atom(alias);
|
self.print_atom(alias);
|
||||||
} else {
|
} else {
|
||||||
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
|
if self.format_struct(iter, max_depth, 1, clause_name!("$stream")) {
|
||||||
let atom =
|
let atom = if stream.is_stdout() || stream.is_stdin() {
|
||||||
if stream.is_stdout() || stream.is_stdin() {
|
TokenOrRedirect::Atom(clause_name!("user"))
|
||||||
TokenOrRedirect::Atom(clause_name!("user"))
|
} else {
|
||||||
} else {
|
TokenOrRedirect::RawPtr(stream.as_ptr())
|
||||||
TokenOrRedirect::RawPtr(stream.as_ptr())
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let stream_root = self.state_stack.pop().unwrap();
|
let stream_root = self.state_stack.pop().unwrap();
|
||||||
|
|
||||||
@@ -1414,7 +1401,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
match self.machine_st.heap.index_addr(&addr).as_ref() {
|
||||||
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
|
||||||
let spec = fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir);
|
let spec =
|
||||||
|
fetch_op_spec_from_existing(name.clone(), arity, spec.clone(), self.op_dir);
|
||||||
|
|
||||||
if let Some(spec) = spec {
|
if let Some(spec) = spec {
|
||||||
self.handle_op_as_struct(
|
self.handle_op_as_struct(
|
||||||
|
|||||||
480
src/indexing.rs
480
src/indexing.rs
@@ -1,11 +1,12 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use prolog_parser::clause_name;
|
||||||
|
use prolog_parser::tabled_rc::*;
|
||||||
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::instructions::*;
|
use crate::instructions::*;
|
||||||
|
|
||||||
use crate::indexmap::IndexMap;
|
|
||||||
use crate::rug::Integer;
|
use crate::rug::Integer;
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use slice_deque::{sdeq, SliceDeque};
|
use slice_deque::{sdeq, SliceDeque};
|
||||||
|
|
||||||
@@ -43,14 +44,10 @@ impl OptArgIndexKey {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
|
fn has_key_type(&self, key_type: OptArgIndexKeyType) -> bool {
|
||||||
match (self, key_type) {
|
match (self, key_type) {
|
||||||
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant) |
|
(OptArgIndexKey::Constant(..), OptArgIndexKeyType::Constant)
|
||||||
(OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure) |
|
| (OptArgIndexKey::Structure(..), OptArgIndexKeyType::Structure)
|
||||||
(OptArgIndexKey::List(..), OptArgIndexKeyType::List) => {
|
| (OptArgIndexKey::List(..), OptArgIndexKeyType::List) => true,
|
||||||
true
|
_ => false,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,16 +90,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
indexing_code: &'a mut Vec<IndexingLine>,
|
indexing_code: &'a mut Vec<IndexingLine>,
|
||||||
append_or_prepend: AppendOrPrepend,
|
append_or_prepend: AppendOrPrepend,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self { skeleton, indexing_code, offset: 0, append_or_prepend }
|
Self {
|
||||||
|
skeleton,
|
||||||
|
indexing_code,
|
||||||
|
offset: 0,
|
||||||
|
append_or_prepend,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
|
fn internalize_constant(&mut self, constant_ptr: IndexingCodePtr) {
|
||||||
let constant_key =
|
let constant_key = search_skeleton_for_first_key_type(
|
||||||
search_skeleton_for_first_key_type(
|
self.skeleton,
|
||||||
self.skeleton,
|
OptArgIndexKeyType::Constant,
|
||||||
OptArgIndexKeyType::Constant,
|
self.append_or_prepend,
|
||||||
self.append_or_prepend,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
let mut constants = IndexMap::new();
|
let mut constants = IndexMap::new();
|
||||||
|
|
||||||
@@ -117,7 +118,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
|
|
||||||
if let IndexingCodePtr::Internal(_) = constant_ptr {
|
if let IndexingCodePtr::Internal(_) = constant_ptr {
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
IndexingInstruction::SwitchOnConstant(constants),
|
||||||
));
|
));
|
||||||
|
|
||||||
let last_index = self.indexing_code.len() - 1;
|
let last_index = self.indexing_code.len() - 1;
|
||||||
@@ -126,34 +127,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
self.offset = self.indexing_code.len();
|
self.offset = self.indexing_code.len();
|
||||||
|
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
IndexingInstruction::SwitchOnConstant(constants),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_indexed_choice_for_constant(&mut self, external: usize, constant: Constant, index: usize)
|
fn add_indexed_choice_for_constant(
|
||||||
{
|
&mut self,
|
||||||
let third_level_index =
|
external: usize,
|
||||||
if self.append_or_prepend.is_append() {
|
constant: Constant,
|
||||||
sdeq![
|
index: usize,
|
||||||
IndexedChoiceInstruction::Try(external),
|
) {
|
||||||
IndexedChoiceInstruction::Trust(index)
|
let third_level_index = if self.append_or_prepend.is_append() {
|
||||||
]
|
sdeq![
|
||||||
} else {
|
IndexedChoiceInstruction::Try(external),
|
||||||
sdeq![
|
IndexedChoiceInstruction::Trust(index)
|
||||||
IndexedChoiceInstruction::Try(index),
|
]
|
||||||
IndexedChoiceInstruction::Trust(external)
|
} else {
|
||||||
]
|
sdeq![
|
||||||
};
|
IndexedChoiceInstruction::Try(index),
|
||||||
|
IndexedChoiceInstruction::Trust(external)
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index));
|
self.indexing_code
|
||||||
|
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref mut constants)) => {
|
||||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
constants.insert(
|
||||||
) => {
|
constant,
|
||||||
constants.insert(constant, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -164,10 +170,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
fn extend_indexed_choice(&mut self, index: usize) {
|
fn extend_indexed_choice(&mut self, index: usize) {
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
|
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs)
|
||||||
if self.append_or_prepend.is_append() => {
|
if self.append_or_prepend.is_append() =>
|
||||||
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
{
|
||||||
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
uncap_choice_seq_with_trust(indexed_choice_instrs);
|
||||||
}
|
indexed_choice_instrs.push_back(IndexedChoiceInstruction::Trust(index));
|
||||||
|
}
|
||||||
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => {
|
IndexingLine::IndexedChoice(ref mut indexed_choice_instrs) => {
|
||||||
uncap_choice_seq_with_try(indexed_choice_instrs);
|
uncap_choice_seq_with_try(indexed_choice_instrs);
|
||||||
indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index));
|
indexed_choice_instrs.push_front(IndexedChoiceInstruction::Try(index));
|
||||||
@@ -188,9 +195,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
match *c {
|
match *c {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*c = IndexingCodePtr::External(index);
|
*c = IndexingCodePtr::External(index);
|
||||||
@@ -203,7 +208,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
*c = IndexingCodePtr::Internal(indexing_code_len);
|
*c = IndexingCodePtr::Internal(indexing_code_len);
|
||||||
|
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
IndexingInstruction::SwitchOnConstant(constants),
|
||||||
));
|
));
|
||||||
|
|
||||||
self.offset = indexing_code_len;
|
self.offset = indexing_code_len;
|
||||||
@@ -213,12 +218,11 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
|
||||||
) => {
|
|
||||||
match constants.get(&overlapping_constant).cloned() {
|
match constants.get(&overlapping_constant).cloned() {
|
||||||
None | Some(IndexingCodePtr::Fail) => {
|
None | Some(IndexingCodePtr::Fail) => {
|
||||||
constants.insert(overlapping_constant, IndexingCodePtr::External(index));
|
constants
|
||||||
|
.insert(overlapping_constant, IndexingCodePtr::External(index));
|
||||||
}
|
}
|
||||||
Some(IndexingCodePtr::External(o)) => {
|
Some(IndexingCodePtr::External(o)) => {
|
||||||
self.add_indexed_choice_for_constant(o, overlapping_constant, index);
|
self.add_indexed_choice_for_constant(o, overlapping_constant, index);
|
||||||
@@ -232,9 +236,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IndexingLine::IndexedChoice(_) => {
|
IndexingLine::IndexedChoice(_) => {
|
||||||
self.internalize_constant(
|
self.internalize_constant(IndexingCodePtr::Internal(
|
||||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
indexing_code_len - self.offset,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -248,9 +252,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
match *c {
|
match *c {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*c = IndexingCodePtr::External(index);
|
*c = IndexingCodePtr::External(index);
|
||||||
@@ -265,9 +267,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(constants)) => {
|
||||||
IndexingInstruction::SwitchOnConstant(constants)
|
|
||||||
) => {
|
|
||||||
match constants.get(&constant).cloned() {
|
match constants.get(&constant).cloned() {
|
||||||
None | Some(IndexingCodePtr::Fail) => {
|
None | Some(IndexingCodePtr::Fail) => {
|
||||||
constants.insert(constant, IndexingCodePtr::External(index));
|
constants.insert(constant, IndexingCodePtr::External(index));
|
||||||
@@ -284,9 +284,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
IndexingLine::IndexedChoice(_) => {
|
IndexingLine::IndexedChoice(_) => {
|
||||||
self.internalize_constant(
|
self.internalize_constant(IndexingCodePtr::Internal(
|
||||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
indexing_code_len - self.offset,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -295,13 +295,12 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
fn internalize_structure(&mut self, structure_ptr: IndexingCodePtr) {
|
||||||
let structure_key =
|
let structure_key = search_skeleton_for_first_key_type(
|
||||||
search_skeleton_for_first_key_type(
|
self.skeleton,
|
||||||
self.skeleton,
|
OptArgIndexKeyType::Structure,
|
||||||
OptArgIndexKeyType::Structure,
|
self.append_or_prepend,
|
||||||
self.append_or_prepend,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
let mut structures = IndexMap::new();
|
let mut structures = IndexMap::new();
|
||||||
|
|
||||||
@@ -316,7 +315,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
|
|
||||||
if let IndexingCodePtr::Internal(_) = structure_ptr {
|
if let IndexingCodePtr::Internal(_) = structure_ptr {
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnStructure(structures)
|
IndexingInstruction::SwitchOnStructure(structures),
|
||||||
));
|
));
|
||||||
|
|
||||||
let last_index = self.indexing_code.len() - 1;
|
let last_index = self.indexing_code.len() - 1;
|
||||||
@@ -325,34 +324,39 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
self.offset = self.indexing_code.len();
|
self.offset = self.indexing_code.len();
|
||||||
|
|
||||||
self.indexing_code.push(IndexingLine::Indexing(
|
self.indexing_code.push(IndexingLine::Indexing(
|
||||||
IndexingInstruction::SwitchOnStructure(structures)
|
IndexingInstruction::SwitchOnStructure(structures),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_indexed_choice_for_structure(&mut self, external: usize, key: PredicateKey, index: usize)
|
fn add_indexed_choice_for_structure(
|
||||||
{
|
&mut self,
|
||||||
let third_level_index =
|
external: usize,
|
||||||
if self.append_or_prepend.is_append() {
|
key: PredicateKey,
|
||||||
sdeq![
|
index: usize,
|
||||||
IndexedChoiceInstruction::Try(external),
|
) {
|
||||||
IndexedChoiceInstruction::Trust(index)
|
let third_level_index = if self.append_or_prepend.is_append() {
|
||||||
]
|
sdeq![
|
||||||
} else {
|
IndexedChoiceInstruction::Try(external),
|
||||||
sdeq![
|
IndexedChoiceInstruction::Trust(index)
|
||||||
IndexedChoiceInstruction::Try(index),
|
]
|
||||||
IndexedChoiceInstruction::Trust(external)
|
} else {
|
||||||
]
|
sdeq![
|
||||||
};
|
IndexedChoiceInstruction::Try(index),
|
||||||
|
IndexedChoiceInstruction::Trust(external)
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
self.indexing_code.push(IndexingLine::IndexedChoice(third_level_index));
|
self.indexing_code
|
||||||
|
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
structures.insert(
|
||||||
) => {
|
key,
|
||||||
structures.insert(key, IndexingCodePtr::Internal(indexing_code_len - self.offset));
|
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -365,26 +369,26 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
_,
|
||||||
) => {
|
_,
|
||||||
match *s {
|
_,
|
||||||
IndexingCodePtr::Fail => {
|
_,
|
||||||
*s = IndexingCodePtr::External(index);
|
ref mut s,
|
||||||
break;
|
)) => match *s {
|
||||||
}
|
IndexingCodePtr::Fail => {
|
||||||
IndexingCodePtr::External(o) => {
|
*s = IndexingCodePtr::External(index);
|
||||||
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
break;
|
||||||
self.internalize_structure(IndexingCodePtr::External(o));
|
|
||||||
}
|
|
||||||
IndexingCodePtr::Internal(o) => {
|
|
||||||
self.offset += o;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
IndexingCodePtr::External(o) => {
|
||||||
IndexingLine::Indexing(
|
*s = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||||
IndexingInstruction::SwitchOnStructure(structures)
|
self.internalize_structure(IndexingCodePtr::External(o));
|
||||||
) => {
|
}
|
||||||
|
IndexingCodePtr::Internal(o) => {
|
||||||
|
self.offset += o;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(structures)) => {
|
||||||
match structures.get(&key).cloned() {
|
match structures.get(&key).cloned() {
|
||||||
None | Some(IndexingCodePtr::Fail) => {
|
None | Some(IndexingCodePtr::Fail) => {
|
||||||
structures.insert(key, IndexingCodePtr::External(index));
|
structures.insert(key, IndexingCodePtr::External(index));
|
||||||
@@ -404,9 +408,9 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
// replace this value, at self.offset, with
|
// replace this value, at self.offset, with
|
||||||
// SwitchOnStructures, and swap this IndexedChoice
|
// SwitchOnStructures, and swap this IndexedChoice
|
||||||
// vector to the end of self.indexing_code.
|
// vector to the end of self.indexing_code.
|
||||||
self.internalize_structure(
|
self.internalize_structure(IndexingCodePtr::Internal(
|
||||||
IndexingCodePtr::Internal(indexing_code_len - self.offset),
|
indexing_code_len - self.offset,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -419,9 +423,7 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
let indexing_code_len = self.indexing_code.len();
|
let indexing_code_len = self.indexing_code.len();
|
||||||
|
|
||||||
match &mut self.indexing_code[self.offset] {
|
match &mut self.indexing_code[self.offset] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
|
||||||
) => {
|
|
||||||
match *l {
|
match *l {
|
||||||
IndexingCodePtr::Fail => {
|
IndexingCodePtr::Fail => {
|
||||||
*l = IndexingCodePtr::External(index);
|
*l = IndexingCodePtr::External(index);
|
||||||
@@ -429,22 +431,20 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
IndexingCodePtr::External(o) => {
|
IndexingCodePtr::External(o) => {
|
||||||
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
*l = IndexingCodePtr::Internal(indexing_code_len - self.offset);
|
||||||
|
|
||||||
let third_level_index =
|
let third_level_index = if self.append_or_prepend.is_append() {
|
||||||
if self.append_or_prepend.is_append() {
|
sdeq![
|
||||||
sdeq![
|
IndexedChoiceInstruction::Try(o),
|
||||||
IndexedChoiceInstruction::Try(o),
|
IndexedChoiceInstruction::Trust(index)
|
||||||
IndexedChoiceInstruction::Trust(index)
|
]
|
||||||
]
|
} else {
|
||||||
} else {
|
sdeq![
|
||||||
sdeq![
|
IndexedChoiceInstruction::Try(index),
|
||||||
IndexedChoiceInstruction::Try(index),
|
IndexedChoiceInstruction::Trust(o)
|
||||||
IndexedChoiceInstruction::Trust(o)
|
]
|
||||||
]
|
};
|
||||||
};
|
|
||||||
|
|
||||||
self.indexing_code.push(
|
self.indexing_code
|
||||||
IndexingLine::IndexedChoice(third_level_index),
|
.push(IndexingLine::IndexedChoice(third_level_index));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
IndexingCodePtr::Internal(o) => {
|
IndexingCodePtr::Internal(o) => {
|
||||||
self.offset += o;
|
self.offset += o;
|
||||||
@@ -462,24 +462,16 @@ impl<'a> IndexingCodeMergingPtr<'a> {
|
|||||||
pub fn merge_clause_index(
|
pub fn merge_clause_index(
|
||||||
target_indexing_code: &mut Vec<IndexingLine>,
|
target_indexing_code: &mut Vec<IndexingLine>,
|
||||||
skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton.
|
skeleton: &mut [ClauseIndexInfo], // the clause to be merged is the last element in the skeleton.
|
||||||
new_clause_loc: usize, // the absolute location of the new clause in the code vector.
|
new_clause_loc: usize, // the absolute location of the new clause in the code vector.
|
||||||
append_or_prepend: AppendOrPrepend,
|
append_or_prepend: AppendOrPrepend,
|
||||||
) {
|
) {
|
||||||
let opt_arg_index_key =
|
let opt_arg_index_key = match append_or_prepend {
|
||||||
match append_or_prepend {
|
AppendOrPrepend::Append => skeleton.last_mut().unwrap().opt_arg_index_key.take(),
|
||||||
AppendOrPrepend::Append => {
|
AppendOrPrepend::Prepend => skeleton.first_mut().unwrap().opt_arg_index_key.take(),
|
||||||
skeleton.last_mut().unwrap().opt_arg_index_key.take()
|
};
|
||||||
}
|
|
||||||
AppendOrPrepend::Prepend => {
|
|
||||||
skeleton.first_mut().unwrap().opt_arg_index_key.take()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut merging_ptr = IndexingCodeMergingPtr::new(
|
let mut merging_ptr =
|
||||||
skeleton,
|
IndexingCodeMergingPtr::new(skeleton, target_indexing_code, append_or_prepend);
|
||||||
target_indexing_code,
|
|
||||||
append_or_prepend,
|
|
||||||
);
|
|
||||||
|
|
||||||
match &opt_arg_index_key {
|
match &opt_arg_index_key {
|
||||||
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
|
OptArgIndexKey::Constant(_, index_loc, ref constant, ref overlapping_constants) => {
|
||||||
@@ -488,7 +480,9 @@ pub fn merge_clause_index(
|
|||||||
|
|
||||||
for overlapping_constant in overlapping_constants {
|
for overlapping_constant in overlapping_constants {
|
||||||
merging_ptr.index_overlapping_constant(
|
merging_ptr.index_overlapping_constant(
|
||||||
constant, overlapping_constant.clone(), offset,
|
constant,
|
||||||
|
overlapping_constant.clone(),
|
||||||
|
offset,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -514,10 +508,7 @@ pub fn merge_clause_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn remove_instruction_with_offset(
|
fn remove_instruction_with_offset(code: &mut SliceDeque<IndexedChoiceInstruction>, offset: usize) {
|
||||||
code: &mut SliceDeque<IndexedChoiceInstruction>,
|
|
||||||
offset: usize,
|
|
||||||
) {
|
|
||||||
for (index, line) in code.iter().enumerate() {
|
for (index, line) in code.iter().enumerate() {
|
||||||
if offset == line.offset() {
|
if offset == line.offset() {
|
||||||
code.remove(index);
|
code.remove(index);
|
||||||
@@ -537,9 +528,7 @@ pub fn remove_constant_indices(
|
|||||||
let iter = once(constant).chain(overlapping_constants.iter());
|
let iter = once(constant).chain(overlapping_constants.iter());
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
match *c {
|
match *c {
|
||||||
IndexingCodePtr::External(_) => {
|
IndexingCodePtr::External(_) => {
|
||||||
*c = IndexingCodePtr::Fail;
|
*c = IndexingCodePtr::Fail;
|
||||||
@@ -560,12 +549,13 @@ pub fn remove_constant_indices(
|
|||||||
|
|
||||||
let mut constants_index = 0;
|
let mut constants_index = 0;
|
||||||
|
|
||||||
for constant in iter { // (constant, index_loc) in iter.zip(index_locs.iter()) {
|
for constant in iter {
|
||||||
|
// (constant, index_loc) in iter.zip(index_locs.iter()) {
|
||||||
loop {
|
loop {
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
ref mut constants,
|
||||||
) => {
|
)) => {
|
||||||
constants_index = index;
|
constants_index = index;
|
||||||
|
|
||||||
match constants.get(constant).cloned() {
|
match constants.get(constant).cloned() {
|
||||||
@@ -586,18 +576,21 @@ pub fn remove_constant_indices(
|
|||||||
|
|
||||||
if indexed_choice_instrs.len() == 1 {
|
if indexed_choice_instrs.len() == 1 {
|
||||||
let ext = IndexingCodePtr::External(
|
let ext = IndexingCodePtr::External(
|
||||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut indexing_code[constants_index] {
|
match &mut indexing_code[constants_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
ref mut c,
|
||||||
|
..,
|
||||||
|
)) => {
|
||||||
*c = ext;
|
*c = ext;
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(
|
||||||
IndexingInstruction::SwitchOnConstant(ref mut constants)
|
ref mut constants,
|
||||||
) => {
|
)) => {
|
||||||
constants.insert(constant.clone(), ext);
|
constants.insert(constant.clone(), ext);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -616,13 +609,11 @@ pub fn remove_constant_indices(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &indexing_code[constants_index] {
|
match &indexing_code[constants_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(ref constants))
|
||||||
IndexingInstruction::SwitchOnConstant(ref constants)
|
if constants.is_empty() =>
|
||||||
) if constants.is_empty() => {
|
{
|
||||||
match &mut indexing_code[0] {
|
match &mut indexing_code[0] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, ref mut c, ..)
|
|
||||||
) => {
|
|
||||||
*c = IndexingCodePtr::Fail;
|
*c = IndexingCodePtr::Fail;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -630,8 +621,7 @@ pub fn remove_constant_indices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,9 +634,7 @@ pub fn remove_structure_index(
|
|||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
|
||||||
) => {
|
|
||||||
match *s {
|
match *s {
|
||||||
IndexingCodePtr::External(_) => {
|
IndexingCodePtr::External(_) => {
|
||||||
*s = IndexingCodePtr::Fail;
|
*s = IndexingCodePtr::Fail;
|
||||||
@@ -669,9 +657,7 @@ pub fn remove_structure_index(
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
|
||||||
) => {
|
|
||||||
structures_index = index;
|
structures_index = index;
|
||||||
|
|
||||||
match structures.get(&(name.clone(), arity)).cloned() {
|
match structures.get(&(name.clone(), arity)).cloned() {
|
||||||
@@ -692,18 +678,22 @@ pub fn remove_structure_index(
|
|||||||
|
|
||||||
if indexed_choice_instrs.len() == 1 {
|
if indexed_choice_instrs.len() == 1 {
|
||||||
let ext = IndexingCodePtr::External(
|
let ext = IndexingCodePtr::External(
|
||||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
indexed_choice_instrs.pop_back().unwrap().offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut indexing_code[structures_index] {
|
match &mut indexing_code[structures_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
ref mut s,
|
||||||
|
)) => {
|
||||||
*s = ext;
|
*s = ext;
|
||||||
}
|
}
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
||||||
IndexingInstruction::SwitchOnStructure(ref mut structures)
|
ref mut structures,
|
||||||
) => {
|
)) => {
|
||||||
structures.insert((name.clone(), arity), ext);
|
structures.insert((name.clone(), arity), ext);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -721,13 +711,17 @@ pub fn remove_structure_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &indexing_code[structures_index] {
|
match &indexing_code[structures_index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref structures))
|
||||||
IndexingInstruction::SwitchOnStructure(ref structures)
|
if structures.is_empty() =>
|
||||||
) if structures.is_empty() => {
|
{
|
||||||
match &mut indexing_code[0] {
|
match &mut indexing_code[0] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, _, ref mut s)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
ref mut s,
|
||||||
|
)) => {
|
||||||
*s = IndexingCodePtr::Fail;
|
*s = IndexingCodePtr::Fail;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -735,21 +729,15 @@ pub fn remove_structure_index(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_list_index(
|
pub fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
|
||||||
indexing_code: &mut Vec<IndexingLine>,
|
|
||||||
offset: usize,
|
|
||||||
) {
|
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)) => {
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
|
||||||
) => {
|
|
||||||
match *l {
|
match *l {
|
||||||
IndexingCodePtr::External(_) => {
|
IndexingCodePtr::External(_) => {
|
||||||
*l = IndexingCodePtr::Fail;
|
*l = IndexingCodePtr::Fail;
|
||||||
@@ -773,14 +761,17 @@ pub fn remove_list_index(
|
|||||||
remove_instruction_with_offset(indexed_choice_instrs, offset);
|
remove_instruction_with_offset(indexed_choice_instrs, offset);
|
||||||
|
|
||||||
if indexed_choice_instrs.len() == 1 {
|
if indexed_choice_instrs.len() == 1 {
|
||||||
let ext = IndexingCodePtr::External(
|
let ext =
|
||||||
indexed_choice_instrs.pop_back().unwrap().offset()
|
IndexingCodePtr::External(indexed_choice_instrs.pop_back().unwrap().offset());
|
||||||
);
|
|
||||||
|
|
||||||
match &mut indexing_code[0] {
|
match &mut indexing_code[0] {
|
||||||
IndexingLine::Indexing(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(_, _, _, ref mut l, _)
|
_,
|
||||||
) => {
|
_,
|
||||||
|
_,
|
||||||
|
ref mut l,
|
||||||
|
_,
|
||||||
|
)) => {
|
||||||
*l = ext;
|
*l = ext;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -836,8 +827,7 @@ pub fn remove_index(
|
|||||||
fn second_level_index<IndexKey: Eq + Hash>(
|
fn second_level_index<IndexKey: Eq + Hash>(
|
||||||
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
|
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>,
|
||||||
prelude: &mut SliceDeque<IndexingLine>,
|
prelude: &mut SliceDeque<IndexingLine>,
|
||||||
) -> IndexMap<IndexKey, IndexingCodePtr>
|
) -> IndexMap<IndexKey, IndexingCodePtr> {
|
||||||
{
|
|
||||||
let mut index_locs = IndexMap::new();
|
let mut index_locs = IndexMap::new();
|
||||||
|
|
||||||
for (key, mut code) in indices.into_iter() {
|
for (key, mut code) in indices.into_iter() {
|
||||||
@@ -868,10 +858,11 @@ fn switch_on<IndexKey: Eq + Hash>(
|
|||||||
|
|
||||||
IndexingCodePtr::Internal(1)
|
IndexingCodePtr::Internal(1)
|
||||||
} else {
|
} else {
|
||||||
index.into_iter()
|
index
|
||||||
.next()
|
.into_iter()
|
||||||
.map(|(_, v)| v)
|
.next()
|
||||||
.unwrap_or(IndexingCodePtr::Fail)
|
.map(|(_, v)| v)
|
||||||
|
.unwrap_or(IndexingCodePtr::Fail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,9 +875,10 @@ fn switch_on_list(
|
|||||||
prelude.push_back(IndexingLine::from(lists));
|
prelude.push_back(IndexingLine::from(lists));
|
||||||
IndexingCodePtr::Internal(1)
|
IndexingCodePtr::Internal(1)
|
||||||
} else {
|
} else {
|
||||||
lists.first()
|
lists
|
||||||
.map(|i| IndexingCodePtr::External(i.offset()))
|
.first()
|
||||||
.unwrap_or(IndexingCodePtr::Fail)
|
.map(|i| IndexingCodePtr::External(i.offset()))
|
||||||
|
.unwrap_or(IndexingCodePtr::Fail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,8 +970,7 @@ pub fn constant_key_alternatives(constant: &Constant, atom_tbl: TabledData<Atom>
|
|||||||
constants.push(Constant::Fixnum(n));
|
constants.push(Constant::Fixnum(n));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constants
|
constants
|
||||||
@@ -1001,7 +992,7 @@ impl CodeOffsets {
|
|||||||
constants: IndexMap::new(),
|
constants: IndexMap::new(),
|
||||||
lists: sdeq![],
|
lists: sdeq![],
|
||||||
structures: IndexMap::new(),
|
structures: IndexMap::new(),
|
||||||
optimal_index
|
optimal_index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1011,20 +1002,15 @@ impl CodeOffsets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
|
fn index_constant(&mut self, constant: &Constant, index: usize) -> Vec<Constant> {
|
||||||
let overlapping_constants =
|
let overlapping_constants = constant_key_alternatives(constant, self.atom_tbl.clone());
|
||||||
constant_key_alternatives(constant, self.atom_tbl.clone());
|
|
||||||
|
|
||||||
let code = self.constants
|
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||||
.entry(constant.clone())
|
|
||||||
.or_insert(sdeq![]);
|
|
||||||
|
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
code.push_back(compute_index(is_initial_index, index));
|
code.push_back(compute_index(is_initial_index, index));
|
||||||
|
|
||||||
for constant in &overlapping_constants {
|
for constant in &overlapping_constants {
|
||||||
let code = self.constants
|
let code = self.constants.entry(constant.clone()).or_insert(sdeq![]);
|
||||||
.entry(constant.clone())
|
|
||||||
.or_insert(sdeq![]);
|
|
||||||
|
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
let index = compute_index(is_initial_index, index);
|
let index = compute_index(is_initial_index, index);
|
||||||
@@ -1062,25 +1048,21 @@ impl CodeOffsets {
|
|||||||
self.index_structure(name, terms.len(), index);
|
self.index_structure(name, terms.len(), index);
|
||||||
}
|
}
|
||||||
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
&Term::Cons(..) | &Term::Constant(_, Constant::String(_)) => {
|
||||||
clause_index_info.opt_arg_index_key =
|
clause_index_info.opt_arg_index_key = OptArgIndexKey::List(self.optimal_index, 0);
|
||||||
OptArgIndexKey::List(self.optimal_index, 0);
|
|
||||||
|
|
||||||
self.index_list(index);
|
self.index_list(index);
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref constant) => {
|
&Term::Constant(_, ref constant) => {
|
||||||
let overlapping_constants =
|
let overlapping_constants = self.index_constant(constant, index);
|
||||||
self.index_constant(constant, index);
|
|
||||||
|
|
||||||
clause_index_info.opt_arg_index_key =
|
clause_index_info.opt_arg_index_key = OptArgIndexKey::Constant(
|
||||||
OptArgIndexKey::Constant(
|
self.optimal_index,
|
||||||
self.optimal_index,
|
0,
|
||||||
0,
|
constant.clone(),
|
||||||
constant.clone(),
|
overlapping_constants,
|
||||||
overlapping_constants,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1117,8 +1099,7 @@ impl CodeOffsets {
|
|||||||
IndexingCodePtr::Internal(ref mut i) => {
|
IndexingCodePtr::Internal(ref mut i) => {
|
||||||
*i += con_loc.is_internal() as usize;
|
*i += con_loc.is_internal() as usize;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match &mut lst_loc {
|
match &mut lst_loc {
|
||||||
@@ -1126,15 +1107,18 @@ impl CodeOffsets {
|
|||||||
*i += con_loc.is_internal() as usize;
|
*i += con_loc.is_internal() as usize;
|
||||||
*i += str_loc.is_internal() as usize;
|
*i += str_loc.is_internal() as usize;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let var_offset = 1 + skip_stub_try_me_else as usize;
|
let var_offset = 1 + skip_stub_try_me_else as usize;
|
||||||
|
|
||||||
prelude.push_front(IndexingLine::from(
|
prelude.push_front(IndexingLine::from(IndexingInstruction::SwitchOnTerm(
|
||||||
IndexingInstruction::SwitchOnTerm(self.optimal_index, var_offset, con_loc, lst_loc, str_loc)
|
self.optimal_index,
|
||||||
));
|
var_offset,
|
||||||
|
con_loc,
|
||||||
|
lst_loc,
|
||||||
|
str_loc,
|
||||||
|
)));
|
||||||
|
|
||||||
prelude.into_iter().collect()
|
prelude.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::clause_name;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -8,7 +9,7 @@ use crate::machine::machine_errors::MachineStub;
|
|||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::rug::Integer;
|
use crate::rug::Integer;
|
||||||
|
|
||||||
use crate::indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use slice_deque::SliceDeque;
|
use slice_deque::SliceDeque;
|
||||||
|
|
||||||
@@ -34,9 +35,7 @@ impl Level {
|
|||||||
impl ArithmeticTerm {
|
impl ArithmeticTerm {
|
||||||
fn into_functor(&self) -> MachineStub {
|
fn into_functor(&self) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&ArithmeticTerm::Reg(r) => {
|
&ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
||||||
reg_type_into_functor(r)
|
|
||||||
}
|
|
||||||
&ArithmeticTerm::Interm(i) => {
|
&ArithmeticTerm::Interm(i) => {
|
||||||
functor!("intermediate", [integer(i)])
|
functor!("intermediate", [integer(i)])
|
||||||
}
|
}
|
||||||
@@ -185,16 +184,11 @@ impl Line {
|
|||||||
|
|
||||||
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
|
pub fn enqueue_functors(&self, mut h: usize, functors: &mut Vec<MachineStub>) {
|
||||||
match self {
|
match self {
|
||||||
&Line::Arithmetic(ref arith_instr) =>
|
&Line::Arithmetic(ref arith_instr) => functors.push(arith_instr.to_functor(h)),
|
||||||
functors.push(arith_instr.to_functor(h)),
|
&Line::Choice(ref choice_instr) => functors.push(choice_instr.to_functor()),
|
||||||
&Line::Choice(ref choice_instr) =>
|
&Line::Control(ref control_instr) => functors.push(control_instr.to_functor()),
|
||||||
functors.push(choice_instr.to_functor()),
|
&Line::Cut(ref cut_instr) => functors.push(cut_instr.to_functor(h)),
|
||||||
&Line::Control(ref control_instr) =>
|
&Line::Fact(ref fact_instr) => functors.push(fact_instr.to_functor(h)),
|
||||||
functors.push(control_instr.to_functor()),
|
|
||||||
&Line::Cut(ref cut_instr) =>
|
|
||||||
functors.push(cut_instr.to_functor(h)),
|
|
||||||
&Line::Fact(ref fact_instr) =>
|
|
||||||
functors.push(fact_instr.to_functor(h)),
|
|
||||||
&Line::IndexingCode(ref indexing_instrs) => {
|
&Line::IndexingCode(ref indexing_instrs) => {
|
||||||
for indexing_instr in indexing_instrs {
|
for indexing_instr in indexing_instrs {
|
||||||
match indexing_instr {
|
match indexing_instr {
|
||||||
@@ -213,10 +207,10 @@ impl Line {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Line::IndexedChoice(ref indexed_choice_instr) =>
|
&Line::IndexedChoice(ref indexed_choice_instr) => {
|
||||||
functors.push(indexed_choice_instr.to_functor()),
|
functors.push(indexed_choice_instr.to_functor())
|
||||||
&Line::Query(ref query_instr) =>
|
}
|
||||||
functors.push(query_instr.to_functor(h)),
|
&Line::Query(ref query_instr) => functors.push(query_instr.to_functor(h)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,24 +218,16 @@ impl Line {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
pub fn to_indexing_line_mut(line: &mut Line) -> Option<&mut Vec<IndexingLine>> {
|
||||||
match line {
|
match line {
|
||||||
Line::IndexingCode(ref mut indexing_code) => {
|
Line::IndexingCode(ref mut indexing_code) => Some(indexing_code),
|
||||||
Some(indexing_code)
|
_ => None,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
pub fn to_indexing_line(line: &Line) -> Option<&Vec<IndexingLine>> {
|
||||||
match line {
|
match line {
|
||||||
Line::IndexingCode(ref indexing_code) => {
|
Line::IndexingCode(ref indexing_code) => Some(indexing_code),
|
||||||
Some(indexing_code)
|
_ => None,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,11 +282,7 @@ fn arith_instr_unary_functor(
|
|||||||
) -> MachineStub {
|
) -> MachineStub {
|
||||||
let at_stub = at.into_functor();
|
let at_stub = at.into_functor();
|
||||||
|
|
||||||
functor!(
|
functor!(name, [aux(h, 0), integer(t)], [at_stub])
|
||||||
name,
|
|
||||||
[aux(h, 0), integer(t)],
|
|
||||||
[at_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arith_instr_bin_functor(
|
fn arith_instr_bin_functor(
|
||||||
@@ -383,39 +365,17 @@ impl ArithmeticInstruction {
|
|||||||
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
&ArithmeticInstruction::Gcd(ref at_1, ref at_2, t) => {
|
||||||
arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
|
arith_instr_bin_functor(h, "gcd", at_1, at_2, t)
|
||||||
}
|
}
|
||||||
&ArithmeticInstruction::Sign(ref at, t) => {
|
&ArithmeticInstruction::Sign(ref at, t) => arith_instr_unary_functor(h, "sign", at, t),
|
||||||
arith_instr_unary_functor(h, "sign", at, t)
|
&ArithmeticInstruction::Cos(ref at, t) => arith_instr_unary_functor(h, "cos", at, t),
|
||||||
}
|
&ArithmeticInstruction::Sin(ref at, t) => arith_instr_unary_functor(h, "sin", at, t),
|
||||||
&ArithmeticInstruction::Cos(ref at, t) => {
|
&ArithmeticInstruction::Tan(ref at, t) => arith_instr_unary_functor(h, "tan", at, t),
|
||||||
arith_instr_unary_functor(h, "cos", at, t)
|
&ArithmeticInstruction::Log(ref at, t) => arith_instr_unary_functor(h, "log", at, t),
|
||||||
}
|
&ArithmeticInstruction::Exp(ref at, t) => arith_instr_unary_functor(h, "exp", at, t),
|
||||||
&ArithmeticInstruction::Sin(ref at, t) => {
|
&ArithmeticInstruction::ACos(ref at, t) => arith_instr_unary_functor(h, "acos", at, t),
|
||||||
arith_instr_unary_functor(h, "sin", at, t)
|
&ArithmeticInstruction::ASin(ref at, t) => arith_instr_unary_functor(h, "asin", at, t),
|
||||||
}
|
&ArithmeticInstruction::ATan(ref at, t) => arith_instr_unary_functor(h, "atan", at, t),
|
||||||
&ArithmeticInstruction::Tan(ref at, t) => {
|
&ArithmeticInstruction::Sqrt(ref at, t) => arith_instr_unary_functor(h, "sqrt", at, t),
|
||||||
arith_instr_unary_functor(h, "tan", at, t)
|
&ArithmeticInstruction::Abs(ref at, t) => arith_instr_unary_functor(h, "abs", at, t),
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Log(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "log", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Exp(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "exp", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::ACos(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "acos", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::ASin(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "asin", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::ATan(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "atan", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Sqrt(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "sqrt", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Abs(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "abs", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Float(ref at, t) => {
|
&ArithmeticInstruction::Float(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, "float", at, t)
|
arith_instr_unary_functor(h, "float", at, t)
|
||||||
}
|
}
|
||||||
@@ -431,12 +391,8 @@ impl ArithmeticInstruction {
|
|||||||
&ArithmeticInstruction::Floor(ref at, t) => {
|
&ArithmeticInstruction::Floor(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, "floor", at, t)
|
arith_instr_unary_functor(h, "floor", at, t)
|
||||||
}
|
}
|
||||||
&ArithmeticInstruction::Neg(ref at, t) => {
|
&ArithmeticInstruction::Neg(ref at, t) => arith_instr_unary_functor(h, "-", at, t),
|
||||||
arith_instr_unary_functor(h, "-", at, t)
|
&ArithmeticInstruction::Plus(ref at, t) => arith_instr_unary_functor(h, "+", at, t),
|
||||||
}
|
|
||||||
&ArithmeticInstruction::Plus(ref at, t) => {
|
|
||||||
arith_instr_unary_functor(h, "+", at, t)
|
|
||||||
}
|
|
||||||
&ArithmeticInstruction::BitwiseComplement(ref at, t) => {
|
&ArithmeticInstruction::BitwiseComplement(ref at, t) => {
|
||||||
arith_instr_unary_functor(h, "\\", at, t)
|
arith_instr_unary_functor(h, "\\", at, t)
|
||||||
}
|
}
|
||||||
@@ -451,21 +407,18 @@ pub enum ControlInstruction {
|
|||||||
CallClause(ClauseType, usize, usize, bool, bool),
|
CallClause(ClauseType, usize, usize, bool, bool),
|
||||||
Deallocate,
|
Deallocate,
|
||||||
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
JmpBy(usize, usize, usize, bool), // arity, global_offset, perm_vars after threshold, last call.
|
||||||
RevJmpBy(usize), // notice the lack of context change as in
|
RevJmpBy(usize), // notice the lack of context change as in
|
||||||
// JmpBy. RevJmpBy is used only to patch extensible
|
// JmpBy. RevJmpBy is used only to patch extensible
|
||||||
// predicates together.
|
// predicates together.
|
||||||
Proceed,
|
Proceed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControlInstruction {
|
impl ControlInstruction {
|
||||||
pub fn perm_vars(&self) -> Option<usize> {
|
pub fn perm_vars(&self) -> Option<usize> {
|
||||||
match self {
|
match self {
|
||||||
ControlInstruction::CallClause(_, _, num_cells, ..) =>
|
ControlInstruction::CallClause(_, _, num_cells, ..) => Some(*num_cells),
|
||||||
Some(*num_cells),
|
ControlInstruction::JmpBy(_, _, num_cells, ..) => Some(*num_cells),
|
||||||
ControlInstruction::JmpBy(_, _, num_cells, ..) =>
|
_ => None,
|
||||||
Some(*num_cells),
|
|
||||||
_ =>
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,7 +453,13 @@ impl ControlInstruction {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum IndexingInstruction {
|
pub enum IndexingInstruction {
|
||||||
// The first index is the optimal argument being indexed.
|
// The first index is the optimal argument being indexed.
|
||||||
SwitchOnTerm(usize, usize, IndexingCodePtr, IndexingCodePtr, IndexingCodePtr),
|
SwitchOnTerm(
|
||||||
|
usize,
|
||||||
|
usize,
|
||||||
|
IndexingCodePtr,
|
||||||
|
IndexingCodePtr,
|
||||||
|
IndexingCodePtr,
|
||||||
|
),
|
||||||
SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>),
|
SwitchOnConstant(IndexMap<Constant, IndexingCodePtr>),
|
||||||
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
|
SwitchOnStructure(IndexMap<(ClauseName, usize), IndexingCodePtr>),
|
||||||
}
|
}
|
||||||
@@ -511,11 +470,13 @@ impl IndexingInstruction {
|
|||||||
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
&IndexingInstruction::SwitchOnTerm(arg, vars, constants, lists, structures) => {
|
||||||
functor!(
|
functor!(
|
||||||
"switch_on_term",
|
"switch_on_term",
|
||||||
[integer(arg),
|
[
|
||||||
integer(vars),
|
integer(arg),
|
||||||
indexing_code_ptr(h, constants),
|
integer(vars),
|
||||||
indexing_code_ptr(h, lists),
|
indexing_code_ptr(h, constants),
|
||||||
indexing_code_ptr(h, structures)]
|
indexing_code_ptr(h, lists),
|
||||||
|
indexing_code_ptr(h, structures)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
||||||
@@ -528,15 +489,14 @@ impl IndexingInstruction {
|
|||||||
let key_value_pair = functor!(
|
let key_value_pair = functor!(
|
||||||
":",
|
":",
|
||||||
SharedOpDesc::new(600, XFY),
|
SharedOpDesc::new(600, XFY),
|
||||||
[constant(c),
|
[constant(c), indexing_code_ptr(h + 3, *ptr)]
|
||||||
indexing_code_ptr(h + 3, *ptr)]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||||
Addr::HeapCell(h + 3 + key_value_pair.len())
|
h + 3 + key_value_pair.len(),
|
||||||
));
|
)));
|
||||||
|
|
||||||
h += key_value_pair.len() + 3;
|
h += key_value_pair.len() + 3;
|
||||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||||
@@ -560,23 +520,21 @@ impl IndexingInstruction {
|
|||||||
let predicate_indicator_stub = functor!(
|
let predicate_indicator_stub = functor!(
|
||||||
"/",
|
"/",
|
||||||
SharedOpDesc::new(400, YFX),
|
SharedOpDesc::new(400, YFX),
|
||||||
[clause_name(name.clone()),
|
[clause_name(name.clone()), integer(*arity)]
|
||||||
integer(*arity)]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let key_value_pair = functor!(
|
let key_value_pair = functor!(
|
||||||
":",
|
":",
|
||||||
SharedOpDesc::new(600, XFY),
|
SharedOpDesc::new(600, XFY),
|
||||||
[aux(h + 3, 0),
|
[aux(h + 3, 0), indexing_code_ptr(h + 3, *ptr)],
|
||||||
indexing_code_ptr(h + 3, *ptr)],
|
|
||||||
[predicate_indicator_stub]
|
[predicate_indicator_stub]
|
||||||
);
|
);
|
||||||
|
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::Str(h + 3)));
|
||||||
key_value_list_stub.push(HeapCellValue::Addr(
|
key_value_list_stub.push(HeapCellValue::Addr(Addr::HeapCell(
|
||||||
Addr::HeapCell(h + 3 + key_value_pair.len())
|
h + 3 + key_value_pair.len(),
|
||||||
));
|
)));
|
||||||
|
|
||||||
h += key_value_pair.len() + 3;
|
h += key_value_pair.len() + 3;
|
||||||
key_value_list_stub.extend(key_value_pair.into_iter());
|
key_value_list_stub.extend(key_value_pair.into_iter());
|
||||||
@@ -614,7 +572,7 @@ impl FactInstruction {
|
|||||||
match self {
|
match self {
|
||||||
&FactInstruction::GetConstant(lvl, ref c, r) => {
|
&FactInstruction::GetConstant(lvl, ref c, r) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
"get_constant",
|
"get_constant",
|
||||||
@@ -624,17 +582,13 @@ impl FactInstruction {
|
|||||||
}
|
}
|
||||||
&FactInstruction::GetList(lvl, r) => {
|
&FactInstruction::GetList(lvl, r) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||||
"get_list",
|
|
||||||
[aux(h, 0), aux(h, 1)],
|
|
||||||
[lvl_stub, rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
|
&FactInstruction::GetPartialString(lvl, ref s, r, has_tail) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
"get_partial_string",
|
"get_partial_string",
|
||||||
@@ -654,20 +608,12 @@ impl FactInstruction {
|
|||||||
&FactInstruction::GetValue(r, arg) => {
|
&FactInstruction::GetValue(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"get_value",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::GetVariable(r, arg) => {
|
&FactInstruction::GetVariable(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"get_variable",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyConstant(ref c) => {
|
&FactInstruction::UnifyConstant(ref c) => {
|
||||||
functor!("unify_constant", [constant(h, c)], [])
|
functor!("unify_constant", [constant(h, c)], [])
|
||||||
@@ -675,29 +621,17 @@ impl FactInstruction {
|
|||||||
&FactInstruction::UnifyLocalValue(r) => {
|
&FactInstruction::UnifyLocalValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("unify_local_value", [aux(h, 0)], [rt_stub])
|
||||||
"unify_local_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyVariable(r) => {
|
&FactInstruction::UnifyVariable(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("unify_variable", [aux(h, 0)], [rt_stub])
|
||||||
"unify_variable",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyValue(r) => {
|
&FactInstruction::UnifyValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("unify_value", [aux(h, 0)], [rt_stub])
|
||||||
"unify_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&FactInstruction::UnifyVoid(vars) => {
|
&FactInstruction::UnifyVoid(vars) => {
|
||||||
functor!("unify_void", [integer(vars)])
|
functor!("unify_void", [integer(vars)])
|
||||||
@@ -726,13 +660,12 @@ pub enum QueryInstruction {
|
|||||||
impl QueryInstruction {
|
impl QueryInstruction {
|
||||||
pub fn to_functor(&self, h: usize) -> MachineStub {
|
pub fn to_functor(&self, h: usize) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&QueryInstruction::PutUnsafeValue(norm, arg) => functor!(
|
&QueryInstruction::PutUnsafeValue(norm, arg) => {
|
||||||
"put_unsafe_value",
|
functor!("put_unsafe_value", [integer(norm), integer(arg)])
|
||||||
[integer(norm), integer(arg)]
|
}
|
||||||
),
|
|
||||||
&QueryInstruction::PutConstant(lvl, ref c, r) => {
|
&QueryInstruction::PutConstant(lvl, ref c, r) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
"put_constant",
|
"put_constant",
|
||||||
@@ -742,17 +675,13 @@ impl QueryInstruction {
|
|||||||
}
|
}
|
||||||
&QueryInstruction::PutList(lvl, r) => {
|
&QueryInstruction::PutList(lvl, r) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("put_list", [aux(h, 0), aux(h, 1)], [lvl_stub, rt_stub])
|
||||||
"put_list",
|
|
||||||
[aux(h, 0), aux(h, 1)],
|
|
||||||
[lvl_stub, rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
|
&QueryInstruction::PutPartialString(lvl, ref s, r, has_tail) => {
|
||||||
let lvl_stub = lvl.into_functor();
|
let lvl_stub = lvl.into_functor();
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!(
|
||||||
"put_partial_string",
|
"put_partial_string",
|
||||||
@@ -772,29 +701,17 @@ impl QueryInstruction {
|
|||||||
&QueryInstruction::PutValue(r, arg) => {
|
&QueryInstruction::PutValue(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("put_value", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"put_value",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::GetVariable(r, arg) => {
|
&QueryInstruction::GetVariable(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("get_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"get_variable",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::PutVariable(r, arg) => {
|
&QueryInstruction::PutVariable(r, arg) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("put_variable", [aux(h, 0), integer(arg)], [rt_stub])
|
||||||
"put_variable",
|
|
||||||
[aux(h, 0), integer(arg)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetConstant(ref c) => {
|
&QueryInstruction::SetConstant(ref c) => {
|
||||||
functor!("set_constant", [constant(h, c)], [])
|
functor!("set_constant", [constant(h, c)], [])
|
||||||
@@ -802,29 +719,17 @@ impl QueryInstruction {
|
|||||||
&QueryInstruction::SetLocalValue(r) => {
|
&QueryInstruction::SetLocalValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("set_local_value", [aux(h, 0)], [rt_stub])
|
||||||
"set_local_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetVariable(r) => {
|
&QueryInstruction::SetVariable(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("set_variable", [aux(h, 0)], [rt_stub])
|
||||||
"set_variable",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetValue(r) => {
|
&QueryInstruction::SetValue(r) => {
|
||||||
let rt_stub = reg_type_into_functor(r);
|
let rt_stub = reg_type_into_functor(r);
|
||||||
|
|
||||||
functor!(
|
functor!("set_value", [aux(h, 0)], [rt_stub])
|
||||||
"set_value",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[rt_stub]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
&QueryInstruction::SetVoid(vars) => {
|
&QueryInstruction::SetVoid(vars) => {
|
||||||
functor!("set_void", [integer(vars)])
|
functor!("set_void", [integer(vars)])
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::rc_atom;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -25,11 +26,11 @@ impl<'a> TermRef<'a> {
|
|||||||
pub fn level(self) -> Level {
|
pub fn level(self) -> Level {
|
||||||
match self {
|
match self {
|
||||||
TermRef::AnonVar(lvl)
|
TermRef::AnonVar(lvl)
|
||||||
| TermRef::Cons(lvl, ..)
|
| TermRef::Cons(lvl, ..)
|
||||||
| TermRef::Constant(lvl, ..)
|
| TermRef::Constant(lvl, ..)
|
||||||
| TermRef::Var(lvl, ..)
|
| TermRef::Var(lvl, ..)
|
||||||
| TermRef::Clause(lvl, ..) => lvl,
|
| TermRef::Clause(lvl, ..) => lvl,
|
||||||
| TermRef::PartialString(lvl, ..) => lvl,
|
TermRef::PartialString(lvl, ..) => lvl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,23 +52,16 @@ pub enum TermIterState<'a> {
|
|||||||
Var(Level, &'a Cell<VarReg>, Rc<Var>),
|
Var(Level, &'a Cell<VarReg>, Rc<Var>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_partial_string<'a>(
|
fn is_partial_string<'a>(head: &'a Term, mut tail: &'a Term) -> Option<(String, Option<&'a Term>)> {
|
||||||
head: &'a Term,
|
let mut string = match head {
|
||||||
mut tail: &'a Term,
|
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
||||||
) -> Option<(String, Option<&'a Term>)>
|
atom.as_str().chars().next().unwrap().to_string()
|
||||||
{
|
}
|
||||||
let mut string =
|
&Term::Constant(_, Constant::Char(c)) => c.to_string(),
|
||||||
match head {
|
_ => {
|
||||||
&Term::Constant(_, Constant::Atom(ref atom, _)) if atom.is_char() => {
|
return None;
|
||||||
atom.as_str().chars().next().unwrap().to_string()
|
}
|
||||||
}
|
};
|
||||||
&Term::Constant(_, Constant::Char(c)) => {
|
|
||||||
c.to_string()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
while let Term::Cons(_, ref head, ref succ) = tail {
|
while let Term::Cons(_, ref head, ref succ) = tail {
|
||||||
match head.as_ref() {
|
match head.as_ref() {
|
||||||
@@ -105,9 +99,7 @@ fn is_partial_string<'a>(
|
|||||||
impl<'a> TermIterState<'a> {
|
impl<'a> TermIterState<'a> {
|
||||||
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
|
pub fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> {
|
||||||
match term {
|
match term {
|
||||||
&Term::AnonVar => {
|
&Term::AnonVar => TermIterState::AnonVar(lvl),
|
||||||
TermIterState::AnonVar(lvl)
|
|
||||||
}
|
|
||||||
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
|
&Term::Clause(ref cell, ref name, ref subterms, ref spec) => {
|
||||||
let ct = if let Some(spec) = spec {
|
let ct = if let Some(spec) = spec {
|
||||||
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
|
ClauseType::Op(name.clone(), spec.clone(), CodeIndex::default())
|
||||||
@@ -120,12 +112,8 @@ impl<'a> TermIterState<'a> {
|
|||||||
&Term::Cons(ref cell, ref head, ref tail) => {
|
&Term::Cons(ref cell, ref head, ref tail) => {
|
||||||
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
|
TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref())
|
||||||
}
|
}
|
||||||
&Term::Constant(ref cell, ref constant) => {
|
&Term::Constant(ref cell, ref constant) => TermIterState::Constant(lvl, cell, constant),
|
||||||
TermIterState::Constant(lvl, cell, constant)
|
&Term::Var(ref cell, ref var) => TermIterState::Var(lvl, cell, var.clone()),
|
||||||
}
|
|
||||||
&Term::Var(ref cell, ref var) => {
|
|
||||||
TermIterState::Var(lvl, cell, var.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,8 +163,7 @@ impl<'a> QueryIterator<'a> {
|
|||||||
state_stack: vec![],
|
state_stack: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Term::Var(ref cell, ref var) =>
|
&Term::Var(ref cell, ref var) => TermIterState::Var(Level::Root, cell, (*var).clone()),
|
||||||
TermIterState::Var(Level::Root, cell, (*var).clone()),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QueryIterator {
|
QueryIterator {
|
||||||
@@ -265,18 +252,15 @@ impl<'a> Iterator for QueryIterator<'a> {
|
|||||||
}
|
}
|
||||||
TermIterState::InitialCons(lvl, cell, head, tail) => {
|
TermIterState::InitialCons(lvl, cell, head, tail) => {
|
||||||
if let Some((string, tail)) = is_partial_string(head, tail) {
|
if let Some((string, tail)) = is_partial_string(head, tail) {
|
||||||
self.state_stack.push(TermIterState::PartialString(
|
self.state_stack
|
||||||
lvl,
|
.push(TermIterState::PartialString(lvl, cell, string, tail));
|
||||||
cell,
|
|
||||||
string,
|
|
||||||
tail,
|
|
||||||
));
|
|
||||||
|
|
||||||
if let Some(tail) = tail {
|
if let Some(tail) = tail {
|
||||||
self.push_subterm(lvl.child_level(), tail);
|
self.push_subterm(lvl.child_level(), tail);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail));
|
self.state_stack
|
||||||
|
.push(TermIterState::FinalCons(lvl, cell, head, tail));
|
||||||
|
|
||||||
self.push_subterm(lvl.child_level(), tail);
|
self.push_subterm(lvl.child_level(), tail);
|
||||||
self.push_subterm(lvl.child_level(), head);
|
self.push_subterm(lvl.child_level(), head);
|
||||||
@@ -309,7 +293,8 @@ pub struct FactIterator<'a> {
|
|||||||
|
|
||||||
impl<'a> FactIterator<'a> {
|
impl<'a> FactIterator<'a> {
|
||||||
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
|
||||||
self.state_queue.push_back(TermIterState::subterm_to_state(lvl, term));
|
self.state_queue
|
||||||
|
.push_back(TermIterState::subterm_to_state(lvl, term));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
|
pub fn from_rule_head_clause(terms: &'a Vec<Box<Term>>) -> Self {
|
||||||
@@ -393,8 +378,7 @@ impl<'a> Iterator for FactIterator<'a> {
|
|||||||
TermIterState::Var(lvl, cell, var) => {
|
TermIterState::Var(lvl, cell, var) => {
|
||||||
return Some(TermRef::Var(lvl, cell, var));
|
return Some(TermRef::Var(lvl, cell, var));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,16 +465,16 @@ impl<'a> ChunkedIterator<'a> {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
|
pub fn from_term_sequence(terms: &'a [QueryTerm]) -> Self {
|
||||||
ChunkedIterator {
|
ChunkedIterator {
|
||||||
chunk_num: 0,
|
chunk_num: 0,
|
||||||
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
|
||||||
deep_cut_encountered: false,
|
deep_cut_encountered: false,
|
||||||
cut_var_in_head: false,
|
cut_var_in_head: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
*/
|
|
||||||
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
|
pub fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec<QueryTerm>) -> Self {
|
||||||
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
|
let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1)));
|
||||||
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));
|
let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)));
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
abolish/1, asserta/1, assertz/1,
|
abolish/1, asserta/1, assertz/1,
|
||||||
at_end_of_stream/0, at_end_of_stream/1,
|
at_end_of_stream/0, at_end_of_stream/1,
|
||||||
atom_chars/2, atom_codes/2, atom_concat/3,
|
atom_chars/2, atom_codes/2, atom_concat/3,
|
||||||
atom_length/2, bagof/3, catch/3, char_code/2,
|
atom_length/2, bagof/3, call/1, call/2, call/3,
|
||||||
clause/2, close/1, close/2, current_input/1,
|
call/4, call/5, call/6, call/7, call/8, call/9,
|
||||||
current_output/1, current_op/3,
|
catch/3, char_code/2, clause/2, close/1, close/2,
|
||||||
|
current_input/1, current_output/1, current_op/3,
|
||||||
current_predicate/1, current_prolog_flag/2,
|
current_predicate/1, current_prolog_flag/2,
|
||||||
fail/0, false/0, findall/3, findall/4,
|
fail/0, false/0, findall/3, findall/4,
|
||||||
flush_output/0, flush_output/1, get_byte/1,
|
flush_output/0, flush_output/1, get_byte/1,
|
||||||
@@ -38,6 +39,30 @@ true.
|
|||||||
|
|
||||||
false :- '$fail'.
|
false :- '$fail'.
|
||||||
|
|
||||||
|
|
||||||
|
% These are stub versions of call/{1-9} defined for bootstrapping.
|
||||||
|
% Once Scryer is bootstrapped, each is replaced with a version that
|
||||||
|
% uses expand_goal to pass the expanded goal along to '$call'.
|
||||||
|
|
||||||
|
call(G) :- '$call'(G).
|
||||||
|
|
||||||
|
call(G, A) :- '$call'(G, A).
|
||||||
|
|
||||||
|
call(G, A, B) :- '$call'(G, A, B).
|
||||||
|
|
||||||
|
call(G, A, B, C) :- '$call'(G, A, B, C).
|
||||||
|
|
||||||
|
call(G, A, B, C, D) :- '$call'(G, A, B, C, D).
|
||||||
|
|
||||||
|
call(G, A, B, C, D, E) :- '$call'(G, A, B, C, D, E).
|
||||||
|
|
||||||
|
call(G, A, B, C, D, E, F) :- '$call'(G, A, B, C, D, E, F).
|
||||||
|
|
||||||
|
call(G, A, B, C, D, E, F, G) :- '$call'(G, A, B, C, D, E, F, G).
|
||||||
|
|
||||||
|
call(G, A, B, C, D, E, F, G, H) :- '$call'(G, A, B, C, D, E, F, G, H).
|
||||||
|
|
||||||
|
|
||||||
Module : Predicate :-
|
Module : Predicate :-
|
||||||
( atom(Module) ->
|
( atom(Module) ->
|
||||||
'$module_call'(Module, Predicate)
|
'$module_call'(Module, Predicate)
|
||||||
@@ -209,6 +234,8 @@ G1 -> G2 :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
|
:-non_counted_backtracking call_or_cut/3.
|
||||||
|
|
||||||
call_or_cut(G, B, ErrorPI) :-
|
call_or_cut(G, B, ErrorPI) :-
|
||||||
( '$call_with_default_policy'(var(G)) ->
|
( '$call_with_default_policy'(var(G)) ->
|
||||||
throw(error(instantiation_error, ErrorPI))
|
throw(error(instantiation_error, ErrorPI))
|
||||||
@@ -216,55 +243,71 @@ call_or_cut(G, B, ErrorPI) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
call_or_cut(!, B) :-
|
:- non_counted_backtracking call_or_cut/2.
|
||||||
|
|
||||||
|
call_or_cut(M:G, B) :-
|
||||||
|
!,
|
||||||
|
( nonvar(G),
|
||||||
|
'$call_with_default_policy'(call_or_cut_interp(G, B)) ->
|
||||||
|
true
|
||||||
|
; call(M:G)
|
||||||
|
).
|
||||||
|
call_or_cut(G, B) :-
|
||||||
|
( '$call_with_default_policy'(call_or_cut_interp(G, B)) ->
|
||||||
|
true
|
||||||
|
; call(G)
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
|
:- non_counted_backtracking call_or_cut_interp/2.
|
||||||
|
|
||||||
|
call_or_cut_interp(!, B) :-
|
||||||
'$set_cp_by_default'(B).
|
'$set_cp_by_default'(B).
|
||||||
call_or_cut((G1, G2), B) :-
|
call_or_cut_interp((G1, G2), B) :-
|
||||||
!,
|
|
||||||
'$call_with_default_policy'(','(G1, G2, B)).
|
'$call_with_default_policy'(','(G1, G2, B)).
|
||||||
call_or_cut((G1 ; G2), B) :-
|
call_or_cut_interp((G1 ; G2), B) :-
|
||||||
!,
|
|
||||||
'$call_with_default_policy'(';'(G1, G2, B)).
|
'$call_with_default_policy'(';'(G1, G2, B)).
|
||||||
call_or_cut((G1 -> G2), B) :-
|
call_or_cut_interp((G1 -> G2), B) :-
|
||||||
!,
|
|
||||||
'$call_with_default_policy'(->(G1, G2, B)).
|
'$call_with_default_policy'(->(G1, G2, B)).
|
||||||
call_or_cut(G, _) :-
|
|
||||||
'$call_with_default_policy'(G).
|
|
||||||
|
|
||||||
|
|
||||||
:- non_counted_backtracking (',')/3.
|
:- non_counted_backtracking (',')/3.
|
||||||
','((G1, G2), G3, B) :-
|
|
||||||
|
','(M:G1, G2, B) :-
|
||||||
!,
|
!,
|
||||||
'$call_with_default_policy'(','(G1, G2, B)),
|
( nonvar(G1),
|
||||||
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
|
'$call_with_default_policy'(',-interp'(G1, G2, B)) ->
|
||||||
','((G1; G2), G3, B) :-
|
true
|
||||||
!,
|
; call(M:G1),
|
||||||
'$call_with_default_policy'(';'(G1, G2, B)),
|
'$call_with_default_policy'(call_or_cut(G2, B, (',')/2))
|
||||||
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
|
).
|
||||||
','((G1 -> G2), G3, B) :-
|
|
||||||
!,
|
|
||||||
'$call_with_default_policy'(->(G1, G2, B)),
|
|
||||||
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
|
|
||||||
','(G1, G2, B) :-
|
','(G1, G2, B) :-
|
||||||
'$call_with_default_policy'(call_or_cut(G1, B, (',')/2)),
|
'$call_with_default_policy'(call_or_cut(G1, B, (',')/2)),
|
||||||
'$call_with_default_policy'(call_or_cut(G2, B, (',')/2)).
|
'$call_with_default_policy'(call_or_cut(G2, B, (',')/2)).
|
||||||
|
|
||||||
|
|
||||||
|
:- non_counted_backtracking (',-interp')/3.
|
||||||
|
|
||||||
|
',-interp'((G1, G2), G3, B) :-
|
||||||
|
'$call_with_default_policy'(','(G1, G2, B)),
|
||||||
|
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
|
||||||
|
',-interp'((G1; G2), G3, B) :-
|
||||||
|
'$call_with_default_policy'(';'(G1, G2, B)),
|
||||||
|
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
|
||||||
|
',-interp'((G1 -> G2), G3, B) :-
|
||||||
|
'$call_with_default_policy'(->(G1, G2, B)),
|
||||||
|
'$call_with_default_policy'(call_or_cut(G3, B, (',')/2)).
|
||||||
|
|
||||||
|
|
||||||
:- non_counted_backtracking (;)/3.
|
:- non_counted_backtracking (;)/3.
|
||||||
';'((G1, G2), G3, B) :-
|
|
||||||
|
';'(M:G1, G2, B) :-
|
||||||
!,
|
!,
|
||||||
( '$call_with_default_policy'(','(G1, G2, B))
|
( nonvar(G1),
|
||||||
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
|
'$call_with_default_policy'(';-interp'(G1, G2, B)) ->
|
||||||
).
|
true
|
||||||
';'((G1; G2), G3, B) :-
|
; call(M:G1)
|
||||||
!,
|
; '$call_with_default_policy'(call_or_cut(G2, B, (;)/2))
|
||||||
( '$call_with_default_policy'(';'(G1, G2, B))
|
|
||||||
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
|
|
||||||
).
|
|
||||||
';'((G1 -> G2), G3, B) :-
|
|
||||||
!,
|
|
||||||
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2)) ->
|
|
||||||
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
|
|
||||||
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
|
|
||||||
).
|
).
|
||||||
';'(G1, G2, B) :-
|
';'(G1, G2, B) :-
|
||||||
( '$call_with_default_policy'(call_or_cut(G1, B, (;)/2))
|
( '$call_with_default_policy'(call_or_cut(G1, B, (;)/2))
|
||||||
@@ -272,26 +315,54 @@ call_or_cut(G, _) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
|
:- non_counted_backtracking ';-interp'/3.
|
||||||
|
|
||||||
|
';-interp'((G1, G2), G3, B) :-
|
||||||
|
( '$call_with_default_policy'(','(G1, G2, B))
|
||||||
|
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
|
||||||
|
).
|
||||||
|
';-interp'((G1; G2), G3, B) :-
|
||||||
|
( '$call_with_default_policy'(';'(G1, G2, B))
|
||||||
|
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
|
||||||
|
).
|
||||||
|
';-interp'((G1 -> G2), G3, B) :-
|
||||||
|
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2)) ->
|
||||||
|
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
|
||||||
|
; '$call_with_default_policy'(call_or_cut(G3, B, (;)/2))
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
:- non_counted_backtracking (->)/3.
|
:- non_counted_backtracking (->)/3.
|
||||||
->((G1, G2), G3, B) :-
|
|
||||||
|
->(M:G1, G2, B) :-
|
||||||
!,
|
!,
|
||||||
|
( nonvar(G1),
|
||||||
|
'$call_with_default_policy'('->-interp'(G1, G2, B)) ->
|
||||||
|
true
|
||||||
|
; call(M:G1) ->
|
||||||
|
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
|
||||||
|
).
|
||||||
|
->(G1, G2, B) :-
|
||||||
|
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2)) ->
|
||||||
|
'$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
|
:- non_counted_backtracking '->-interp'/3.
|
||||||
|
|
||||||
|
'->-interp'((G1, G2), G3, B) :-
|
||||||
( '$call_with_default_policy'(','(G1, G2, B)) ->
|
( '$call_with_default_policy'(','(G1, G2, B)) ->
|
||||||
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
|
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
|
||||||
).
|
).
|
||||||
->((G1 ; G2), G3, B) :-
|
'->-interp'((G1 ; G2), G3, B) :-
|
||||||
!,
|
|
||||||
( '$call_with_default_policy'(';'(G1, G2, B)) ->
|
( '$call_with_default_policy'(';'(G1, G2, B)) ->
|
||||||
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
|
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
|
||||||
).
|
).
|
||||||
->((G1 -> G2), G3, B) :-
|
'->-interp'((G1 -> G2), G3, B) :-
|
||||||
!,
|
|
||||||
( '$call_with_default_policy'(->(G1, G2, B)) ->
|
( '$call_with_default_policy'(->(G1, G2, B)) ->
|
||||||
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
|
'$call_with_default_policy'(call_or_cut(G3, B, (->)/2))
|
||||||
).
|
).
|
||||||
->(G1, G2, B) :-
|
|
||||||
( '$call_with_default_policy'(call_or_cut(G1, B, (->)/2))
|
|
||||||
-> '$call_with_default_policy'(call_or_cut(G2, B, (->)/2))
|
|
||||||
).
|
|
||||||
|
|
||||||
% univ.
|
% univ.
|
||||||
|
|
||||||
@@ -640,8 +711,11 @@ iterate_variants([V-Solution|GroupSolutions], V, Solution) :-
|
|||||||
iterate_variants([_|GroupSolutions], Ws, Solution) :-
|
iterate_variants([_|GroupSolutions], Ws, Solution) :-
|
||||||
iterate_variants(GroupSolutions, Ws, Solution).
|
iterate_variants(GroupSolutions, Ws, Solution).
|
||||||
|
|
||||||
|
|
||||||
rightmost_power(Term, FinalTerm, Xs) :-
|
rightmost_power(Term, FinalTerm, Xs) :-
|
||||||
( Term = X ^ Y
|
( ( Term = X ^ Y
|
||||||
|
; Term = _ : X ^ Y
|
||||||
|
)
|
||||||
-> ( var(Y) -> FinalTerm = Y, Xs = [X]
|
-> ( var(Y) -> FinalTerm = Y, Xs = [X]
|
||||||
; Xs = [X | Xss], rightmost_power(Y, FinalTerm, Xss)
|
; Xs = [X | Xss], rightmost_power(Y, FinalTerm, Xss)
|
||||||
)
|
)
|
||||||
@@ -649,11 +723,11 @@ rightmost_power(Term, FinalTerm, Xs) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
% :- meta_predicate findall_with_existential(?, 0, ?, ?, ?).
|
|
||||||
|
|
||||||
findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses) :-
|
findall_with_existential(Template, Goal, PairedSolutions, Witnesses0, Witnesses) :-
|
||||||
( nonvar(Goal),
|
( nonvar(Goal),
|
||||||
Goal = _ ^ _ ->
|
( Goal = _ ^ _
|
||||||
|
; Goal = _ : (_ ^ _)
|
||||||
|
) ->
|
||||||
rightmost_power(Goal, Goal1, ExistentialVars0),
|
rightmost_power(Goal, Goal1, ExistentialVars0),
|
||||||
term_variables(ExistentialVars0, ExistentialVars),
|
term_variables(ExistentialVars0, ExistentialVars),
|
||||||
sort(Witnesses0, Witnesses1),
|
sort(Witnesses0, Witnesses1),
|
||||||
@@ -714,13 +788,16 @@ setof(Template, Goal, Solution) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
'$module_clause'(H, B, Module) :-
|
'$module_clause'(H, B, Module) :-
|
||||||
( var(H) -> throw(error(instantiation_error, clause/2))
|
( var(H) ->
|
||||||
|
throw(error(instantiation_error, clause/2))
|
||||||
; functor(H, Name, Arity) ->
|
; functor(H, Name, Arity) ->
|
||||||
( Name == '.' ->
|
( Name == '.' ->
|
||||||
throw(error(type_error(callable, H), clause/2))
|
throw(error(type_error(callable, H), clause/2))
|
||||||
|
; '$no_such_predicate'(Module, H) ->
|
||||||
|
'$fail'
|
||||||
; '$head_is_dynamic'(Module, H) ->
|
; '$head_is_dynamic'(Module, H) ->
|
||||||
'$clause_body_is_valid'(B),
|
'$clause_body_is_valid'(B),
|
||||||
Module:'$clause'(H, B) %%TODO: how do we show this exists?
|
Module:'$clause'(H, B)
|
||||||
; throw(error(permission_error(access, private_procedure, Name/Arity),
|
; throw(error(permission_error(access, private_procedure, Name/Arity),
|
||||||
clause/2))
|
clause/2))
|
||||||
)
|
)
|
||||||
@@ -728,8 +805,6 @@ setof(Template, Goal, Solution) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
:- dynamic('$clause'/2).
|
|
||||||
|
|
||||||
clause(H, B) :-
|
clause(H, B) :-
|
||||||
( var(H) ->
|
( var(H) ->
|
||||||
throw(error(instantiation_error, clause/2))
|
throw(error(instantiation_error, clause/2))
|
||||||
@@ -753,24 +828,19 @@ clause(H, B) :-
|
|||||||
; throw(error(type_error(callable, H), clause/2))
|
; throw(error(type_error(callable, H), clause/2))
|
||||||
).
|
).
|
||||||
|
|
||||||
call_module_asserta(Head, Body, Name, Arity, Module) :-
|
call_asserta(Head, Body, Name, Arity, Module) :-
|
||||||
'$clause_body_is_valid'(Body),
|
'$clause_body_is_valid'(Body),
|
||||||
functor(VarHead, Name, Arity),
|
functor(_, Name, Arity),
|
||||||
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses),
|
'$asserta'(Head, Body, Name, Arity, Module).
|
||||||
'$module_asserta'((Head :- Body), Clauses, Name, Arity, Module).
|
|
||||||
|
|
||||||
call_asserta(Head, Body, Name, Arity) :-
|
|
||||||
'$clause_body_is_valid'(Body),
|
|
||||||
functor(VarHead, Name, Arity),
|
|
||||||
'$asserta'(Head, Body, Name, Arity).
|
|
||||||
|
|
||||||
module_asserta_clause(Head, Body, Module) :-
|
module_asserta_clause(Head, Body, Module) :-
|
||||||
( var(Head) -> throw(error(instantiation_error, asserta/1))
|
( var(Head) ->
|
||||||
|
throw(error(instantiation_error, asserta/1))
|
||||||
; functor(Head, Name, Arity),
|
; functor(Head, Name, Arity),
|
||||||
atom(Name),
|
atom(Name),
|
||||||
Name \== '.' ->
|
Name \== '.' ->
|
||||||
( '$module_head_is_dynamic'(Head, Module) ->
|
( '$head_is_dynamic'(Module, Head) ->
|
||||||
call_module_asserta(Head, Body, Name, Arity, Module)
|
call_asserta(Head, Body, Name, Arity, Module)
|
||||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
|
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(callable, Head), asserta/1))
|
; throw(error(type_error(callable, Head), asserta/1))
|
||||||
@@ -787,9 +857,9 @@ asserta_clause(Head, Body) :-
|
|||||||
arg(2, Head, F),
|
arg(2, Head, F),
|
||||||
module_asserta_clause(F, Body, Module)
|
module_asserta_clause(F, Body, Module)
|
||||||
; '$no_such_predicate'(user, Head) ->
|
; '$no_such_predicate'(user, Head) ->
|
||||||
call_asserta(Head, Body, Name, Arity)
|
call_asserta(Head, Body, Name, Arity, user)
|
||||||
; '$head_is_dynamic'(user, Head) ->
|
; '$head_is_dynamic'(user, Head) ->
|
||||||
call_asserta(Head, Body, Name, Arity)
|
call_asserta(Head, Body, Name, Arity, user)
|
||||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
|
; throw(error(permission_error(modify, static_procedure, Name/Arity), asserta/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(callable, Head), asserta/1))
|
; throw(error(type_error(callable, Head), asserta/1))
|
||||||
@@ -798,36 +868,33 @@ asserta_clause(Head, Body) :-
|
|||||||
asserta(Clause) :-
|
asserta(Clause) :-
|
||||||
( Clause \= (_ :- _) ->
|
( Clause \= (_ :- _) ->
|
||||||
Head = Clause,
|
Head = Clause,
|
||||||
Body = true, asserta_clause(Head, Body)
|
Body = true,
|
||||||
|
asserta_clause(Head, Body)
|
||||||
; Clause = (Head :- Body) ->
|
; Clause = (Head :- Body) ->
|
||||||
asserta_clause(Head, Body)
|
asserta_clause(Head, Body)
|
||||||
).
|
).
|
||||||
|
|
||||||
% NOT MODIFIED.
|
|
||||||
call_module_assertz(Head, Body, Name, Arity, Module) :-
|
|
||||||
'$clause_body_is_valid'(Body),
|
|
||||||
functor(VarHead, Name, Arity),
|
|
||||||
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses),
|
|
||||||
'$module_assertz'((Head :- Body), Clauses, Name, Arity, Module).
|
|
||||||
|
|
||||||
module_assertz_clause(Head, Body, Module) :-
|
module_assertz_clause(Head, Body, Module) :-
|
||||||
( var(Head) ->
|
( var(Head) ->
|
||||||
throw(error(instantiation_error, assertz/1))
|
throw(error(instantiation_error, assertz/1))
|
||||||
; functor(Head, Name, Arity),
|
; functor(Head, Name, Arity),
|
||||||
atom(Name),
|
atom(Name),
|
||||||
Name \== '.' ->
|
Name \== '.' ->
|
||||||
( '$head_is_dynamic'(Module, Head) ->
|
( '$no_such_predicate'(Module, Head) ->
|
||||||
call_module_assertz(Head, Body, Name, Arity, Module)
|
call_assertz(Head, Body, Name, Arity, Module)
|
||||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1))
|
; '$head_is_dynamic'(Module, Head) ->
|
||||||
|
call_assertz(Head, Body, Name, Arity, Module)
|
||||||
|
; throw(error(permission_error(modify, static_procedure, Name/Arity),
|
||||||
|
assertz/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(callable, Head), assertz/1))
|
; throw(error(type_error(callable, Head), assertz/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
% MODIFIED.
|
|
||||||
call_assertz(Head, Body, Name, Arity) :-
|
call_assertz(Head, Body, Name, Arity, Module) :-
|
||||||
'$clause_body_is_valid'(Body),
|
'$clause_body_is_valid'(Body),
|
||||||
functor(VarHead, Name, Arity),
|
functor(_, Name, Arity),
|
||||||
'$assertz'(Head, Body, Name, Arity).
|
'$assertz'(Head, Body, Name, Arity, Module).
|
||||||
|
|
||||||
assertz_clause(Head, Body) :-
|
assertz_clause(Head, Body) :-
|
||||||
( var(Head) ->
|
( var(Head) ->
|
||||||
@@ -835,16 +902,17 @@ assertz_clause(Head, Body) :-
|
|||||||
; functor(Head, Name, Arity),
|
; functor(Head, Name, Arity),
|
||||||
atom(Name),
|
atom(Name),
|
||||||
Name \== '.' ->
|
Name \== '.' ->
|
||||||
( Name == (:),
|
( Name == (:),
|
||||||
Arity =:= 2 ->
|
Arity =:= 2 ->
|
||||||
arg(1, Head, Module),
|
arg(1, Head, Module),
|
||||||
arg(2, Head, F),
|
arg(2, Head, F),
|
||||||
module_assertz_clause(F, Body, Module)
|
module_assertz_clause(F, Body, Module)
|
||||||
; '$no_such_predicate'(user, Head) ->
|
; '$no_such_predicate'(user, Head) ->
|
||||||
call_assertz(Head, Body, Name, Arity)
|
call_assertz(Head, Body, Name, Arity, user)
|
||||||
; '$head_is_dynamic'(user, Head) ->
|
; '$head_is_dynamic'(user, Head) ->
|
||||||
call_assertz(Head, Body, Name, Arity)
|
call_assertz(Head, Body, Name, Arity, user)
|
||||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), assertz/1))
|
; throw(error(permission_error(modify, static_procedure, Name/Arity),
|
||||||
|
assertz/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(callable, Head), assertz/1))
|
; throw(error(type_error(callable, Head), assertz/1))
|
||||||
).
|
).
|
||||||
@@ -861,18 +929,18 @@ assertz(Clause) :-
|
|||||||
|
|
||||||
module_retract_clauses([Clause|Clauses0], Head, Body, Name, Arity, Module) :-
|
module_retract_clauses([Clause|Clauses0], Head, Body, Name, Arity, Module) :-
|
||||||
functor(VarHead, Name, Arity),
|
functor(VarHead, Name, Arity),
|
||||||
findall((VarHead :- VarBody), builtins:clause(Module:VarHead, VarBody), Clauses1),
|
findall((VarHead :- VarBody), Module:'$clause'(VarHead, VarBody), Clauses1),
|
||||||
first_match_index(Clauses1, (Head :- Body), 0, N),
|
first_match_index(Clauses1, (Head :- Body), 0, N),
|
||||||
( Clauses0 == [] -> !
|
( Clauses0 == [] -> !
|
||||||
; true
|
; true
|
||||||
),
|
),
|
||||||
'$module_retract_clause'(Name, Arity, N, Clauses1, Module).
|
'$retract_clause'(Name, Arity, N, Module).
|
||||||
|
|
||||||
module_retract_clauses([_|Clauses0], Head, Body, Name, Arity, Module) :-
|
module_retract_clauses([_|Clauses0], Head, Body, Name, Arity, Module) :-
|
||||||
module_retract_clauses(Clauses0, Head, Body, Name, Arity, Module).
|
module_retract_clauses(Clauses0, Head, Body, Name, Arity, Module).
|
||||||
|
|
||||||
call_module_retract(Head, Body, Name, Arity, Module) :-
|
call_module_retract(Head, Body, Name, Arity, Module) :-
|
||||||
findall((Head :- Body), builtins:clause(Module:Head, Body), Clauses),
|
findall((Head :- Body), Module:'$clause'(Head, Body), Clauses),
|
||||||
module_retract_clauses(Clauses, Head, Body, Name, Arity, Module).
|
module_retract_clauses(Clauses, Head, Body, Name, Arity, Module).
|
||||||
|
|
||||||
retract_module_clause(Head, Body, Module) :-
|
retract_module_clause(Head, Body, Module) :-
|
||||||
@@ -881,9 +949,12 @@ retract_module_clause(Head, Body, Module) :-
|
|||||||
; functor(Head, Name, Arity),
|
; functor(Head, Name, Arity),
|
||||||
atom(Name),
|
atom(Name),
|
||||||
Name \== '.' ->
|
Name \== '.' ->
|
||||||
( '$module_head_is_dynamic'(Head, Module) ->
|
( '$head_is_dynamic'(Module, Head) ->
|
||||||
call_module_retract(Head, Body, Name, Arity, Module)
|
( Module == user ->
|
||||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
call_retract(Head, Body, Name, Arity)
|
||||||
|
; call_module_retract(Head, Body, Name, Arity, Module)
|
||||||
|
)
|
||||||
|
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(callable, Head), retract/1))
|
; throw(error(type_error(callable, Head), retract/1))
|
||||||
).
|
).
|
||||||
@@ -904,7 +975,7 @@ retract_clauses([Clause | Clauses0], Head, Body, Name, Arity) :-
|
|||||||
( Clauses0 == [] -> !
|
( Clauses0 == [] -> !
|
||||||
; true
|
; true
|
||||||
),
|
),
|
||||||
'$retract_clause'(Name, Arity, N).
|
'$retract_clause'(Name, Arity, N, user).
|
||||||
|
|
||||||
retract_clauses([_ | Clauses0], Head, Body, Name, Arity) :-
|
retract_clauses([_ | Clauses0], Head, Body, Name, Arity) :-
|
||||||
retract_clauses(Clauses0, Head, Body, Name, Arity).
|
retract_clauses(Clauses0, Head, Body, Name, Arity).
|
||||||
@@ -919,16 +990,16 @@ retract_clause(Head, Body) :-
|
|||||||
; functor(Head, Name, Arity),
|
; functor(Head, Name, Arity),
|
||||||
atom(Name),
|
atom(Name),
|
||||||
Name \== '.' ->
|
Name \== '.' ->
|
||||||
( Name == (:),
|
( Name == (:),
|
||||||
Arity =:= 2 ->
|
Arity =:= 2 ->
|
||||||
arg(1, Head, Module),
|
arg(1, Head, Module),
|
||||||
arg(2, Head, F),
|
arg(2, Head, F),
|
||||||
retract_module_clause(F, Body, Module)
|
retract_module_clause(F, Body, Module)
|
||||||
; '$head_is_dynamic'(user, Head) ->
|
; '$head_is_dynamic'(user, Head) ->
|
||||||
call_retract(Head, Body, Name, Arity)
|
call_retract(Head, Body, Name, Arity)
|
||||||
; '$no_such_predicate'(user, Head) ->
|
; '$no_such_predicate'(user, Head) ->
|
||||||
'$fail'
|
'$fail'
|
||||||
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
; throw(error(permission_error(modify, static_procedure, Name/Arity), retract/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(callable, Head), retract/1))
|
; throw(error(type_error(callable, Head), retract/1))
|
||||||
).
|
).
|
||||||
@@ -950,21 +1021,21 @@ module_abolish(Pred, Module) :-
|
|||||||
( var(Name) ->
|
( var(Name) ->
|
||||||
throw(error(instantiation_error, abolish/1))
|
throw(error(instantiation_error, abolish/1))
|
||||||
; integer(Arity) ->
|
; integer(Arity) ->
|
||||||
( \+ atom(Name) ->
|
( \+ atom(Name) ->
|
||||||
throw(error(type_error(atom, Name), abolish/1))
|
throw(error(type_error(atom, Name), abolish/1))
|
||||||
; Arity < 0 ->
|
; Arity < 0 ->
|
||||||
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
||||||
; max_arity(N), Arity > N ->
|
; max_arity(N), Arity > N ->
|
||||||
throw(error(representation_error(max_arity), abolish/1))
|
throw(error(representation_error(max_arity), abolish/1))
|
||||||
; functor(Head, Name, Arity) ->
|
; functor(Head, Name, Arity) ->
|
||||||
( '$module_head_is_dynamic'(Head, Module) ->
|
( '$head_is_dynamic'(Module, Head) ->
|
||||||
'$abolish_module_clause'(Name, Arity, Module)
|
'$abolish_clause'(Module, Name, Arity)
|
||||||
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
|
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
; throw(error(type_error(integer, Arity), abolish/1))
|
; throw(error(type_error(integer, Arity), abolish/1))
|
||||||
)
|
)
|
||||||
; throw(error(type_error(predicate_indicator, Module:Pred), abolish/1))
|
; throw(error(type_error(predicate_indicator, Module:Pred), abolish/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
abolish(Pred) :-
|
abolish(Pred) :-
|
||||||
@@ -978,17 +1049,19 @@ abolish(Pred) :-
|
|||||||
; var(Arity) ->
|
; var(Arity) ->
|
||||||
throw(error(instantiation_error, abolish/1))
|
throw(error(instantiation_error, abolish/1))
|
||||||
; integer(Arity) ->
|
; integer(Arity) ->
|
||||||
( \+ atom(Name) ->
|
( \+ atom(Name) ->
|
||||||
throw(error(type_error(atom, Name), abolish/1))
|
throw(error(type_error(atom, Name), abolish/1))
|
||||||
; Arity < 0 ->
|
; Arity < 0 ->
|
||||||
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
throw(error(domain_error(not_less_than_zero, Arity), abolish/1))
|
||||||
; max_arity(N), Arity > N ->
|
; max_arity(N), Arity > N ->
|
||||||
throw(error(representation_error(max_arity), abolish/1))
|
throw(error(representation_error(max_arity), abolish/1))
|
||||||
; functor(Head, Name, Arity) ->
|
; functor(Head, Name, Arity) ->
|
||||||
( '$no_such_predicate'(Head) -> true
|
( '$no_such_predicate'(user, Head) ->
|
||||||
; '$head_is_dynamic'(Head) -> '$abolish_clause'(Name, Arity)
|
true
|
||||||
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
|
; '$head_is_dynamic'(user, Head) ->
|
||||||
)
|
'$abolish_clause'(user, Name, Arity)
|
||||||
|
; throw(error(permission_error(modify, static_procedure, Pred), abolish/1))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
; throw(error(type_error(integer, Arity), abolish/1))
|
; throw(error(type_error(integer, Arity), abolish/1))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3068,12 +3068,10 @@ is_false(var(X)) :- nonvar(X).
|
|||||||
|
|
||||||
:- dynamic(goal_expansion/1).
|
:- dynamic(goal_expansion/1).
|
||||||
|
|
||||||
% goal expansion is disabled for now, until #445 is resolved
|
user:goal_expansion(Goal0, Goal) :-
|
||||||
%
|
\+ goal_expansion(false),
|
||||||
% user:goal_expansion(Goal0, Goal) :-
|
clpz_expandable(Goal0),
|
||||||
% \+ goal_expansion(false),
|
clpz_expansion(Goal0, Goal).
|
||||||
% clpz_expandable(Goal0),
|
|
||||||
% clpz_expansion(Goal0, Goal).
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|||||||
@@ -125,3 +125,5 @@
|
|||||||
:- meta_predicate call(61, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
:- meta_predicate call(61, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||||
:- meta_predicate call(62, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
:- meta_predicate call(62, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||||
:- meta_predicate call(63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
:- meta_predicate call(63, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||||
|
:- meta_predicate call(64, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||||
|
:- meta_predicate call(65, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?).
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ parse_socket_options_(Option, OptionPair) :-
|
|||||||
|
|
||||||
parse_socket_options(Options, OptionValues, Stub) :-
|
parse_socket_options(Options, OptionValues, Stub) :-
|
||||||
DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, tls-false, type-text],
|
DefaultOptions = [alias-[], eof_action-eof_code, reposition-false, tls-false, type-text],
|
||||||
builtins:parse_options_list(Options, parse_socket_options_, DefaultOptions, OptionValues, Stub).
|
builtins:parse_options_list(Options, sockets:parse_socket_options_, DefaultOptions, OptionValues, Stub).
|
||||||
|
|
||||||
socket_client_open(Addr, Stream, Options) :-
|
socket_client_open(Addr, Stream, Options) :-
|
||||||
( var(Addr) ->
|
( var(Addr) ->
|
||||||
|
|||||||
844
src/loader.pl
844
src/loader.pl
@@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
|
|
||||||
'$print_message_and_fail'(Error, Culprit) :-
|
'$print_message_and_fail'(Error, Culprit) :-
|
||||||
% writeq(error(Error, Culprit)),
|
% writeq(error(Error, Culprit)),
|
||||||
% nl,
|
% nl,
|
||||||
'$fail'.
|
'$fail'.
|
||||||
|
|
||||||
expand_term(Term, ExpandedTerm) :-
|
expand_term(Term, ExpandedTerm) :-
|
||||||
( catch(user:term_expansion(Term, ExpandedTerm0),
|
( catch('$call'(user:term_expansion(Term, ExpandedTerm0)),
|
||||||
E,
|
E,
|
||||||
loader:'$print_message_and_fail'(E, user:term_expansion)) ->
|
'$call'(loader:'$print_message_and_fail'(E, user:term_expansion))) ->
|
||||||
( var(ExpandedTerm0) ->
|
( var(ExpandedTerm0) ->
|
||||||
error:instantiation_error(term_expansion/2)
|
error:instantiation_error(term_expansion/2)
|
||||||
; ExpandedTerm0 = [_|_] ->
|
; ExpandedTerm0 = [_|_] ->
|
||||||
@@ -35,7 +35,6 @@ expand_term(Term, ExpandedTerm) :-
|
|||||||
; Term = ExpandedTerm
|
; Term = ExpandedTerm
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
term_expansion_list([], ExpandedTerms, ExpandedTerms).
|
term_expansion_list([], ExpandedTerms, ExpandedTerms).
|
||||||
term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
|
term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
|
||||||
expand_term(Term, ExpandedTerm0),
|
expand_term(Term, ExpandedTerm0),
|
||||||
@@ -50,9 +49,9 @@ term_expansion_list([Term|Terms], ExpandedTermsHead, ExpandedTermsTail) :-
|
|||||||
|
|
||||||
|
|
||||||
goal_expansion(Goal, Module, ExpandedGoal) :-
|
goal_expansion(Goal, Module, ExpandedGoal) :-
|
||||||
( catch(Module:goal_expansion(Goal, ExpandedGoal0),
|
( catch('$call'(Module:goal_expansion(Goal, ExpandedGoal0)),
|
||||||
E,
|
E,
|
||||||
loader:'$print_message_and_fail'(E, Module:goal_expansion)) ->
|
'$call'(loader:'$print_message_and_fail'(E, Module:goal_expansion))) ->
|
||||||
( var(ExpandedGoal0) ->
|
( var(ExpandedGoal0) ->
|
||||||
error:instantiation_error(goal_expansion/2)
|
error:instantiation_error(goal_expansion/2)
|
||||||
; goal_expansion(ExpandedGoal0, Module, ExpandedGoal)
|
; goal_expansion(ExpandedGoal0, Module, ExpandedGoal)
|
||||||
@@ -74,6 +73,16 @@ unload_evacuable(Evacuable) :-
|
|||||||
'$pop_load_state_payload'(Evacuable),
|
'$pop_load_state_payload'(Evacuable),
|
||||||
'$pop_load_context'.
|
'$pop_load_context'.
|
||||||
|
|
||||||
|
run_initialization_goals :-
|
||||||
|
prolog_load_context(module, Module),
|
||||||
|
( predicate_property(Module:'$initialization_goals'(_), dynamic) ->
|
||||||
|
findall(Goal, '$call'(builtins:retract(Module:'$initialization_goals'(Goal))), Goals),
|
||||||
|
( maplist(Module:call, Goals) ->
|
||||||
|
true
|
||||||
|
; true %% initialization goals can fail without thwarting the load.
|
||||||
|
)
|
||||||
|
; true
|
||||||
|
).
|
||||||
|
|
||||||
file_load(Stream, Path) :-
|
file_load(Stream, Path) :-
|
||||||
file_load(Stream, Path, _).
|
file_load(Stream, Path, _).
|
||||||
@@ -83,6 +92,7 @@ file_load(Stream, Path, Evacuable) :-
|
|||||||
catch(loader:load_loop(Stream, Evacuable),
|
catch(loader:load_loop(Stream, Evacuable),
|
||||||
E,
|
E,
|
||||||
(loader:unload_evacuable(Evacuable), throw(E))),
|
(loader:unload_evacuable(Evacuable), throw(E))),
|
||||||
|
run_initialization_goals,
|
||||||
'$pop_load_context'.
|
'$pop_load_context'.
|
||||||
|
|
||||||
|
|
||||||
@@ -91,6 +101,7 @@ load(Stream) :-
|
|||||||
catch(loader:load_loop(Stream, Evacuable),
|
catch(loader:load_loop(Stream, Evacuable),
|
||||||
E,
|
E,
|
||||||
(loader:unload_evacuable(Evacuable), throw(E))),
|
(loader:unload_evacuable(Evacuable), throw(E))),
|
||||||
|
run_initialization_goals,
|
||||||
'$pop_load_context'.
|
'$pop_load_context'.
|
||||||
|
|
||||||
load_loop(Stream, Evacuable) :-
|
load_loop(Stream, Evacuable) :-
|
||||||
@@ -195,8 +206,7 @@ compile_dispatch_or_clause(Term, Evacuable, VNs) :-
|
|||||||
compile_dispatch((:- Declaration), Evacuable, _VNs) :-
|
compile_dispatch((:- Declaration), Evacuable, _VNs) :-
|
||||||
( var(Declaration) ->
|
( var(Declaration) ->
|
||||||
instantiation_error(load/1)
|
instantiation_error(load/1)
|
||||||
;
|
; compile_declaration(Declaration, Evacuable)
|
||||||
compile_declaration(Declaration, Evacuable)
|
|
||||||
).
|
).
|
||||||
compile_dispatch(term_expansion(Term, Terms), Evacuable, VNs) :-
|
compile_dispatch(term_expansion(Term, Terms), Evacuable, VNs) :-
|
||||||
'$add_term_expansion_clause'(term_expansion(Term, Terms), Evacuable, VNs).
|
'$add_term_expansion_clause'(term_expansion(Term, Terms), Evacuable, VNs).
|
||||||
@@ -224,13 +234,13 @@ compile_declaration(use_module(Module, Exports), Evacuable) :-
|
|||||||
( Exports == [] ->
|
( Exports == [] ->
|
||||||
'$remove_module_exports'(Module, Evacuable) % TODO: implement this.
|
'$remove_module_exports'(Module, Evacuable) % TODO: implement this.
|
||||||
;
|
;
|
||||||
use_module(Module, Exports, Evacuable)
|
use_module(Module, Exports, Evacuable)
|
||||||
).
|
).
|
||||||
compile_declaration(module(Module, Exports), Evacuable) :-
|
compile_declaration(module(Module, Exports), Evacuable) :-
|
||||||
( atom(Module) ->
|
( atom(Module) ->
|
||||||
'$declare_module'(Module, Exports, Evacuable)
|
'$declare_module'(Module, Exports, Evacuable)
|
||||||
;
|
;
|
||||||
type_error(atom, Module, load/1)
|
type_error(atom, Module, load/1)
|
||||||
).
|
).
|
||||||
compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
||||||
must_be(atom, Name),
|
must_be(atom, Name),
|
||||||
@@ -238,9 +248,8 @@ compile_declaration(dynamic(Name/Arity), Evacuable) :-
|
|||||||
'$add_dynamic_predicate'(Name, Arity, Evacuable).
|
'$add_dynamic_predicate'(Name, Arity, Evacuable).
|
||||||
compile_declaration(initialization(Goal), Evacuable) :-
|
compile_declaration(initialization(Goal), Evacuable) :-
|
||||||
prolog_load_context(module, Module),
|
prolog_load_context(module, Module),
|
||||||
'$compile_pending_predicates'(Evacuable),
|
assertz(Module:'$initialization_goals'(Goal)).
|
||||||
expand_goal(call(Goal), Module, call(ExpandedGoal)),
|
|
||||||
call(ExpandedGoal).
|
|
||||||
|
|
||||||
|
|
||||||
compile_clause(Clause, Evacuable, VNs) :-
|
compile_clause(Clause, Evacuable, VNs) :-
|
||||||
@@ -290,45 +299,64 @@ use_module(Module, Exports) :-
|
|||||||
'$push_load_state_payload'(Evacuable),
|
'$push_load_state_payload'(Evacuable),
|
||||||
( Exports == [] ->
|
( Exports == [] ->
|
||||||
'$remove_module_exports'(Module, Evacuable)
|
'$remove_module_exports'(Module, Evacuable)
|
||||||
;
|
; use_module(Module, Exports, Evacuable)
|
||||||
use_module(Module, Exports, Evacuable)
|
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
%% If use_module is invoked in an existing load context, use its
|
%% If use_module is invoked in an existing load context, use its
|
||||||
%% directory. Otherwise, use the relative path of Path.
|
%% directory. Otherwise, use the relative path of Path.
|
||||||
|
|
||||||
load_context_path(Module, Path) :-
|
load_context_path(Module, Path) :-
|
||||||
( prolog_load_context(directory, CurrentDir) ->
|
( prolog_load_context(directory, CurrentDir) ->
|
||||||
atom_concat(CurrentDir, Path, Module)
|
% Rust's Path module never ends a directory path with '/', so
|
||||||
;
|
% add one here.
|
||||||
Module = Path
|
atom_concat(CurrentDir, '/', CurrentDirSlashed),
|
||||||
|
atom_concat(CurrentDirSlashed, Module, Path)
|
||||||
|
; Module = Path
|
||||||
).
|
).
|
||||||
|
|
||||||
|
path_atom(Dir/File, Path) :-
|
||||||
|
must_be(atom, File),
|
||||||
|
!,
|
||||||
|
path_atom(Dir, DirPath),
|
||||||
|
foldl(builtins:atom_concat, ['/', DirPath], File, Path).
|
||||||
|
path_atom(Path, Path) :-
|
||||||
|
must_be(atom, Path).
|
||||||
|
|
||||||
|
% Try to open the file with the Path name as given; if that fails,
|
||||||
|
% append '.pl' and try again.
|
||||||
|
open_file(Path, Stream) :-
|
||||||
|
( atom_concat(_, '.pl', Path) ->
|
||||||
|
open(Path, read, Stream)
|
||||||
|
; catch(open(Path, read, Stream),
|
||||||
|
error(existence_error(source_sink, Path), _),
|
||||||
|
( atom_concat(Path, '.pl', ExtendedPath),
|
||||||
|
open(ExtendedPath, read, Stream) )
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
use_module(Module, Exports, Evacuable) :-
|
use_module(Module, Exports, Evacuable) :-
|
||||||
( var(Module) ->
|
( var(Module) ->
|
||||||
instantiation_error(load/1)
|
instantiation_error(load/1)
|
||||||
; Module = library(Library) ->
|
; Module = library(Library) ->
|
||||||
( atom(Library) ->
|
( path_atom(Library, LibraryPath) ->
|
||||||
( '$load_compiled_library'(Library, Evacuable) -> %% TODO: What about Exports?
|
( '$load_compiled_library'(LibraryPath, Evacuable) -> %% TODO: What about Exports?
|
||||||
true
|
true
|
||||||
;
|
; '$load_library_as_stream'(LibraryPath, Stream, Path),
|
||||||
'$load_library_as_stream'(Library, Stream, Path),
|
|
||||||
file_load(Stream, Path, Subevacuable),
|
file_load(Stream, Path, Subevacuable),
|
||||||
'$use_module'(Evacuable, Subevacuable, Exports)
|
'$use_module'(Evacuable, Subevacuable, Exports)
|
||||||
)
|
)
|
||||||
; var(Library) ->
|
; var(Library) ->
|
||||||
instantiation_error(load/1)
|
instantiation_error(load/1)
|
||||||
;
|
; type_error(atom, Library, load/1)
|
||||||
type_error(atom, Library, load/1)
|
)
|
||||||
|
; ( path_atom(Module, ModulePath) ->
|
||||||
|
load_context_path(ModulePath, Path),
|
||||||
|
open_file(Path, Stream),
|
||||||
|
file_load(Stream, Path, Subevacuable),
|
||||||
|
'$use_module'(Evacuable, Subevacuable, Exports)
|
||||||
|
; type_error(atom, Library, load/1)
|
||||||
)
|
)
|
||||||
; atom(Module) ->
|
|
||||||
load_context_path(Module, Path),
|
|
||||||
open(Path, read, Stream),
|
|
||||||
file_load(Stream, Path, Subevacuable),
|
|
||||||
'$use_module'(Evacuable, Subevacuable, Exports)
|
|
||||||
;
|
|
||||||
type_error(atom, Library, load/1)
|
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
@@ -337,6 +365,13 @@ check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm)
|
|||||||
'$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
'$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
||||||
check_predicate_property(built_in, _, Name, Arity, built_in) :-
|
check_predicate_property(built_in, _, Name, Arity, built_in) :-
|
||||||
'$cpp_built_in_property'(Name, Arity).
|
'$cpp_built_in_property'(Name, Arity).
|
||||||
|
check_predicate_property(dynamic, Module, Name, Arity, dynamic) :-
|
||||||
|
'$cpp_dynamic_property'(Module, Name, Arity).
|
||||||
|
check_predicate_property(multifile, Module, Name, Arity, multifile) :-
|
||||||
|
'$cpp_multifile_property'(Module, Name, Arity).
|
||||||
|
check_predicate_property(discontiguous, Module, Name, Arity, multifile) :-
|
||||||
|
'$cpp_discontiguous_property'(Module, Name, Arity).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extract_predicate_property(Property, PropertyType) :-
|
extract_predicate_property(Property, PropertyType) :-
|
||||||
@@ -345,35 +380,47 @@ extract_predicate_property(Property, PropertyType) :-
|
|||||||
; functor(Property, PropertyType, _)
|
; functor(Property, PropertyType, _)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
load_context(Module) :-
|
||||||
|
( prolog_load_context(module, Module) ->
|
||||||
|
true
|
||||||
|
; Module = user
|
||||||
|
).
|
||||||
|
|
||||||
predicate_property(Callable, Property) :-
|
predicate_property(Callable, Property) :-
|
||||||
( var(Callable) ->
|
( var(Callable) ->
|
||||||
instantiation_error(load/1)
|
instantiation_error(load/1)
|
||||||
; Callable =.. [(:), Module, Callable0],
|
; functor(Callable, (:), 2), % Callable =.. [(:), Module, Callable0],
|
||||||
|
arg(1, Callable, Module),
|
||||||
|
arg(2, Callable, Callable0),
|
||||||
atom(Module) ->
|
atom(Module) ->
|
||||||
functor(Callable0, Name, Arity),
|
functor(Callable0, Name, Arity),
|
||||||
extract_predicate_property(Property, PropertyType),
|
( atom(Name),
|
||||||
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
Name \== [] ->
|
||||||
|
extract_predicate_property(Property, PropertyType),
|
||||||
|
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
||||||
|
; type_error(callable, Callable0, predicate_property/2)
|
||||||
|
)
|
||||||
; functor(Callable, Name, Arity),
|
; functor(Callable, Name, Arity),
|
||||||
extract_predicate_property(Property, PropertyType),
|
( atom(Name),
|
||||||
( prolog_load_context(module, Module) ->
|
Name \== [] ->
|
||||||
true
|
extract_predicate_property(Property, PropertyType),
|
||||||
; Module = user
|
load_context(Module),
|
||||||
),
|
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
||||||
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
; type_error(callable, Callable, predicate_property/2)
|
||||||
|
)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
strip_module_(M0, G0, M1, G1) :-
|
strip_module(M0, G0, M1, G1) :-
|
||||||
( nonvar(G0),
|
( nonvar(G0),
|
||||||
G0 = (MG1:G2) ->
|
G0 = (MG1:G2) ->
|
||||||
strip_module_(MG1, G2, M1, G1)
|
strip_module(MG1, G2, M1, G1)
|
||||||
; M0 = M1,
|
; M0 = M1,
|
||||||
G0 = G1
|
G0 = G1
|
||||||
).
|
).
|
||||||
|
|
||||||
strip_module(Goal, M, G) :-
|
strip_module(Goal, M, G) :-
|
||||||
strip_module_(_, Goal, M, G).
|
strip_module(_, Goal, M, G).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
|
expand_subgoal(UnexpandedGoals, MS, Module, ExpandedGoals, HeadVars) :-
|
||||||
@@ -498,3 +545,710 @@ thread_goals(Goals0, Goals1, Hole, Functor) :-
|
|||||||
; Goals1 =.. [Functor, Goals0, Hole]
|
; Goals1 =.. [Functor, Goals0, Hole]
|
||||||
)
|
)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%
|
||||||
|
% call/{1-64} with dynamic goal expansion.
|
||||||
|
%
|
||||||
|
% The program used to generate the call/N predicates:
|
||||||
|
%
|
||||||
|
%
|
||||||
|
% :- use_module(library(between)).
|
||||||
|
% :- use_module(library(error)).
|
||||||
|
% :- use_module(library(lists)).
|
||||||
|
% :- use_module(library(format)).
|
||||||
|
%
|
||||||
|
% call_form_generator(N) :-
|
||||||
|
% length(Args, N),
|
||||||
|
% CallHead =.. [call, G | Args],
|
||||||
|
% N1 is N + 1,
|
||||||
|
% Form = (CallHead :- ( var(G) ->
|
||||||
|
% instantiation_error(call/N1)
|
||||||
|
% ; call_clause(G, Args, N1, G0) ->
|
||||||
|
% '$call'(G0)
|
||||||
|
% ; type_error(callable, G, call/N1)
|
||||||
|
% )),
|
||||||
|
% portray_clause(Form).
|
||||||
|
%
|
||||||
|
% generate_call_forms :-
|
||||||
|
% between(1, 64, N),
|
||||||
|
% call_form_generator(N),
|
||||||
|
% nl,
|
||||||
|
% false.
|
||||||
|
%
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
|
call_clause(M:G1, G0) :-
|
||||||
|
functor(G1, F, _),
|
||||||
|
atom(F),
|
||||||
|
atom(M),
|
||||||
|
F \== [],
|
||||||
|
!,
|
||||||
|
expand_goal(M:G1, M, G0).
|
||||||
|
|
||||||
|
% The '$call' functor is an escape hatch from goal expansion. So far,
|
||||||
|
% it is used only to avoid infinite recursion into expand_goal/3.
|
||||||
|
|
||||||
|
call_clause('$call'(G), G0) :-
|
||||||
|
( var(G),
|
||||||
|
instantiation_error(call/1)
|
||||||
|
; G = M:G1,
|
||||||
|
!,
|
||||||
|
functor(G1, F, _),
|
||||||
|
atom(F),
|
||||||
|
atom(M),
|
||||||
|
F \== [],
|
||||||
|
G0 = M:G1
|
||||||
|
; !,
|
||||||
|
functor(G, F, _),
|
||||||
|
atom(F),
|
||||||
|
F \== [],
|
||||||
|
load_context(M),
|
||||||
|
G0 = M:G
|
||||||
|
).
|
||||||
|
|
||||||
|
call_clause(G, G0) :-
|
||||||
|
functor(G, F, _),
|
||||||
|
atom(F),
|
||||||
|
F \== [],
|
||||||
|
load_context(M),
|
||||||
|
expand_goal(M:G, M, G0).
|
||||||
|
|
||||||
|
|
||||||
|
call(G) :-
|
||||||
|
( var(G) ->
|
||||||
|
instantiation_error(call/1)
|
||||||
|
; call_clause(G, G0) ->
|
||||||
|
'$call'(G0)
|
||||||
|
; type_error(callable, G, call/1)
|
||||||
|
).
|
||||||
|
|
||||||
|
|
||||||
|
call_clause(M:G1, Args, _, G0) :-
|
||||||
|
atom(M),
|
||||||
|
G1 =.. [F | As],
|
||||||
|
atom(F),
|
||||||
|
F \== [],
|
||||||
|
!,
|
||||||
|
append(As, Args, As1),
|
||||||
|
G2 =.. [F | As1],
|
||||||
|
expand_goal(M:G2, M, G0).
|
||||||
|
|
||||||
|
call_clause('$call'(G1), Args, N, G0) :-
|
||||||
|
( var(G1),
|
||||||
|
instantiation_error(call/N)
|
||||||
|
; G1 = M:G2,
|
||||||
|
!,
|
||||||
|
atom(M),
|
||||||
|
G2 =.. [F | As],
|
||||||
|
atom(F),
|
||||||
|
F \== [],
|
||||||
|
append(As, Args, As1),
|
||||||
|
G3 =.. [F | As1],
|
||||||
|
G0 = M:G3
|
||||||
|
; !,
|
||||||
|
G1 =.. [F | As],
|
||||||
|
atom(F),
|
||||||
|
F \== [],
|
||||||
|
load_context(M),
|
||||||
|
append(As, Args, As1),
|
||||||
|
G2 =.. [F | As1],
|
||||||
|
G0 = M:G2
|
||||||
|
).
|
||||||
|
|
||||||
|
call_clause(G, Args, _, G0) :-
|
||||||
|
G =.. [F | As],
|
||||||
|
atom(F),
|
||||||
|
F \== [],
|
||||||
|
load_context(M),
|
||||||
|
append(As, Args, As1),
|
||||||
|
G2 =.. [F | As1],
|
||||||
|
expand_goal(M:G2, M, G0).
|
||||||
|
|
||||||
|
|
||||||
|
call(A,B) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/2)
|
||||||
|
; ( call_clause(A,[B],2,C) ->
|
||||||
|
'$call'(C)
|
||||||
|
; type_error(callable,A,call/2)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/3)
|
||||||
|
; ( call_clause(A,[B,C],3,D) ->
|
||||||
|
'$call'(D)
|
||||||
|
; type_error(callable,A,call/3)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/4)
|
||||||
|
; ( call_clause(A,[B,C,D],4,E) ->
|
||||||
|
'$call'(E)
|
||||||
|
; type_error(callable,A,call/4)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/5)
|
||||||
|
; ( call_clause(A,[B,C,D,E],5,F) ->
|
||||||
|
'$call'(F)
|
||||||
|
; type_error(callable,A,call/5)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/6)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F],6,G) ->
|
||||||
|
'$call'(G)
|
||||||
|
; type_error(callable,A,call/6)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/7)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G],7,H) ->
|
||||||
|
'$call'(H)
|
||||||
|
; type_error(callable,A,call/7)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/8)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H],8,I) ->
|
||||||
|
'$call'(I)
|
||||||
|
; type_error(callable,A,call/8)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/9)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I],9,J) ->
|
||||||
|
'$call'(J)
|
||||||
|
; type_error(callable,A,call/9)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/10)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J],10,K) ->
|
||||||
|
'$call'(K)
|
||||||
|
; type_error(callable,A,call/10)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/11)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K],11,L) ->
|
||||||
|
'$call'(L)
|
||||||
|
; type_error(callable,A,call/11)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/12)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L],12,M) ->
|
||||||
|
'$call'(M)
|
||||||
|
; type_error(callable,A,call/12)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/13)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M],13,N) ->
|
||||||
|
'$call'(N)
|
||||||
|
; type_error(callable,A,call/13)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/14)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N],14,O) ->
|
||||||
|
'$call'(O)
|
||||||
|
; type_error(callable,A,call/14)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/15)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O],15,P) ->
|
||||||
|
'$call'(P)
|
||||||
|
; type_error(callable,A,call/15)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/16)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P],16,Q) ->
|
||||||
|
'$call'(Q)
|
||||||
|
; type_error(callable,A,call/16)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/17)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q],17,R) ->
|
||||||
|
'$call'(R)
|
||||||
|
; type_error(callable,A,call/17)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/18)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R],18,S) ->
|
||||||
|
'$call'(S)
|
||||||
|
; type_error(callable,A,call/18)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/19)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S],19,T) ->
|
||||||
|
'$call'(T)
|
||||||
|
; type_error(callable,A,call/19)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/20)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T],20,U) ->
|
||||||
|
'$call'(U)
|
||||||
|
; type_error(callable,A,call/20)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/21)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U],21,V) ->
|
||||||
|
'$call'(V)
|
||||||
|
; type_error(callable,A,call/21)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/22)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V],22,W) ->
|
||||||
|
'$call'(W)
|
||||||
|
; type_error(callable,A,call/22)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/23)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W],23,X) ->
|
||||||
|
'$call'(X)
|
||||||
|
; type_error(callable,A,call/23)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/24)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X],24,Y) ->
|
||||||
|
'$call'(Y)
|
||||||
|
; type_error(callable,A,call/24)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/25)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y],25,Z) ->
|
||||||
|
'$call'(Z)
|
||||||
|
; type_error(callable,A,call/25)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/26)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z],26,A1) ->
|
||||||
|
'$call'(A1)
|
||||||
|
; type_error(callable,A,call/26)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/27)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1],27,B1) ->
|
||||||
|
'$call'(B1)
|
||||||
|
; type_error(callable,A,call/27)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/28)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1],28,C1) ->
|
||||||
|
'$call'(C1)
|
||||||
|
; type_error(callable,A,call/28)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/29)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1],29,D1) ->
|
||||||
|
'$call'(D1)
|
||||||
|
; type_error(callable,A,call/29)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/30)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1],30,E1) ->
|
||||||
|
'$call'(E1)
|
||||||
|
; type_error(callable,A,call/30)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/31)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1],31,F1) ->
|
||||||
|
'$call'(F1)
|
||||||
|
; type_error(callable,A,call/31)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/32)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1],32,G1) ->
|
||||||
|
'$call'(G1)
|
||||||
|
; type_error(callable,A,call/32)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/33)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1],33,H1) ->
|
||||||
|
'$call'(H1)
|
||||||
|
; type_error(callable,A,call/33)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/34)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1],34,I1) ->
|
||||||
|
'$call'(I1)
|
||||||
|
; type_error(callable,A,call/34)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/35)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1],35,J1) ->
|
||||||
|
'$call'(J1)
|
||||||
|
; type_error(callable,A,call/35)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/36)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1],36,K1) ->
|
||||||
|
'$call'(K1)
|
||||||
|
; type_error(callable,A,call/36)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/37)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1],37,L1) ->
|
||||||
|
'$call'(L1)
|
||||||
|
; type_error(callable,A,call/37)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/38)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1],38,M1) ->
|
||||||
|
'$call'(M1)
|
||||||
|
; type_error(callable,A,call/38)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/39)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1],39,N1) ->
|
||||||
|
'$call'(N1)
|
||||||
|
; type_error(callable,A,call/39)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/40)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1],40,O1) ->
|
||||||
|
'$call'(O1)
|
||||||
|
; type_error(callable,A,call/40)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/41)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1],41,P1) ->
|
||||||
|
'$call'(P1)
|
||||||
|
; type_error(callable,A,call/41)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/42)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1],42,Q1) ->
|
||||||
|
'$call'(Q1)
|
||||||
|
; type_error(callable,A,call/42)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/43)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1],43,R1) ->
|
||||||
|
'$call'(R1)
|
||||||
|
; type_error(callable,A,call/43)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/44)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1],44,S1) ->
|
||||||
|
'$call'(S1)
|
||||||
|
; type_error(callable,A,call/44)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/45)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1],45,T1) ->
|
||||||
|
'$call'(T1)
|
||||||
|
; type_error(callable,A,call/45)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/46)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1],46,U1) ->
|
||||||
|
'$call'(U1)
|
||||||
|
; type_error(callable,A,call/46)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/47)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1],47,V1) ->
|
||||||
|
'$call'(V1)
|
||||||
|
; type_error(callable,A,call/47)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/48)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1],48,W1) ->
|
||||||
|
'$call'(W1)
|
||||||
|
; type_error(callable,A,call/48)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/49)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1],49,X1) ->
|
||||||
|
'$call'(X1)
|
||||||
|
; type_error(callable,A,call/49)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/50)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1],50,Y1) ->
|
||||||
|
'$call'(Y1)
|
||||||
|
; type_error(callable,A,call/50)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/51)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1],51,Z1) ->
|
||||||
|
'$call'(Z1)
|
||||||
|
; type_error(callable,A,call/51)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/52)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1],52,A2) ->
|
||||||
|
'$call'(A2)
|
||||||
|
; type_error(callable,A,call/52)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/53)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2],53,B2) ->
|
||||||
|
'$call'(B2)
|
||||||
|
; type_error(callable,A,call/53)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/54)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2],54,C2) ->
|
||||||
|
'$call'(C2)
|
||||||
|
; type_error(callable,A,call/54)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/55)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2],55,D2) ->
|
||||||
|
'$call'(D2)
|
||||||
|
; type_error(callable,A,call/55)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/56)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2],56,E2) ->
|
||||||
|
'$call'(E2)
|
||||||
|
; type_error(callable,A,call/56)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/57)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2],57,F2) ->
|
||||||
|
'$call'(F2)
|
||||||
|
; type_error(callable,A,call/57)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/58)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2],58,G2) ->
|
||||||
|
'$call'(G2)
|
||||||
|
; type_error(callable,A,call/58)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/59)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2],59,H2) ->
|
||||||
|
'$call'(H2)
|
||||||
|
; type_error(callable,A,call/59)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/60)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2],60,I2) ->
|
||||||
|
'$call'(I2)
|
||||||
|
; type_error(callable,A,call/60)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/61)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2],61,J2) ->
|
||||||
|
'$call'(J2)
|
||||||
|
; type_error(callable,A,call/61)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/62)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2],62,K2) ->
|
||||||
|
'$call'(K2)
|
||||||
|
; type_error(callable,A,call/62)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/63)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2],63,L2) ->
|
||||||
|
'$call'(L2)
|
||||||
|
; type_error(callable,A,call/63)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/64)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2],64,M2) ->
|
||||||
|
'$call'(M2)
|
||||||
|
; type_error(callable,A,call/64)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/65)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2],65,N2) ->
|
||||||
|
'$call'(N2)
|
||||||
|
; type_error(callable,A,call/65)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|
||||||
|
call(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2) :-
|
||||||
|
( var(A) ->
|
||||||
|
instantiation_error(call/65)
|
||||||
|
; ( call_clause(A,[B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2],65,N2) ->
|
||||||
|
'$call'(N2)
|
||||||
|
; type_error(callable,A,call/65)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -51,7 +51,6 @@ call_goals_0([Module-GoalList | GoalLists]) :-
|
|||||||
call_goals_0([]).
|
call_goals_0([]).
|
||||||
|
|
||||||
call_goals_1([Goal | Goals], Module) :-
|
call_goals_1([Goal | Goals], Module) :-
|
||||||
expand_goal(Goal, Module, Goal1), % TODO: remove this when goal expansions are added to call/N.
|
call(Module:Goal),
|
||||||
call(Module:Goal1),
|
|
||||||
call_goals_1(Goals, Module).
|
call_goals_1(Goals, Module).
|
||||||
call_goals_1([], _).
|
call_goals_1([], _).
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use crate::heap_iter::*;
|
use crate::heap_iter::*;
|
||||||
use crate::machine::*;
|
use crate::machine::*;
|
||||||
|
use prolog_parser::temp_v;
|
||||||
|
|
||||||
use crate::indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
@@ -20,8 +21,7 @@ pub(super) struct AttrVarInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AttrVarInitializer {
|
impl AttrVarInitializer {
|
||||||
pub(super)
|
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
||||||
fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
|
|
||||||
AttrVarInitializer {
|
AttrVarInitializer {
|
||||||
attribute_goals: vec![],
|
attribute_goals: vec![],
|
||||||
attr_var_queue: vec![],
|
attr_var_queue: vec![],
|
||||||
@@ -34,24 +34,21 @@ impl AttrVarInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn reset(&mut self) {
|
||||||
fn reset(&mut self) {
|
self.attribute_goals.clear();
|
||||||
self.attribute_goals.clear();
|
|
||||||
self.attr_var_queue.clear();
|
self.attr_var_queue.clear();
|
||||||
self.bindings.clear();
|
self.bindings.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
||||||
fn backtrack(&mut self, queue_b: usize, bindings_b: usize) {
|
|
||||||
self.attr_var_queue.truncate(queue_b);
|
self.attr_var_queue.truncate(queue_b);
|
||||||
self.bindings.truncate(bindings_b);
|
self.bindings.truncate(bindings_b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(super)
|
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
||||||
fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
|
|
||||||
if self.attr_var_init.bindings.is_empty() {
|
if self.attr_var_init.bindings.is_empty() {
|
||||||
self.attr_var_init.instigating_p = self.p.local();
|
self.attr_var_init.instigating_p = self.p.local();
|
||||||
|
|
||||||
@@ -79,7 +76,7 @@ impl MachineState {
|
|||||||
let iter = self
|
let iter = self
|
||||||
.attr_var_init
|
.attr_var_init
|
||||||
.bindings
|
.bindings
|
||||||
.drain(0 ..)
|
.drain(0..)
|
||||||
.map(|(_, addr)| HeapCellValue::Addr(addr));
|
.map(|(_, addr)| HeapCellValue::Addr(addr));
|
||||||
|
|
||||||
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
|
let value_list_addr = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
@@ -97,8 +94,7 @@ impl MachineState {
|
|||||||
self[temp_v!(2)] = value_list_addr;
|
self[temp_v!(2)] = value_list_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
||||||
fn gather_attr_vars_created_since(&self, b: usize) -> IntoIter<Addr> {
|
|
||||||
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
let mut attr_vars: Vec<_> = self.attr_var_init.attr_var_queue[b..]
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
.filter_map(|h| match self.store(self.deref(Addr::HeapCell(*h))) {
|
||||||
@@ -107,29 +103,25 @@ impl MachineState {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
attr_vars.sort_unstable_by(|a1, a2| {
|
attr_vars
|
||||||
self.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
|
.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2).unwrap_or(Ordering::Less));
|
||||||
});
|
|
||||||
|
|
||||||
self.term_dedup(&mut attr_vars);
|
self.term_dedup(&mut attr_vars);
|
||||||
attr_vars.into_iter()
|
attr_vars.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
|
||||||
fn verify_attr_interrupt(&mut self, p: usize) {
|
|
||||||
self.allocate(self.num_of_args + 2);
|
self.allocate(self.num_of_args + 2);
|
||||||
|
|
||||||
let e = self.e;
|
let e = self.e;
|
||||||
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
|
self.stack.index_and_frame_mut(e).prelude.interrupt_cp = self.attr_var_init.cp;
|
||||||
|
|
||||||
for i in 1 .. self.num_of_args + 1 {
|
for i in 1..self.num_of_args + 1 {
|
||||||
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
self.stack.index_and_frame_mut(e)[i] = self[RegType::Temp(i)];
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] =
|
self.stack.index_and_frame_mut(e)[self.num_of_args + 1] = Addr::CutPoint(self.b0);
|
||||||
Addr::CutPoint(self.b0);
|
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] = Addr::Usize(self.num_of_args);
|
||||||
self.stack.index_and_frame_mut(e)[self.num_of_args + 2] =
|
|
||||||
Addr::Usize(self.num_of_args);
|
|
||||||
|
|
||||||
self.verify_attributes();
|
self.verify_attributes();
|
||||||
|
|
||||||
@@ -138,9 +130,8 @@ impl MachineState {
|
|||||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
||||||
fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
|
let mut seen_set = IndexSet::new();
|
||||||
let mut seen_set = IndexSet::new();
|
|
||||||
let mut seen_vars = vec![];
|
let mut seen_vars = vec![];
|
||||||
|
|
||||||
let mut iter = self.acyclic_pre_order_iter(addr);
|
let mut iter = self.acyclic_pre_order_iter(addr);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::prolog_parser_rebis::ast::Constant;
|
use prolog_parser::ast::Constant;
|
||||||
|
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::partial_string::*;
|
use crate::machine::partial_string::*;
|
||||||
@@ -42,16 +42,17 @@ impl<T: RawBlockTraits> Drop for HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate)
|
pub(crate) struct HeapIntoIter<T: RawBlockTraits> {
|
||||||
struct HeapIntoIter<T: RawBlockTraits> {
|
|
||||||
offset: usize,
|
offset: usize,
|
||||||
buf: RawBlock<T>,
|
buf: RawBlock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RawBlockTraits> Drop for HeapIntoIter<T> {
|
impl<T: RawBlockTraits> Drop for HeapIntoIter<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut heap =
|
let mut heap = HeapTemplate {
|
||||||
HeapTemplate { buf: self.buf.take(), _marker: PhantomData };
|
buf: self.buf.take(),
|
||||||
|
_marker: PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
heap.truncate(self.offset / mem::size_of::<HeapCellValue>());
|
heap.truncate(self.offset / mem::size_of::<HeapCellValue>());
|
||||||
heap.buf.deallocate();
|
heap.buf.deallocate();
|
||||||
@@ -66,9 +67,7 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
|
|||||||
self.offset += mem::size_of::<HeapCellValue>();
|
self.offset += mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
if ptr < self.buf.top as usize {
|
if ptr < self.buf.top as usize {
|
||||||
unsafe {
|
unsafe { Some(ptr::read(ptr as *const HeapCellValue)) }
|
||||||
Some(ptr::read(ptr as *const HeapCellValue))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -76,15 +75,13 @@ impl<T: RawBlockTraits> Iterator for HeapIntoIter<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate)
|
pub(crate) struct HeapIter<'a, T: RawBlockTraits> {
|
||||||
struct HeapIter<'a, T: RawBlockTraits> {
|
|
||||||
offset: usize,
|
offset: usize,
|
||||||
buf: &'a RawBlock<T>,
|
buf: &'a RawBlock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawBlockTraits> HeapIter<'a, T> {
|
impl<'a, T: RawBlockTraits> HeapIter<'a, T> {
|
||||||
pub(crate)
|
pub(crate) fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
|
||||||
fn new(buf: &'a RawBlock<T>, offset: usize) -> Self {
|
|
||||||
HeapIter { buf, offset }
|
HeapIter { buf, offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,9 +94,7 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
|
|||||||
self.offset += mem::size_of::<HeapCellValue>();
|
self.offset += mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
if ptr < self.buf.top as usize {
|
if ptr < self.buf.top as usize {
|
||||||
unsafe {
|
unsafe { Some(&*(ptr as *const _)) }
|
||||||
Some(&*(ptr as *const _))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -107,23 +102,20 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIter<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate)
|
pub(crate) fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
|
||||||
fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: usize) {
|
|
||||||
for (index, term) in heap.enumerate() {
|
for (index, term) in heap.enumerate() {
|
||||||
println!("{} : {}", h + index, term);
|
println!("{} : {}", h + index, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate)
|
pub(crate) struct HeapIterMut<'a, T: RawBlockTraits> {
|
||||||
struct HeapIterMut<'a, T: RawBlockTraits> {
|
|
||||||
offset: usize,
|
offset: usize,
|
||||||
buf: &'a mut RawBlock<T>,
|
buf: &'a mut RawBlock<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> {
|
impl<'a, T: RawBlockTraits> HeapIterMut<'a, T> {
|
||||||
pub(crate)
|
pub(crate) fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
|
||||||
fn new(buf: &'a mut RawBlock<T>, offset: usize) -> Self {
|
|
||||||
HeapIterMut { buf, offset }
|
HeapIterMut { buf, offset }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,9 +128,7 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
|
|||||||
self.offset += mem::size_of::<HeapCellValue>();
|
self.offset += mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
if ptr < self.buf.top as usize {
|
if ptr < self.buf.top as usize {
|
||||||
unsafe {
|
unsafe { Some(&mut *(ptr as *mut _)) }
|
||||||
Some(&mut *(ptr as *mut _))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -147,51 +137,33 @@ impl<'a, T: RawBlockTraits> Iterator for HeapIterMut<'a, T> {
|
|||||||
|
|
||||||
impl<T: RawBlockTraits> HeapTemplate<T> {
|
impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn new() -> Self {
|
||||||
fn new() -> Self {
|
HeapTemplate {
|
||||||
HeapTemplate { buf: RawBlock::new(), _marker: PhantomData }
|
buf: RawBlock::new(),
|
||||||
}
|
_marker: PhantomData,
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate)
|
|
||||||
fn clone(&self, h: usize) -> HeapCellValue {
|
|
||||||
match &self[h] {
|
|
||||||
&HeapCellValue::Addr(addr) => {
|
|
||||||
HeapCellValue::Addr(addr)
|
|
||||||
}
|
|
||||||
&HeapCellValue::Atom(ref name, ref op) => {
|
|
||||||
HeapCellValue::Atom(name.clone(), op.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::DBRef(ref db_ref) => {
|
|
||||||
HeapCellValue::DBRef(db_ref.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::Integer(ref n) => {
|
|
||||||
HeapCellValue::Integer(n.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::LoadStatePayload(_) => {
|
|
||||||
HeapCellValue::Addr(Addr::LoadStatePayload(h))
|
|
||||||
}
|
|
||||||
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
|
||||||
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::PartialString(..) => {
|
|
||||||
HeapCellValue::Addr(Addr::PStrLocation(h, 0))
|
|
||||||
}
|
|
||||||
&HeapCellValue::Rational(ref r) => {
|
|
||||||
HeapCellValue::Rational(r.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::Stream(_) => {
|
|
||||||
HeapCellValue::Addr(Addr::Stream(h))
|
|
||||||
}
|
|
||||||
&HeapCellValue::TcpListener(_) => {
|
|
||||||
HeapCellValue::Addr(Addr::TcpListener(h))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn clone(&self, h: usize) -> HeapCellValue {
|
||||||
fn put_complete_string(&mut self, s: &str) -> Addr {
|
match &self[h] {
|
||||||
|
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr),
|
||||||
|
&HeapCellValue::Atom(ref name, ref op) => HeapCellValue::Atom(name.clone(), op.clone()),
|
||||||
|
&HeapCellValue::DBRef(ref db_ref) => HeapCellValue::DBRef(db_ref.clone()),
|
||||||
|
&HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
|
||||||
|
&HeapCellValue::LoadStatePayload(_) => HeapCellValue::Addr(Addr::LoadStatePayload(h)),
|
||||||
|
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
||||||
|
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
||||||
|
}
|
||||||
|
&HeapCellValue::PartialString(..) => HeapCellValue::Addr(Addr::PStrLocation(h, 0)),
|
||||||
|
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
|
||||||
|
&HeapCellValue::Stream(_) => HeapCellValue::Addr(Addr::Stream(h)),
|
||||||
|
&HeapCellValue::TcpListener(_) => HeapCellValue::Addr(Addr::TcpListener(h)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn put_complete_string(&mut self, s: &str) -> Addr {
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
return Addr::EmptyList;
|
return Addr::EmptyList;
|
||||||
}
|
}
|
||||||
@@ -214,30 +186,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn put_constant(&mut self, c: Constant) -> Addr {
|
||||||
fn put_constant(&mut self, c: Constant) -> Addr {
|
|
||||||
match c {
|
match c {
|
||||||
Constant::Atom(name, op) => {
|
Constant::Atom(name, op) => Addr::Con(self.push(HeapCellValue::Atom(name, op))),
|
||||||
Addr::Con(self.push(HeapCellValue::Atom(name, op)))
|
Constant::Char(c) => Addr::Char(c),
|
||||||
}
|
Constant::EmptyList => Addr::EmptyList,
|
||||||
Constant::Char(c) => {
|
Constant::Fixnum(n) => Addr::Fixnum(n),
|
||||||
Addr::Char(c)
|
Constant::Integer(n) => Addr::Con(self.push(HeapCellValue::Integer(n))),
|
||||||
}
|
Constant::Rational(r) => Addr::Con(self.push(HeapCellValue::Rational(r))),
|
||||||
Constant::EmptyList => {
|
Constant::Float(f) => Addr::Float(f),
|
||||||
Addr::EmptyList
|
|
||||||
}
|
|
||||||
Constant::Fixnum(n) => {
|
|
||||||
Addr::Fixnum(n)
|
|
||||||
}
|
|
||||||
Constant::Integer(n) => {
|
|
||||||
Addr::Con(self.push(HeapCellValue::Integer(n)))
|
|
||||||
}
|
|
||||||
Constant::Rational(r) => {
|
|
||||||
Addr::Con(self.push(HeapCellValue::Rational(r)))
|
|
||||||
}
|
|
||||||
Constant::Float(f) => {
|
|
||||||
Addr::Float(f)
|
|
||||||
}
|
|
||||||
Constant::String(s) => {
|
Constant::String(s) => {
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
Addr::EmptyList
|
Addr::EmptyList
|
||||||
@@ -245,15 +202,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
self.put_complete_string(&s)
|
self.put_complete_string(&s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constant::Usize(n) => {
|
Constant::Usize(n) => Addr::Usize(n),
|
||||||
Addr::Usize(n)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn pop(&mut self) {
|
||||||
fn pop(&mut self) {
|
|
||||||
let h = self.h();
|
let h = self.h();
|
||||||
|
|
||||||
if h > 0 {
|
if h > 0 {
|
||||||
@@ -262,8 +216,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn push(&mut self, val: HeapCellValue) -> usize {
|
||||||
fn push(&mut self, val: HeapCellValue) -> usize {
|
|
||||||
let h = self.h();
|
let h = self.h();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -276,8 +229,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn atom_at(&self, h: usize) -> bool {
|
||||||
fn atom_at(&self, h: usize) -> bool {
|
|
||||||
if let HeapCellValue::Atom(..) = &self[h] {
|
if let HeapCellValue::Atom(..) = &self[h] {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@@ -286,24 +238,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
|
||||||
fn to_unifiable(&mut self, non_heap_value: HeapCellValue) -> Addr {
|
|
||||||
match non_heap_value {
|
match non_heap_value {
|
||||||
HeapCellValue::Addr(addr) => {
|
HeapCellValue::Addr(addr) => addr,
|
||||||
addr
|
val @ HeapCellValue::Atom(..)
|
||||||
}
|
| val @ HeapCellValue::Integer(_)
|
||||||
val @ HeapCellValue::Atom(..) |
|
| val @ HeapCellValue::DBRef(_)
|
||||||
val @ HeapCellValue::Integer(_) |
|
| val @ HeapCellValue::Rational(_) => Addr::Con(self.push(val)),
|
||||||
val @ HeapCellValue::DBRef(_) |
|
val @ HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(self.push(val)),
|
||||||
val @ HeapCellValue::Rational(_) => {
|
val @ HeapCellValue::NamedStr(..) => Addr::Str(self.push(val)),
|
||||||
Addr::Con(self.push(val))
|
|
||||||
}
|
|
||||||
val @ HeapCellValue::LoadStatePayload(_) => {
|
|
||||||
Addr::LoadStatePayload(self.push(val))
|
|
||||||
}
|
|
||||||
val @ HeapCellValue::NamedStr(..) => {
|
|
||||||
Addr::Str(self.push(val))
|
|
||||||
}
|
|
||||||
HeapCellValue::PartialString(pstr, has_tail) => {
|
HeapCellValue::PartialString(pstr, has_tail) => {
|
||||||
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||||
|
|
||||||
@@ -313,20 +256,14 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
|
|
||||||
Addr::Con(h)
|
Addr::Con(h)
|
||||||
}
|
}
|
||||||
val @ HeapCellValue::Stream(..) => {
|
val @ HeapCellValue::Stream(..) => Addr::Stream(self.push(val)),
|
||||||
Addr::Stream(self.push(val))
|
val @ HeapCellValue::TcpListener(..) => Addr::TcpListener(self.push(val)),
|
||||||
}
|
|
||||||
val @ HeapCellValue::TcpListener(..) => {
|
|
||||||
Addr::TcpListener(self.push(val))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn allocate_pstr(&mut self, src: &str) -> Addr {
|
||||||
fn allocate_pstr(&mut self, src: &str) -> Addr {
|
self.write_pstr(src).unwrap_or_else(|| Addr::EmptyList)
|
||||||
self.write_pstr(src)
|
|
||||||
.unwrap_or_else(|| Addr::EmptyList)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -347,23 +284,20 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
|
|
||||||
let h = self.h();
|
let h = self.h();
|
||||||
|
|
||||||
let (pstr, rest_src) =
|
let (pstr, rest_src) = match PartialString::new(src) {
|
||||||
match PartialString::new(src) {
|
Some(tuple) => tuple,
|
||||||
Some(tuple) => {
|
None => {
|
||||||
tuple
|
if src.len() > '\u{0}'.len_utf8() {
|
||||||
|
src = &src['\u{0}'.len_utf8()..];
|
||||||
|
continue;
|
||||||
|
} else if orig_h == h {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
self[h - 1] = HeapCellValue::Addr(Addr::HeapCell(h - 1));
|
||||||
|
return Some(Addr::PStrLocation(orig_h, 0));
|
||||||
}
|
}
|
||||||
None => {
|
}
|
||||||
if src.len() > '\u{0}'.len_utf8() {
|
};
|
||||||
src = &src['\u{0}'.len_utf8() ..];
|
|
||||||
continue;
|
|
||||||
} else if orig_h == h {
|
|
||||||
return None;
|
|
||||||
} else {
|
|
||||||
self[h - 1] = HeapCellValue::Addr(Addr::HeapCell(h - 1));
|
|
||||||
return Some(Addr::PStrLocation(orig_h, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.push(HeapCellValue::PartialString(pstr, true));
|
self.push(HeapCellValue::PartialString(pstr, true));
|
||||||
|
|
||||||
@@ -378,8 +312,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn truncate(&mut self, h: usize) {
|
||||||
fn truncate(&mut self, h: usize) {
|
|
||||||
let new_top = h * mem::size_of::<HeapCellValue>() + self.buf.base as usize;
|
let new_top = h * mem::size_of::<HeapCellValue>() + self.buf.base as usize;
|
||||||
let mut h = new_top;
|
let mut h = new_top;
|
||||||
|
|
||||||
@@ -395,30 +328,27 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn h(&self) -> usize {
|
||||||
fn h(&self) -> usize {
|
|
||||||
(self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>()
|
(self.buf.top as usize - self.buf.base as usize) / mem::size_of::<HeapCellValue>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn append(&mut self, vals: Vec<HeapCellValue>) {
|
||||||
fn append(&mut self, vals: Vec<HeapCellValue>) {
|
|
||||||
for val in vals {
|
for val in vals {
|
||||||
self.push(val);
|
self.push(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn clear(&mut self) {
|
||||||
fn clear(&mut self) {
|
|
||||||
if !self.buf.base.is_null() {
|
if !self.buf.base.is_null() {
|
||||||
self.truncate(0);
|
self.truncate(0);
|
||||||
self.buf.top = self.buf.base;
|
self.buf.top = self.buf.base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn to_list<Iter, SrcT>(&mut self, values: Iter) -> usize
|
||||||
fn to_list<Iter, SrcT>(&mut self, values: Iter) -> usize
|
where
|
||||||
where Iter: Iterator<Item = SrcT>,
|
Iter: Iterator<Item = SrcT>,
|
||||||
SrcT: Into<HeapCellValue>
|
SrcT: Into<HeapCellValue>,
|
||||||
{
|
{
|
||||||
let head_addr = self.h();
|
let head_addr = self.h();
|
||||||
let mut h = head_addr;
|
let mut h = head_addr;
|
||||||
@@ -436,35 +366,33 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create an iterator starting from the passed offset. */
|
/* Create an iterator starting from the passed offset. */
|
||||||
pub(crate)
|
pub(crate) fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
|
||||||
fn iter_from<'a>(&'a self, offset: usize) -> HeapIter<'a, T> {
|
|
||||||
HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
HeapIter::new(&self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
|
||||||
fn iter_mut_from<'a>(&'a mut self, offset: usize) -> HeapIterMut<'a, T> {
|
|
||||||
HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
HeapIterMut::new(&mut self.buf, offset * mem::size_of::<HeapCellValue>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn into_iter(mut self) -> HeapIntoIter<T> {
|
||||||
fn into_iter(mut self) -> HeapIntoIter<T> {
|
HeapIntoIter {
|
||||||
HeapIntoIter { buf: self.buf.take(), offset: 0 }
|
buf: self.buf.take(),
|
||||||
|
offset: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
|
||||||
fn extend<Iter: Iterator<Item = HeapCellValue>>(&mut self, iter: Iter) {
|
|
||||||
for hcv in iter {
|
for hcv in iter {
|
||||||
self.push(hcv);
|
self.push(hcv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
|
||||||
fn to_local_code_ptr(&self, addr: &Addr) -> Option<LocalCodePtr> {
|
|
||||||
let extract_integer = |s: usize| -> Option<usize> {
|
let extract_integer = |s: usize| -> Option<usize> {
|
||||||
match &self[s] {
|
match &self[s] {
|
||||||
&HeapCellValue::Addr(Addr::Fixnum(n)) => usize::try_from(n).ok(),
|
&HeapCellValue::Addr(Addr::Fixnum(n)) => usize::try_from(n).ok(),
|
||||||
&HeapCellValue::Integer(ref n) => n.to_usize(),
|
&HeapCellValue::Integer(ref n) => n.to_usize(),
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -473,9 +401,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
match &self[*s] {
|
match &self[*s] {
|
||||||
HeapCellValue::NamedStr(arity, ref name, _) => {
|
HeapCellValue::NamedStr(arity, ref name, _) => {
|
||||||
match (name.as_str(), *arity) {
|
match (name.as_str(), *arity) {
|
||||||
("dir_entry", 1) => {
|
("dir_entry", 1) => extract_integer(s + 1).map(LocalCodePtr::DirEntry),
|
||||||
extract_integer(s+1).map(LocalCodePtr::DirEntry)
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
("top_level", 2) => {
|
("top_level", 2) => {
|
||||||
if let Some(chunk_num) = extract_integer(s+1) {
|
if let Some(chunk_num) = extract_integer(s+1) {
|
||||||
@@ -487,15 +413,13 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!()
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,9 +429,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => {
|
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => {
|
||||||
RefOrOwned::Borrowed(&self[h])
|
RefOrOwned::Borrowed(&self[h])
|
||||||
}
|
}
|
||||||
addr => {
|
addr => RefOrOwned::Owned(HeapCellValue::Addr(*addr)),
|
||||||
RefOrOwned::Owned(HeapCellValue::Addr(*addr))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::machine::*;
|
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::term_stream::*;
|
use crate::machine::*;
|
||||||
|
use prolog_parser::clause_name;
|
||||||
|
|
||||||
|
use crate::machine::term_stream::*;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use crate::ref_thread_local::RefThreadLocal;
|
use ref_thread_local::RefThreadLocal;
|
||||||
|
|
||||||
type ModuleOpExports = Vec<(OpDecl, Option<(usize, Specifier)>)>;
|
type ModuleOpExports = Vec<(OpDecl, Option<(usize, Specifier)>)>;
|
||||||
|
|
||||||
@@ -19,37 +20,35 @@ pub(super) struct LoadState<'a> {
|
|||||||
pub(super) wam: &'a mut Machine,
|
pub(super) wam: &'a mut Machine,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn set_code_index(
|
||||||
fn set_code_index(
|
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
code_index: &CodeIndex,
|
code_index: &CodeIndex,
|
||||||
code_ptr: IndexPtr,
|
code_ptr: IndexPtr,
|
||||||
) {
|
) {
|
||||||
let record =
|
let record = match compilation_target {
|
||||||
match compilation_target {
|
CompilationTarget::User => {
|
||||||
CompilationTarget::User => {
|
if IndexPtr::Undefined == code_index.get() {
|
||||||
if IndexPtr::Undefined == code_index.get() {
|
code_index.set(code_ptr);
|
||||||
code_index.set(code_ptr);
|
RetractionRecord::AddedUserPredicate(key)
|
||||||
RetractionRecord::AddedUserPredicate(key)
|
} else {
|
||||||
} else {
|
// TODO: emit warning about overwriting previous record
|
||||||
// TODO: emit warning about overwriting previous record
|
let replaced = code_index.replace(code_ptr);
|
||||||
let replaced = code_index.replace(code_ptr);
|
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
||||||
RetractionRecord::ReplacedUserPredicate(key, replaced)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref module_name) => {
|
}
|
||||||
if IndexPtr::Undefined == code_index.get() {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
code_index.set(code_ptr);
|
if IndexPtr::Undefined == code_index.get() {
|
||||||
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
|
code_index.set(code_ptr);
|
||||||
} else {
|
RetractionRecord::AddedModulePredicate(module_name.clone(), key)
|
||||||
// TODO: emit warning about overwriting previous record
|
} else {
|
||||||
let replaced = code_index.replace(code_ptr);
|
// TODO: emit warning about overwriting previous record
|
||||||
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
|
let replaced = code_index.replace(code_ptr);
|
||||||
}
|
RetractionRecord::ReplacedModulePredicate(module_name.clone(), key, replaced)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
retraction_info.push_record(record);
|
retraction_info.push_record(record);
|
||||||
}
|
}
|
||||||
@@ -71,17 +70,16 @@ fn add_op_decl_as_module_export(
|
|||||||
|
|
||||||
match op_decl.insert_into_op_dir(wam_op_dir) {
|
match op_decl.insert_into_op_dir(wam_op_dir) {
|
||||||
Some((prec, spec)) => {
|
Some((prec, spec)) => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec)
|
op_decl.clone(),
|
||||||
);
|
prec,
|
||||||
|
spec,
|
||||||
|
));
|
||||||
|
|
||||||
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
|
module_op_exports.push((op_decl.clone(), Some((prec, spec))));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
retraction_info.push_record(
|
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||||
RetractionRecord::AddedUserOp(op_decl.clone())
|
|
||||||
);
|
|
||||||
|
|
||||||
module_op_exports.push((op_decl.clone(), None));
|
module_op_exports.push((op_decl.clone(), None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,56 +87,52 @@ fn add_op_decl_as_module_export(
|
|||||||
add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
|
add_op_decl(retraction_info, compilation_target, module_op_dir, op_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn add_op_decl(
|
||||||
fn add_op_decl(
|
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
op_decl: &OpDecl,
|
op_decl: &OpDecl,
|
||||||
) {
|
) {
|
||||||
match op_decl.insert_into_op_dir(op_dir) {
|
match op_decl.insert_into_op_dir(op_dir) {
|
||||||
Some((prec, spec)) => {
|
Some((prec, spec)) => match &compilation_target {
|
||||||
match &compilation_target {
|
CompilationTarget::User => {
|
||||||
CompilationTarget::User => {
|
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
|
||||||
retraction_info.push_record(
|
op_decl.clone(),
|
||||||
RetractionRecord::ReplacedUserOp(op_decl.clone(), prec, spec),
|
prec,
|
||||||
);
|
spec,
|
||||||
}
|
));
|
||||||
CompilationTarget::Module(ref module_name) => {
|
|
||||||
retraction_info.push_record(
|
|
||||||
RetractionRecord::ReplacedModuleOp(
|
|
||||||
module_name.clone(), op_decl.clone(), prec, spec,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
CompilationTarget::Module(ref module_name) => {
|
||||||
None => {
|
retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
|
||||||
match &compilation_target {
|
module_name.clone(),
|
||||||
CompilationTarget::User => {
|
op_decl.clone(),
|
||||||
retraction_info.push_record(
|
prec,
|
||||||
RetractionRecord::AddedUserOp(op_decl.clone()),
|
spec,
|
||||||
);
|
));
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
|
||||||
retraction_info.push_record(
|
|
||||||
RetractionRecord::AddedModuleOp(module_name.clone(), op_decl.clone()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
None => match &compilation_target {
|
||||||
|
CompilationTarget::User => {
|
||||||
|
retraction_info.push_record(RetractionRecord::AddedUserOp(op_decl.clone()));
|
||||||
|
}
|
||||||
|
CompilationTarget::Module(ref module_name) => {
|
||||||
|
retraction_info.push_record(RetractionRecord::AddedModuleOp(
|
||||||
|
module_name.clone(),
|
||||||
|
op_decl.clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn import_module_exports(
|
||||||
fn import_module_exports(
|
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
imported_module: &Module,
|
imported_module: &Module,
|
||||||
code_dir: &mut CodeDir,
|
code_dir: &mut CodeDir,
|
||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
meta_predicates: &mut MetaPredicateDir,
|
meta_predicates: &mut MetaPredicateDir,
|
||||||
) {
|
) -> Result<(), SessionError> {
|
||||||
for export in imported_module.module_decl.exports.iter() {
|
for export in imported_module.module_decl.exports.iter() {
|
||||||
match export {
|
match export {
|
||||||
ModuleExport::PredicateKey((ref name, arity)) => {
|
ModuleExport::PredicateKey((ref name, arity)) => {
|
||||||
@@ -162,19 +156,19 @@ fn import_module_exports(
|
|||||||
src_code_index.get(),
|
src_code_index.get(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
|
imported_module.module_decl.name.clone(),
|
||||||
|
(name.clone(), *arity),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleExport::OpDecl(ref op_decl) => {
|
ModuleExport::OpDecl(ref op_decl) => {
|
||||||
add_op_decl(
|
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||||
retraction_info,
|
|
||||||
compilation_target,
|
|
||||||
op_dir,
|
|
||||||
op_decl,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_module_exports_into_module(
|
fn import_module_exports_into_module(
|
||||||
@@ -185,8 +179,8 @@ fn import_module_exports_into_module(
|
|||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
meta_predicates: &mut MetaPredicateDir,
|
meta_predicates: &mut MetaPredicateDir,
|
||||||
wam_op_dir: &mut OpDir,
|
wam_op_dir: &mut OpDir,
|
||||||
module_op_exports: &mut ModuleOpExports
|
module_op_exports: &mut ModuleOpExports,
|
||||||
) {
|
) -> Result<(), SessionError> {
|
||||||
for export in imported_module.module_decl.exports.iter() {
|
for export in imported_module.module_decl.exports.iter() {
|
||||||
match export {
|
match export {
|
||||||
ModuleExport::PredicateKey((ref name, arity)) => {
|
ModuleExport::PredicateKey((ref name, arity)) => {
|
||||||
@@ -210,7 +204,10 @@ fn import_module_exports_into_module(
|
|||||||
src_code_index.get(),
|
src_code_index.get(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
|
imported_module.module_decl.name.clone(),
|
||||||
|
(name.clone(), *arity),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleExport::OpDecl(ref op_decl) => {
|
ModuleExport::OpDecl(ref op_decl) => {
|
||||||
@@ -225,8 +222,9 @@ fn import_module_exports_into_module(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn import_qualified_module_exports(
|
fn import_qualified_module_exports(
|
||||||
retraction_info: &mut RetractionInfo,
|
retraction_info: &mut RetractionInfo,
|
||||||
@@ -235,7 +233,7 @@ fn import_qualified_module_exports(
|
|||||||
exports: &IndexSet<ModuleExport>,
|
exports: &IndexSet<ModuleExport>,
|
||||||
code_dir: &mut CodeDir,
|
code_dir: &mut CodeDir,
|
||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
) {
|
) -> Result<(), SessionError> {
|
||||||
for export in imported_module.module_decl.exports.iter() {
|
for export in imported_module.module_decl.exports.iter() {
|
||||||
if !exports.contains(export) {
|
if !exports.contains(export) {
|
||||||
continue;
|
continue;
|
||||||
@@ -259,19 +257,19 @@ fn import_qualified_module_exports(
|
|||||||
src_code_index.get(),
|
src_code_index.get(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
|
imported_module.module_decl.name.clone(),
|
||||||
|
(name.clone(), *arity),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleExport::OpDecl(ref op_decl) => {
|
ModuleExport::OpDecl(ref op_decl) => {
|
||||||
add_op_decl(
|
add_op_decl(retraction_info, compilation_target, op_dir, op_decl);
|
||||||
retraction_info,
|
|
||||||
compilation_target,
|
|
||||||
op_dir,
|
|
||||||
op_decl,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_qualified_module_exports_into_module(
|
fn import_qualified_module_exports_into_module(
|
||||||
@@ -283,7 +281,7 @@ fn import_qualified_module_exports_into_module(
|
|||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
wam_op_dir: &mut OpDir,
|
wam_op_dir: &mut OpDir,
|
||||||
module_op_exports: &mut ModuleOpExports,
|
module_op_exports: &mut ModuleOpExports,
|
||||||
) {
|
) -> Result<(), SessionError> {
|
||||||
for export in imported_module.module_decl.exports.iter() {
|
for export in imported_module.module_decl.exports.iter() {
|
||||||
if !exports.contains(export) {
|
if !exports.contains(export) {
|
||||||
continue;
|
continue;
|
||||||
@@ -307,7 +305,10 @@ fn import_qualified_module_exports_into_module(
|
|||||||
src_code_index.get(),
|
src_code_index.get(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
|
imported_module.module_decl.name.clone(),
|
||||||
|
(name.clone(), *arity),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModuleExport::OpDecl(ref op_decl) => {
|
ModuleExport::OpDecl(ref op_decl) => {
|
||||||
@@ -322,33 +323,34 @@ fn import_qualified_module_exports_into_module(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LoadState<'a> {
|
impl<'a> LoadState<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn increment_clause_assert_margin(&mut self, incr: usize) {
|
||||||
fn increment_clause_assert_margin(&mut self, incr: usize) {
|
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {}
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::IncreasedClauseAssertMargin(
|
.push_record(RetractionRecord::IncreasedClauseAssertMargin(
|
||||||
module_name.clone(),
|
module_name.clone(),
|
||||||
incr,
|
incr,
|
||||||
),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
self.wam.indices.modules.get_mut(module_name)
|
self.wam
|
||||||
|
.indices
|
||||||
|
.modules
|
||||||
|
.get_mut(module_name)
|
||||||
.map(|module| module.clause_assert_margin += incr);
|
.map(|module| module.clause_assert_margin += incr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn remove_module_op_exports(&mut self) {
|
||||||
fn remove_module_op_exports(&mut self) {
|
for (mut op_decl, record) in self.module_op_exports.drain(0..) {
|
||||||
for (mut op_decl, record) in self.module_op_exports.drain(0 ..) {
|
|
||||||
op_decl.remove(&mut self.wam.indices.op_dir);
|
op_decl.remove(&mut self.wam.indices.op_dir);
|
||||||
|
|
||||||
if let Some((prec, spec)) = record {
|
if let Some((prec, spec)) = record {
|
||||||
@@ -365,26 +367,28 @@ impl<'a> LoadState<'a> {
|
|||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> CodeIndex {
|
) -> CodeIndex {
|
||||||
match self.wam.indices.modules.get_mut(&module_name) {
|
match self.wam.indices.modules.get_mut(&module_name) {
|
||||||
Some(ref mut module) => {
|
Some(ref mut module) => module
|
||||||
module.code_dir
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone()
|
.clone(),
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
let mut module = Module::new(
|
let mut module = Module::new(
|
||||||
ModuleDecl { name: module_name.clone(), exports: vec![] },
|
ModuleDecl {
|
||||||
|
name: module_name.clone(),
|
||||||
|
exports: vec![],
|
||||||
|
},
|
||||||
ListingSource::DynamicallyGenerated,
|
ListingSource::DynamicallyGenerated,
|
||||||
);
|
);
|
||||||
|
|
||||||
let code_index = module.code_dir
|
let code_index = module
|
||||||
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedModule(module_name.clone()),
|
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
code_index
|
code_index
|
||||||
@@ -392,29 +396,31 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
||||||
fn get_or_insert_code_index(&mut self, key: PredicateKey) -> CodeIndex {
|
|
||||||
match self.compilation_target.clone() {
|
match self.compilation_target.clone() {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => self
|
||||||
self.wam.indices.code_dir
|
.wam
|
||||||
.entry(key)
|
.indices
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.code_dir
|
||||||
.clone()
|
.entry(key)
|
||||||
}
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
|
.clone(),
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => {
|
||||||
self.get_or_insert_local_code_index(module_name, key)
|
self.get_or_insert_local_code_index(module_name, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_or_insert_qualified_code_index(
|
||||||
fn get_or_insert_qualified_code_index(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> CodeIndex {
|
) -> CodeIndex {
|
||||||
if module_name.as_str() == "user" {
|
if module_name.as_str() == "user" {
|
||||||
return self.wam.indices.code_dir
|
return self
|
||||||
|
.wam
|
||||||
|
.indices
|
||||||
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined))
|
||||||
.clone();
|
.clone();
|
||||||
@@ -424,15 +430,20 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn add_extensible_predicate(
|
||||||
fn add_extensible_predicate(&mut self, key: PredicateKey, skeleton: PredicateSkeleton) {
|
&mut self,
|
||||||
|
key: PredicateKey,
|
||||||
|
skeleton: PredicateSkeleton,
|
||||||
|
) {
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
self.wam.indices.extensible_predicates.insert(key.clone(), skeleton);
|
self.wam
|
||||||
|
.indices
|
||||||
|
.extensible_predicates
|
||||||
|
.insert(key.clone(), skeleton);
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedUserExtensiblePredicate(key),
|
.push_record(RetractionRecord::AddedUserExtensiblePredicate(key));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
|
if let Some(module) = self.wam.indices.modules.get_mut(module_name) {
|
||||||
@@ -448,8 +459,7 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
||||||
fn add_op_decl(&mut self, op_decl: &OpDecl) {
|
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
add_op_decl(
|
add_op_decl(
|
||||||
@@ -479,8 +489,7 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_clause_type(
|
||||||
fn get_clause_type(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
@@ -495,14 +504,11 @@ impl<'a> LoadState<'a> {
|
|||||||
let idx = self.get_or_insert_code_index((name.clone(), arity));
|
let idx = self.get_or_insert_code_index((name.clone(), arity));
|
||||||
ClauseType::Op(name, fixity, idx)
|
ClauseType::Op(name, fixity, idx)
|
||||||
}
|
}
|
||||||
ct => {
|
ct => ct,
|
||||||
ct
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_qualified_clause_type(
|
||||||
fn get_qualified_clause_type(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
@@ -522,27 +528,11 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
ClauseType::Op(name, fixity, idx)
|
ClauseType::Op(name, fixity, idx)
|
||||||
}
|
}
|
||||||
ct => {
|
ct => ct,
|
||||||
ct
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
pub(super) fn add_meta_predicate_record(
|
||||||
pub(super)
|
|
||||||
fn module_name(&self) -> ClauseName {
|
|
||||||
match self.compilation_target {
|
|
||||||
CompilationTarget::User => {
|
|
||||||
clause_name!("user")
|
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
|
||||||
module_name.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super)
|
|
||||||
fn add_meta_predicate_record(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
@@ -553,20 +543,26 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
match module_name.as_str() {
|
match module_name.as_str() {
|
||||||
"user" => {
|
"user" => {
|
||||||
match self.wam.indices.meta_predicates.insert(key.clone(), meta_specs) {
|
match self
|
||||||
|
.wam
|
||||||
|
.indices
|
||||||
|
.meta_predicates
|
||||||
|
.insert(key.clone(), meta_specs)
|
||||||
|
{
|
||||||
Some(old_meta_specs) => {
|
Some(old_meta_specs) => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::ReplacedMetaPredicate(
|
.push_record(RetractionRecord::ReplacedMetaPredicate(
|
||||||
module_name.clone(), key.0, old_meta_specs,
|
module_name.clone(),
|
||||||
),
|
key.0,
|
||||||
);
|
old_meta_specs,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedMetaPredicate(
|
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||||
module_name.clone(), key,
|
module_name.clone(),
|
||||||
)
|
key,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,15 +573,15 @@ impl<'a> LoadState<'a> {
|
|||||||
Some(old_meta_specs) => {
|
Some(old_meta_specs) => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info.push_record(
|
||||||
RetractionRecord::ReplacedMetaPredicate(
|
RetractionRecord::ReplacedMetaPredicate(
|
||||||
module_name.clone(), key.0, old_meta_specs,
|
module_name.clone(),
|
||||||
|
key.0,
|
||||||
|
old_meta_specs,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info.push_record(
|
||||||
RetractionRecord::AddedMetaPredicate(
|
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
|
||||||
module_name.clone(), key,
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -601,15 +597,14 @@ impl<'a> LoadState<'a> {
|
|||||||
|
|
||||||
module.meta_predicates.insert(key.clone(), meta_specs);
|
module.meta_predicates.insert(key.clone(), meta_specs);
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedMetaPredicate(
|
.push_record(RetractionRecord::AddedMetaPredicate(
|
||||||
module_name.clone(), key,
|
module_name.clone(),
|
||||||
)
|
key,
|
||||||
);
|
));
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedModule(module_name.clone()),
|
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
}
|
}
|
||||||
@@ -632,36 +627,33 @@ impl<'a> LoadState<'a> {
|
|||||||
code_dir,
|
code_dir,
|
||||||
op_dir,
|
op_dir,
|
||||||
meta_predicates,
|
meta_predicates,
|
||||||
);
|
).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
||||||
fn add_module(&mut self, module_decl: ModuleDecl, listing_src: ListingSource) {
|
|
||||||
let module_name = module_decl.name.clone();
|
let module_name = module_decl.name.clone();
|
||||||
|
|
||||||
let mut module =
|
let mut module = match self.wam.indices.modules.remove(&module_name) {
|
||||||
match self.wam.indices.modules.remove(&module_name) {
|
Some(mut module) => {
|
||||||
Some(mut module) => {
|
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
||||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl);
|
|
||||||
|
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::ReplacedModule(
|
.push_record(RetractionRecord::ReplacedModule(
|
||||||
old_module_decl, listing_src.clone(),
|
old_module_decl,
|
||||||
),
|
listing_src.clone(),
|
||||||
);
|
));
|
||||||
|
|
||||||
module.listing_src = listing_src;
|
module.listing_src = listing_src;
|
||||||
module
|
module
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.retraction_info.push_record(
|
self.retraction_info
|
||||||
RetractionRecord::AddedModule(module_name.clone()),
|
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
Module::new(module_decl, listing_src)
|
Module::new(module_decl, listing_src)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.import_builtins_in_module(
|
self.import_builtins_in_module(
|
||||||
&mut module.code_dir,
|
&mut module.code_dir,
|
||||||
@@ -689,8 +681,7 @@ impl<'a> LoadState<'a> {
|
|||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
||||||
fn import_module(&mut self, module_name: ClauseName) -> Result<(), SessionError> {
|
|
||||||
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
|
if let Some(module) = self.wam.indices.modules.remove(&module_name) {
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
@@ -701,7 +692,7 @@ impl<'a> LoadState<'a> {
|
|||||||
&mut self.wam.indices.code_dir,
|
&mut self.wam.indices.code_dir,
|
||||||
&mut self.wam.indices.op_dir,
|
&mut self.wam.indices.op_dir,
|
||||||
&mut self.wam.indices.meta_predicates,
|
&mut self.wam.indices.meta_predicates,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref defining_module_name) => {
|
CompilationTarget::Module(ref defining_module_name) => {
|
||||||
match self.wam.indices.modules.get_mut(defining_module_name) {
|
match self.wam.indices.modules.get_mut(defining_module_name) {
|
||||||
@@ -715,7 +706,7 @@ impl<'a> LoadState<'a> {
|
|||||||
&mut target_module.meta_predicates,
|
&mut target_module.meta_predicates,
|
||||||
&mut self.wam.indices.op_dir,
|
&mut self.wam.indices.op_dir,
|
||||||
&mut self.module_op_exports,
|
&mut self.module_op_exports,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// we find ourselves here because we're trying to import
|
// we find ourselves here because we're trying to import
|
||||||
@@ -730,7 +721,9 @@ impl<'a> LoadState<'a> {
|
|||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||||
|
module_name,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -749,7 +742,7 @@ impl<'a> LoadState<'a> {
|
|||||||
&exports,
|
&exports,
|
||||||
&mut self.wam.indices.code_dir,
|
&mut self.wam.indices.code_dir,
|
||||||
&mut self.wam.indices.op_dir,
|
&mut self.wam.indices.op_dir,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(ref defining_module_name) => {
|
CompilationTarget::Module(ref defining_module_name) => {
|
||||||
match self.wam.indices.modules.get_mut(defining_module_name) {
|
match self.wam.indices.modules.get_mut(defining_module_name) {
|
||||||
@@ -763,7 +756,7 @@ impl<'a> LoadState<'a> {
|
|||||||
&mut target_module.op_dir,
|
&mut target_module.op_dir,
|
||||||
&mut self.wam.indices.op_dir,
|
&mut self.wam.indices.op_dir,
|
||||||
&mut self.module_op_exports,
|
&mut self.module_op_exports,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// we find ourselves here because we're trying to import
|
// we find ourselves here because we're trying to import
|
||||||
@@ -778,41 +771,41 @@ impl<'a> LoadState<'a> {
|
|||||||
self.wam.indices.modules.insert(module_name, module);
|
self.wam.indices.modules.insert(module_name, module);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
|
Err(SessionError::ExistenceError(ExistenceError::Module(
|
||||||
|
module_name,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
||||||
fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
|
let (stream, listing_src) = match module_src {
|
||||||
let (stream, listing_src) =
|
ModuleSource::File(filename) => {
|
||||||
match module_src {
|
let mut path_buf = PathBuf::from(filename.as_str());
|
||||||
ModuleSource::File(filename) => {
|
path_buf.set_extension("pl");
|
||||||
let mut path_buf = PathBuf::from(filename.as_str());
|
let file = File::open(&path_buf)?;
|
||||||
path_buf.set_extension("pl");
|
|
||||||
let file = File::open(&path_buf)?;
|
|
||||||
|
|
||||||
(Stream::from_file_as_input(filename.clone(), file),
|
(
|
||||||
ListingSource::File(filename, path_buf))
|
Stream::from_file_as_input(filename.clone(), file),
|
||||||
}
|
ListingSource::File(filename, path_buf),
|
||||||
ModuleSource::Library(library) => {
|
)
|
||||||
match LIBRARIES.borrow().get(library.as_str()) {
|
}
|
||||||
Some(code) => {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
||||||
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
Some(code) => {
|
||||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
if let Some(ref module) = self.wam.indices.modules.get(&library) {
|
||||||
(Stream::from(*code), ListingSource::User)
|
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||||
} else {
|
(Stream::from(*code), ListingSource::User)
|
||||||
return self.import_module(library);
|
} else {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(Stream::from(*code), ListingSource::User)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return self.import_module(library);
|
return self.import_module(library);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
(Stream::from(*code), ListingSource::User)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
None => {
|
||||||
|
return self.import_module(library);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let compilation_target = {
|
let compilation_target = {
|
||||||
let stream = &mut parsing_stream(stream)?;
|
let stream = &mut parsing_stream(stream)?;
|
||||||
@@ -833,43 +826,39 @@ impl<'a> LoadState<'a> {
|
|||||||
// nothing to do.
|
// nothing to do.
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => self.import_module(module_name),
|
||||||
self.import_module(module_name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn use_qualified_module(
|
||||||
fn use_qualified_module(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
module_src: ModuleSource,
|
module_src: ModuleSource,
|
||||||
exports: IndexSet<ModuleExport>,
|
exports: IndexSet<ModuleExport>,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let (stream, listing_src) =
|
let (stream, listing_src) = match module_src {
|
||||||
match module_src {
|
ModuleSource::File(filename) => {
|
||||||
ModuleSource::File(filename) => {
|
let mut path_buf = PathBuf::from(filename.as_str());
|
||||||
let mut path_buf = PathBuf::from(filename.as_str());
|
path_buf.set_extension("pl");
|
||||||
path_buf.set_extension("pl");
|
let file = File::open(&path_buf)?;
|
||||||
let file = File::open(&path_buf)?;
|
|
||||||
|
|
||||||
(Stream::from_file_as_input(filename.clone(), file),
|
(
|
||||||
ListingSource::File(filename, path_buf))
|
Stream::from_file_as_input(filename.clone(), file),
|
||||||
}
|
ListingSource::File(filename, path_buf),
|
||||||
ModuleSource::Library(library) => {
|
)
|
||||||
match LIBRARIES.borrow().get(library.as_str()) {
|
}
|
||||||
Some(code) => {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
|
||||||
if self.wam.indices.modules.contains_key(&library) {
|
Some(code) => {
|
||||||
return self.import_qualified_module(library, exports);
|
if self.wam.indices.modules.contains_key(&library) {
|
||||||
} else {
|
return self.import_qualified_module(library, exports);
|
||||||
(Stream::from(*code), ListingSource::User)
|
} else {
|
||||||
}
|
(Stream::from(*code), ListingSource::User)
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return self.import_qualified_module(library, exports);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
None => {
|
||||||
|
return self.import_qualified_module(library, exports);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let compilation_target = {
|
let compilation_target = {
|
||||||
let stream = &mut parsing_stream(stream)?;
|
let stream = &mut parsing_stream(stream)?;
|
||||||
@@ -897,12 +886,9 @@ impl<'a> LoadState<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn composite_op_dir(&self) -> CompositeOpDir {
|
||||||
fn composite_op_dir(&self) -> CompositeOpDir {
|
|
||||||
match &self.compilation_target {
|
match &self.compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => CompositeOpDir::new(&self.wam.indices.op_dir, None),
|
||||||
CompositeOpDir::new(&self.wam.indices.op_dir, None)
|
|
||||||
}
|
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
match self.wam.indices.modules.get(module_name) {
|
match self.wam.indices.modules.get(module_name) {
|
||||||
Some(ref module) => {
|
Some(ref module) => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::{clause_name, temp_v};
|
||||||
|
|
||||||
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
|
use crate::forms::{ModuleSource, Number}; //, PredicateKey};
|
||||||
|
use crate::machine::PredicateKey;
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
@@ -23,74 +25,59 @@ pub(crate) struct MachineError {
|
|||||||
from: ErrorProvenance,
|
from: ErrorProvenance,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) trait TypeError {
|
||||||
trait TypeError {
|
|
||||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for Addr {
|
impl TypeError for Addr {
|
||||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), addr(self)]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), addr(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for HeapCellValue {
|
impl TypeError for HeapCellValue {
|
||||||
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, _: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), value(self)]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), value(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for MachineStub {
|
impl TypeError for MachineStub {
|
||||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), aux(h, 0)], [self]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), aux(h, 0)],
|
|
||||||
[self]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Constructed
|
from: ErrorProvenance::Constructed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeError for Number {
|
impl TypeError for Number {
|
||||||
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
|
fn type_error(self, _h: usize, valid_type: ValidType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("type_error", [atom(valid_type.as_str()), number(self)]);
|
||||||
"type_error",
|
|
||||||
[atom(valid_type.as_str()), number(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) trait PermissionError {
|
||||||
trait PermissionError {
|
|
||||||
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +91,7 @@ impl PermissionError for Addr {
|
|||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Received
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,22 +107,18 @@ impl PermissionError for MachineStub {
|
|||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
location: None,
|
location: None,
|
||||||
from: ErrorProvenance::Constructed
|
from: ErrorProvenance::Constructed,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) trait DomainError {
|
||||||
trait DomainError {
|
|
||||||
fn domain_error(self, error: DomainErrorType) -> MachineError;
|
fn domain_error(self, error: DomainErrorType) -> MachineError;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DomainError for Addr {
|
impl DomainError for Addr {
|
||||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("domain_error", [atom(error.as_str()), addr(self)]);
|
||||||
"domain_error",
|
|
||||||
[atom(error.as_str()), addr(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -147,10 +130,7 @@ impl DomainError for Addr {
|
|||||||
|
|
||||||
impl DomainError for Number {
|
impl DomainError for Number {
|
||||||
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
fn domain_error(self, error: DomainErrorType) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!("domain_error", [atom(error.as_str()), number(self)]);
|
||||||
"domain_error",
|
|
||||||
[atom(error.as_str()), number(self)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -161,8 +141,7 @@ impl DomainError for Number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineError {
|
impl MachineError {
|
||||||
pub(super)
|
pub(super) fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
||||||
fn functor_stub(name: ClauseName, arity: usize) -> MachineStub {
|
|
||||||
functor!(
|
functor!(
|
||||||
"/",
|
"/",
|
||||||
SharedOpDesc::new(400, YFX),
|
SharedOpDesc::new(400, YFX),
|
||||||
@@ -171,8 +150,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn interrupt_error() -> Self {
|
||||||
fn interrupt_error() -> Self {
|
|
||||||
let stub = functor!("$interrupt_thrown");
|
let stub = functor!("$interrupt_thrown");
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -182,8 +160,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn evaluation_error(eval_error: EvalError) -> Self {
|
||||||
fn evaluation_error(eval_error: EvalError) -> Self {
|
|
||||||
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
|
let stub = functor!("evaluation_error", [atom(eval_error.as_str())]);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -193,13 +170,11 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
||||||
fn type_error<T: TypeError>(h: usize, valid_type: ValidType, culprit: T) -> Self {
|
|
||||||
culprit.type_error(h, valid_type)
|
culprit.type_error(h, valid_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn module_resolution_error(
|
||||||
fn module_resolution_error(
|
|
||||||
h: usize,
|
h: usize,
|
||||||
mod_name: ClauseName,
|
mod_name: ClauseName,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
@@ -218,11 +193,7 @@ impl MachineError {
|
|||||||
[res_stub]
|
[res_stub]
|
||||||
);
|
);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!("evaluation_error", [aux(h, 0)], [ind_stub]);
|
||||||
"evaluation_error",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[ind_stub]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -231,14 +202,10 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn existence_error(h: usize, err: ExistenceError) -> Self {
|
||||||
fn existence_error(h: usize, err: ExistenceError) -> Self {
|
|
||||||
match err {
|
match err {
|
||||||
ExistenceError::Module(name) => {
|
ExistenceError::Module(name) => {
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("source_sink"), clause_name(name)]);
|
||||||
"existence_error",
|
|
||||||
[atom("source_sink"), clause_name(name)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -253,11 +220,7 @@ impl MachineError {
|
|||||||
[clause_name(name), integer(arity)]
|
[clause_name(name), integer(arity)]
|
||||||
);
|
);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("procedure"), aux(h, 0)], [culprit]);
|
||||||
"existence_error",
|
|
||||||
[atom("procedure"), aux(h, 0)],
|
|
||||||
[culprit]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -281,10 +244,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExistenceError::SourceSink(culprit) => {
|
ExistenceError::SourceSink(culprit) => {
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("source_sink"), addr(culprit)]);
|
||||||
"existence_error",
|
|
||||||
[atom("source_sink"), addr(culprit)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -293,10 +253,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExistenceError::Stream(culprit) => {
|
ExistenceError::Stream(culprit) => {
|
||||||
let stub = functor!(
|
let stub = functor!("existence_error", [atom("stream"), addr(culprit)]);
|
||||||
"existence_error",
|
|
||||||
[atom("stream"), addr(culprit)]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -307,25 +264,18 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn permission_error<T: PermissionError>(
|
||||||
fn permission_error<T: PermissionError>(
|
|
||||||
h: usize,
|
h: usize,
|
||||||
err: Permission,
|
err: Permission,
|
||||||
index_str: &'static str,
|
index_str: &'static str,
|
||||||
culprit: T,
|
culprit: T,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
culprit.permission_error(
|
culprit.permission_error(h, index_str, err)
|
||||||
h,
|
|
||||||
index_str,
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
fn arithmetic_error(h: usize, err: ArithmeticError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
ArithmeticError::UninstantiatedVar => {
|
ArithmeticError::UninstantiatedVar => Self::instantiation_error(),
|
||||||
Self::instantiation_error()
|
|
||||||
}
|
|
||||||
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
ArithmeticError::NonEvaluableFunctor(name, arity) => {
|
||||||
let culprit = functor!(
|
let culprit = functor!(
|
||||||
"/",
|
"/",
|
||||||
@@ -339,13 +289,11 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
||||||
fn domain_error<T: DomainError>(error: DomainErrorType, culprit: T) -> Self {
|
|
||||||
culprit.domain_error(error)
|
culprit.domain_error(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn instantiation_error() -> Self {
|
||||||
fn instantiation_error() -> Self {
|
|
||||||
let stub = functor!("instantiation_error");
|
let stub = functor!("instantiation_error");
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -355,8 +303,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn session_error(h: usize, err: SessionError) -> Self {
|
||||||
fn session_error(h: usize, err: SessionError) -> Self {
|
|
||||||
match err {
|
match err {
|
||||||
// SessionError::CannotOverwriteBuiltIn(pred_str) |
|
// SessionError::CannotOverwriteBuiltIn(pred_str) |
|
||||||
/*
|
/*
|
||||||
@@ -369,13 +316,10 @@ impl MachineError {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
SessionError::ExistenceError(err) => {
|
SessionError::ExistenceError(err) => Self::existence_error(h, err),
|
||||||
Self::existence_error(h, err)
|
|
||||||
}
|
|
||||||
// SessionError::InvalidFileName(filename) => {
|
// SessionError::InvalidFileName(filename) => {
|
||||||
// Self::existence_error(h, ExistenceError::Module(filename))
|
// Self::existence_error(h, ExistenceError::Module(filename))
|
||||||
// }
|
// }
|
||||||
/*
|
|
||||||
SessionError::ModuleDoesNotContainExport(..) => {
|
SessionError::ModuleDoesNotContainExport(..) => {
|
||||||
Self::permission_error(
|
Self::permission_error(
|
||||||
h,
|
h,
|
||||||
@@ -384,47 +328,32 @@ impl MachineError {
|
|||||||
functor!("module_does_not_contain_claimed_export"),
|
functor!("module_does_not_contain_claimed_export"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
*/
|
SessionError::ModuleCannotImportSelf(module_name) => Self::permission_error(
|
||||||
SessionError::ModuleCannotImportSelf(module_name) => {
|
h,
|
||||||
Self::permission_error(
|
Permission::Modify,
|
||||||
h,
|
"module",
|
||||||
Permission::Modify,
|
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
||||||
"module",
|
),
|
||||||
functor!("module_cannot_import_self", [clause_name(module_name)]),
|
SessionError::NamelessEntry => Self::permission_error(
|
||||||
)
|
h,
|
||||||
}
|
Permission::Create,
|
||||||
SessionError::NamelessEntry => {
|
"static_procedure",
|
||||||
Self::permission_error(
|
functor!("nameless_procedure"),
|
||||||
h,
|
),
|
||||||
Permission::Create,
|
|
||||||
"static_procedure",
|
|
||||||
functor!("nameless_procedure")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
SessionError::OpIsInfixAndPostFix(op) => {
|
SessionError::OpIsInfixAndPostFix(op) => {
|
||||||
Self::permission_error(
|
Self::permission_error(h, Permission::Create, "operator", functor!(clause_name(op)))
|
||||||
h,
|
|
||||||
Permission::Create,
|
|
||||||
"operator",
|
|
||||||
functor!(clause_name(op)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
SessionError::CompilationError(err) => {
|
|
||||||
Self::syntax_error(h, err)
|
|
||||||
}
|
|
||||||
SessionError::QueryCannotBeDefinedAsFact => {
|
|
||||||
Self::permission_error(
|
|
||||||
h,
|
|
||||||
Permission::Create,
|
|
||||||
"static_procedure",
|
|
||||||
functor!("query_cannot_be_defined_as_fact")
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
SessionError::CompilationError(err) => Self::syntax_error(h, err),
|
||||||
|
SessionError::QueryCannotBeDefinedAsFact => Self::permission_error(
|
||||||
|
h,
|
||||||
|
Permission::Create,
|
||||||
|
"static_procedure",
|
||||||
|
functor!("query_cannot_be_defined_as_fact"),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
||||||
fn syntax_error<E: Into<CompilationError>>(h: usize, err: E) -> Self {
|
|
||||||
let err = err.into();
|
let err = err.into();
|
||||||
|
|
||||||
if let CompilationError::Arithmetic(err) = err {
|
if let CompilationError::Arithmetic(err) = err {
|
||||||
@@ -434,11 +363,7 @@ impl MachineError {
|
|||||||
let location = err.line_and_col_num();
|
let location = err.line_and_col_num();
|
||||||
let stub = err.as_functor(h);
|
let stub = err.as_functor(h);
|
||||||
|
|
||||||
let stub = functor!(
|
let stub = functor!("syntax_error", [aux(h, 0)], [stub]);
|
||||||
"syntax_error",
|
|
||||||
[aux(h, 0)],
|
|
||||||
[stub]
|
|
||||||
);
|
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -447,8 +372,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn representation_error(flag: RepFlag) -> Self {
|
||||||
fn representation_error(flag: RepFlag) -> Self {
|
|
||||||
let stub = functor!("representation_error", [atom(flag.as_str())]);
|
let stub = functor!("representation_error", [atom(flag.as_str())]);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -515,63 +439,46 @@ impl From<ParserError> for CompilationError {
|
|||||||
impl CompilationError {
|
impl CompilationError {
|
||||||
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
pub fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||||
match self {
|
match self {
|
||||||
&CompilationError::ParserError(ref err) =>
|
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
|
||||||
err.line_and_col_num(),
|
_ => None,
|
||||||
_ =>
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_functor(&self, _h: usize) -> MachineStub {
|
pub fn as_functor(&self, _h: usize) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&CompilationError::Arithmetic(..) =>
|
&CompilationError::Arithmetic(..) => functor!("arithmetic_error"),
|
||||||
functor!("arithmetic_error"),
|
|
||||||
// &CompilationError::BadPendingByte =>
|
// &CompilationError::BadPendingByte =>
|
||||||
// functor!("bad_pending_byte"),
|
// functor!("bad_pending_byte"),
|
||||||
&CompilationError::CannotParseCyclicTerm =>
|
&CompilationError::CannotParseCyclicTerm => functor!("cannot_parse_cyclic_term"),
|
||||||
functor!("cannot_parse_cyclic_term"),
|
|
||||||
// &CompilationError::ExpandedTermsListNotAList =>
|
// &CompilationError::ExpandedTermsListNotAList =>
|
||||||
// functor!("expanded_terms_list_is_not_a_list"),
|
// functor!("expanded_terms_list_is_not_a_list"),
|
||||||
&CompilationError::ExpectedRel =>
|
&CompilationError::ExpectedRel => functor!("expected_relation"),
|
||||||
functor!("expected_relation"),
|
|
||||||
// &CompilationError::ExpectedTopLevelTerm =>
|
// &CompilationError::ExpectedTopLevelTerm =>
|
||||||
// functor!("expected_atom_or_cons_or_clause"),
|
// functor!("expected_atom_or_cons_or_clause"),
|
||||||
&CompilationError::InadmissibleFact =>
|
&CompilationError::InadmissibleFact => functor!("inadmissible_fact"),
|
||||||
functor!("inadmissible_fact"),
|
&CompilationError::InadmissibleQueryTerm => functor!("inadmissible_query_term"),
|
||||||
&CompilationError::InadmissibleQueryTerm =>
|
&CompilationError::InconsistentEntry => functor!("inconsistent_entry"),
|
||||||
functor!("inadmissible_query_term"),
|
|
||||||
&CompilationError::InconsistentEntry =>
|
|
||||||
functor!("inconsistent_entry"),
|
|
||||||
// &CompilationError::InvalidDoubleQuotesDecl =>
|
// &CompilationError::InvalidDoubleQuotesDecl =>
|
||||||
// functor!("invalid_double_quotes_declaration"),
|
// functor!("invalid_double_quotes_declaration"),
|
||||||
// &CompilationError::InvalidHook =>
|
// &CompilationError::InvalidHook =>
|
||||||
// functor!("invalid_hook"),
|
// functor!("invalid_hook"),
|
||||||
&CompilationError::InvalidMetaPredicateDecl =>
|
&CompilationError::InvalidMetaPredicateDecl => functor!("invalid_meta_predicate_decl"),
|
||||||
functor!("invalid_meta_predicate_decl"),
|
&CompilationError::InvalidModuleDecl => functor!("invalid_module_declaration"),
|
||||||
&CompilationError::InvalidModuleDecl =>
|
&CompilationError::InvalidModuleExport => functor!("invalid_module_export"),
|
||||||
functor!("invalid_module_declaration"),
|
&CompilationError::InvalidModuleResolution(ref module_name) => {
|
||||||
&CompilationError::InvalidModuleExport =>
|
functor!("no_such_module", [clause_name(module_name.clone())])
|
||||||
functor!("invalid_module_export"),
|
}
|
||||||
&CompilationError::InvalidModuleResolution(ref module_name) =>
|
&CompilationError::InvalidRuleHead => functor!("invalid_head_of_rule"),
|
||||||
functor!(
|
&CompilationError::InvalidUseModuleDecl => functor!("invalid_use_module_declaration"),
|
||||||
"no_such_module",
|
&CompilationError::ParserError(ref err) => functor!(err.as_str()),
|
||||||
[clause_name(module_name.clone())]
|
&CompilationError::UnreadableTerm => functor!("unreadable_term"),
|
||||||
),
|
|
||||||
&CompilationError::InvalidRuleHead =>
|
|
||||||
functor!("invalid_head_of_rule"),
|
|
||||||
&CompilationError::InvalidUseModuleDecl =>
|
|
||||||
functor!("invalid_use_module_declaration"),
|
|
||||||
&CompilationError::ParserError(ref err) =>
|
|
||||||
functor!(err.as_str()),
|
|
||||||
&CompilationError::UnreadableTerm =>
|
|
||||||
functor!("unreadable_term"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Permission {
|
pub enum Permission {
|
||||||
// Access,
|
Access,
|
||||||
Create,
|
Create,
|
||||||
InputStream,
|
InputStream,
|
||||||
Modify,
|
Modify,
|
||||||
@@ -584,7 +491,7 @@ impl Permission {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_str(self) -> &'static str {
|
pub fn as_str(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
// Permission::Access => "access",
|
Permission::Access => "access",
|
||||||
Permission::Create => "create",
|
Permission::Create => "create",
|
||||||
Permission::InputStream => "input",
|
Permission::InputStream => "input",
|
||||||
Permission::Modify => "modify",
|
Permission::Modify => "modify",
|
||||||
@@ -715,16 +622,15 @@ impl EvalError {
|
|||||||
pub(super) enum CycleSearchResult {
|
pub(super) enum CycleSearchResult {
|
||||||
EmptyList,
|
EmptyList,
|
||||||
NotList,
|
NotList,
|
||||||
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
|
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
|
||||||
ProperList(usize), // the list length.
|
ProperList(usize), // the list length.
|
||||||
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
|
PStrLocation(usize, usize, usize), // the list length (up to max), the heap offset, byte offset into the string.
|
||||||
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
// see 8.4.3 of Draft Technical Corrigendum 2.
|
// see 8.4.3 of Draft Technical Corrigendum 2.
|
||||||
pub(super)
|
pub(super) fn check_sort_errors(&self) -> CallResult {
|
||||||
fn check_sort_errors(&self) -> CallResult {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("sort"), 2);
|
let stub = MachineError::functor_stub(clause_name!("sort"), 2);
|
||||||
let list = self.store(self.deref(self[temp_v!(1)].clone()));
|
let list = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
@@ -734,7 +640,9 @@ impl MachineState {
|
|||||||
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
return Err(self.error_form(MachineError::instantiation_error(), stub))
|
||||||
}
|
}
|
||||||
CycleSearchResult::NotList => {
|
CycleSearchResult::NotList => {
|
||||||
return Err(self.error_form(MachineError::type_error(0, ValidType::List, list), stub))
|
return Err(
|
||||||
|
self.error_form(MachineError::type_error(0, ValidType::List, list), stub)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
@@ -766,7 +674,8 @@ impl MachineState {
|
|||||||
new_l = l;
|
new_l = l;
|
||||||
}
|
}
|
||||||
HeapCellValue::NamedStr(2, ref name, Some(_))
|
HeapCellValue::NamedStr(2, ref name, Some(_))
|
||||||
if name.as_str() == "-" => {
|
if name.as_str() == "-" =>
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
HeapCellValue::Addr(Addr::HeapCell(_)) => {
|
HeapCellValue::Addr(Addr::HeapCell(_)) => {
|
||||||
@@ -793,11 +702,10 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// see 8.4.4 of Draft Technical Corrigendum 2.
|
// see 8.4.4 of Draft Technical Corrigendum 2.
|
||||||
pub(super)
|
pub(super) fn check_keysort_errors(&self) -> CallResult {
|
||||||
fn check_keysort_errors(&self) -> CallResult {
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
|
let stub = MachineError::functor_stub(clause_name!("keysort"), 2);
|
||||||
|
|
||||||
let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
|
let pairs = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
let sorted = self.store(self.deref(self[temp_v!(2)].clone()));
|
||||||
|
|
||||||
match self.detect_cycles(pairs.clone()) {
|
match self.detect_cycles(pairs.clone()) {
|
||||||
@@ -814,8 +722,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn type_error<T: TypeError>(
|
||||||
fn type_error<T: TypeError>(
|
|
||||||
&self,
|
&self,
|
||||||
valid_type: ValidType,
|
valid_type: ValidType,
|
||||||
culprit: T,
|
culprit: T,
|
||||||
@@ -823,33 +730,25 @@ impl MachineState {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
) -> MachineStub {
|
) -> MachineStub {
|
||||||
let stub = MachineError::functor_stub(caller, arity);
|
let stub = MachineError::functor_stub(caller, arity);
|
||||||
let err = MachineError::type_error(
|
let err = MachineError::type_error(self.heap.h(), valid_type, culprit);
|
||||||
self.heap.h(),
|
|
||||||
valid_type,
|
|
||||||
culprit,
|
|
||||||
);
|
|
||||||
|
|
||||||
return self.error_form(err, stub);
|
return self.error_form(err, stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn representation_error(
|
||||||
fn representation_error(
|
|
||||||
&self,
|
&self,
|
||||||
rep_flag: RepFlag,
|
rep_flag: RepFlag,
|
||||||
caller: ClauseName,
|
caller: ClauseName,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
) -> MachineStub {
|
) -> MachineStub {
|
||||||
let stub = MachineError::functor_stub(caller, arity);
|
let stub = MachineError::functor_stub(caller, arity);
|
||||||
let err = MachineError::representation_error(
|
let err = MachineError::representation_error(rep_flag);
|
||||||
rep_flag,
|
|
||||||
);
|
|
||||||
|
|
||||||
return self.error_form(err, stub);
|
return self.error_form(err, stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||||
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
|
||||||
let location = err.location;
|
let location = err.location;
|
||||||
let err_len = err.len();
|
let err_len = err.len();
|
||||||
|
|
||||||
@@ -874,8 +773,7 @@ impl MachineState {
|
|||||||
stub
|
stub
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn throw_exception(&mut self, err: MachineStub) {
|
||||||
fn throw_exception(&mut self, err: MachineStub) {
|
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
|
||||||
self.ball.boundary = 0;
|
self.ball.boundary = 0;
|
||||||
@@ -906,7 +804,7 @@ pub enum SessionError {
|
|||||||
// CannotOverwriteImport(ClauseName),
|
// CannotOverwriteImport(ClauseName),
|
||||||
ExistenceError(ExistenceError),
|
ExistenceError(ExistenceError),
|
||||||
// InvalidFileName(ClauseName),
|
// InvalidFileName(ClauseName),
|
||||||
// ModuleDoesNotContainExport(ClauseName, PredicateKey),
|
ModuleDoesNotContainExport(ClauseName, PredicateKey),
|
||||||
ModuleCannotImportSelf(ClauseName),
|
ModuleCannotImportSelf(ClauseName),
|
||||||
NamelessEntry,
|
NamelessEntry,
|
||||||
OpIsInfixAndPostFix(ClauseName),
|
OpIsInfixAndPostFix(ClauseName),
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
use prolog_parser::clause_name;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::machine::CompilationTarget;
|
use crate::instructions::*;
|
||||||
use crate::machine::code_repo::CodeRepo;
|
use crate::machine::code_repo::CodeRepo;
|
||||||
use crate::machine::Ball;
|
|
||||||
use crate::machine::heap::*;
|
use crate::machine::heap::*;
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
use crate::machine::partial_string::*;
|
use crate::machine::partial_string::*;
|
||||||
use crate::machine::raw_block::RawBlockTraits;
|
use crate::machine::raw_block::RawBlockTraits;
|
||||||
use crate::machine::streams::Stream;
|
use crate::machine::streams::Stream;
|
||||||
use crate::machine::term_stream::LoadStatePayload;
|
use crate::machine::term_stream::LoadStatePayload;
|
||||||
use crate::instructions::*;
|
use crate::machine::Ball;
|
||||||
use crate::ordered_float::OrderedFloat;
|
use crate::machine::CompilationTarget;
|
||||||
use crate::rug::{Integer, Rational};
|
use crate::rug::{Integer, Rational};
|
||||||
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use crate::indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
@@ -96,20 +97,14 @@ impl Ord for Ref {
|
|||||||
fn cmp(&self, other: &Ref) -> Ordering {
|
fn cmp(&self, other: &Ref) -> Ordering {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Ref::AttrVar(h1), Ref::AttrVar(h2))
|
(Ref::AttrVar(h1), Ref::AttrVar(h2))
|
||||||
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
| (Ref::HeapCell(h1), Ref::HeapCell(h2))
|
||||||
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
| (Ref::HeapCell(h1), Ref::AttrVar(h2))
|
||||||
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => {
|
| (Ref::AttrVar(h1), Ref::HeapCell(h2)) => h1.cmp(&h2),
|
||||||
h1.cmp(&h2)
|
|
||||||
}
|
|
||||||
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
|
(Ref::StackCell(fr1, sc1), Ref::StackCell(fr2, sc2)) => {
|
||||||
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
|
fr1.cmp(&fr2).then_with(|| sc1.cmp(&sc2))
|
||||||
}
|
}
|
||||||
(Ref::StackCell(..), _) => {
|
(Ref::StackCell(..), _) => Ordering::Greater,
|
||||||
Ordering::Greater
|
(_, Ref::StackCell(..)) => Ordering::Less,
|
||||||
}
|
|
||||||
(_, Ref::StackCell(..)) => {
|
|
||||||
Ordering::Less
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,35 +119,23 @@ impl PartialEq<Ref> for Addr {
|
|||||||
impl PartialOrd<Ref> for Addr {
|
impl PartialOrd<Ref> for Addr {
|
||||||
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
fn partial_cmp(&self, r: &Ref) -> Option<Ordering> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::StackCell(fr, sc) => {
|
&Addr::StackCell(fr, sc) => match *r {
|
||||||
match *r {
|
Ref::AttrVar(_) | Ref::HeapCell(_) => Some(Ordering::Greater),
|
||||||
Ref::AttrVar(_) | Ref::HeapCell(_) => {
|
Ref::StackCell(fr1, sc1) => {
|
||||||
|
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
||||||
Some(Ordering::Greater)
|
Some(Ordering::Greater)
|
||||||
}
|
} else if fr1 == fr && sc1 == sc {
|
||||||
Ref::StackCell(fr1, sc1) => {
|
Some(Ordering::Equal)
|
||||||
if fr1 < fr || (fr1 == fr && sc1 < sc) {
|
} else {
|
||||||
Some(Ordering::Greater)
|
|
||||||
} else if fr1 == fr && sc1 == sc {
|
|
||||||
Some(Ordering::Equal)
|
|
||||||
} else {
|
|
||||||
Some(Ordering::Less)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&Addr::HeapCell(h) | &Addr::AttrVar(h) => {
|
|
||||||
match r {
|
|
||||||
Ref::StackCell(..) => {
|
|
||||||
Some(Ordering::Less)
|
Some(Ordering::Less)
|
||||||
}
|
}
|
||||||
Ref::AttrVar(h1) | Ref::HeapCell(h1) => {
|
|
||||||
h.partial_cmp(h1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
_ => {
|
&Addr::HeapCell(h) | &Addr::AttrVar(h) => match r {
|
||||||
None
|
Ref::StackCell(..) => Some(Ordering::Less),
|
||||||
}
|
Ref::AttrVar(h1) | Ref::HeapCell(h1) => h.partial_cmp(h1),
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,26 +144,21 @@ impl Addr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_heap_bound(&self) -> bool {
|
pub fn is_heap_bound(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Addr::Char(_) | Addr::EmptyList |
|
Addr::Char(_)
|
||||||
Addr::CutPoint(_) | Addr::Usize(_) | Addr::Fixnum(_) |
|
| Addr::EmptyList
|
||||||
Addr::Float(_) => {
|
| Addr::CutPoint(_)
|
||||||
false
|
| Addr::Usize(_)
|
||||||
}
|
| Addr::Fixnum(_)
|
||||||
_ => {
|
| Addr::Float(_) => false,
|
||||||
true
|
_ => true,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_ref(&self) -> bool {
|
pub fn is_ref(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => {
|
Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::AttrVar(_) => true,
|
||||||
true
|
_ => false,
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,92 +172,54 @@ impl Addr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
||||||
fn order_category(&self, heap: &Heap) -> Option<TermOrderCategory> {
|
|
||||||
match Number::try_from((*self, heap)) {
|
match Number::try_from((*self, heap)) {
|
||||||
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
|
Ok(Number::Integer(_)) | Ok(Number::Fixnum(_)) | Ok(Number::Rational(_)) => {
|
||||||
Some(TermOrderCategory::Integer)
|
Some(TermOrderCategory::Integer)
|
||||||
}
|
}
|
||||||
Ok(Number::Float(_)) => {
|
Ok(Number::Float(_)) => Some(TermOrderCategory::FloatingPoint),
|
||||||
Some(TermOrderCategory::FloatingPoint)
|
_ => match self {
|
||||||
}
|
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
||||||
_ => {
|
Some(TermOrderCategory::Variable)
|
||||||
match self {
|
|
||||||
Addr::HeapCell(_) | Addr::AttrVar(_) | Addr::StackCell(..) => {
|
|
||||||
Some(TermOrderCategory::Variable)
|
|
||||||
}
|
|
||||||
Addr::Float(_) => {
|
|
||||||
Some(TermOrderCategory::FloatingPoint)
|
|
||||||
}
|
|
||||||
&Addr::Con(h) => {
|
|
||||||
match &heap[h] {
|
|
||||||
HeapCellValue::Atom(..) => {
|
|
||||||
Some(TermOrderCategory::Atom)
|
|
||||||
}
|
|
||||||
HeapCellValue::DBRef(_) => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Addr::Char(_) | Addr::EmptyList => {
|
|
||||||
Some(TermOrderCategory::Atom)
|
|
||||||
}
|
|
||||||
Addr::Fixnum(_) | Addr::Usize(_) => {
|
|
||||||
Some(TermOrderCategory::Integer)
|
|
||||||
}
|
|
||||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
|
||||||
Some(TermOrderCategory::Compound)
|
|
||||||
}
|
|
||||||
Addr::CutPoint(_) | Addr::LoadStatePayload(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
Addr::Float(_) => Some(TermOrderCategory::FloatingPoint),
|
||||||
|
&Addr::Con(h) => match &heap[h] {
|
||||||
|
HeapCellValue::Atom(..) => Some(TermOrderCategory::Atom),
|
||||||
|
HeapCellValue::DBRef(_) => None,
|
||||||
|
_ => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Addr::Char(_) | Addr::EmptyList => Some(TermOrderCategory::Atom),
|
||||||
|
Addr::Fixnum(_) | Addr::Usize(_) => Some(TermOrderCategory::Integer),
|
||||||
|
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||||
|
Some(TermOrderCategory::Compound)
|
||||||
|
}
|
||||||
|
Addr::CutPoint(_)
|
||||||
|
| Addr::LoadStatePayload(_)
|
||||||
|
| Addr::Stream(_)
|
||||||
|
| Addr::TcpListener(_) => None,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
|
pub fn as_constant_index(&self, machine_st: &MachineState) -> Option<Constant> {
|
||||||
match self {
|
match self {
|
||||||
&Addr::Char(c) => {
|
&Addr::Char(c) => Some(Constant::Char(c)),
|
||||||
Some(Constant::Char(c))
|
&Addr::Con(h) => match &machine_st.heap[h] {
|
||||||
}
|
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
||||||
&Addr::Con(h) => {
|
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
||||||
match &machine_st.heap[h] {
|
|
||||||
&HeapCellValue::Atom(ref name, _) if name.is_char() => {
|
|
||||||
Some(Constant::Char(name.as_str().chars().next().unwrap()))
|
|
||||||
}
|
|
||||||
&HeapCellValue::Atom(ref name, _) => {
|
|
||||||
Some(Constant::Atom(name.clone(), None))
|
|
||||||
}
|
|
||||||
&HeapCellValue::Integer(ref n) => {
|
|
||||||
Some(Constant::Integer(n.clone()))
|
|
||||||
}
|
|
||||||
&HeapCellValue::Rational(ref n) => {
|
|
||||||
Some(Constant::Rational(n.clone()))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
&HeapCellValue::Atom(ref name, _) => Some(Constant::Atom(name.clone(), None)),
|
||||||
&Addr::EmptyList => {
|
&HeapCellValue::Integer(ref n) => Some(Constant::Integer(n.clone())),
|
||||||
Some(Constant::EmptyList)
|
&HeapCellValue::Rational(ref n) => Some(Constant::Rational(n.clone())),
|
||||||
}
|
_ => None,
|
||||||
&Addr::Fixnum(n) => {
|
},
|
||||||
Some(Constant::Fixnum(n))
|
&Addr::EmptyList => Some(Constant::EmptyList),
|
||||||
}
|
&Addr::Fixnum(n) => Some(Constant::Fixnum(n)),
|
||||||
&Addr::Float(f) => {
|
&Addr::Float(f) => Some(Constant::Float(f)),
|
||||||
Some(Constant::Float(f))
|
&Addr::Usize(n) => Some(Constant::Usize(n)),
|
||||||
}
|
_ => None,
|
||||||
&Addr::Usize(n) => {
|
|
||||||
Some(Constant::Usize(n))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,61 +323,37 @@ impl HeapCellValue {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_addr(&self, focus: usize) -> Addr {
|
pub fn as_addr(&self, focus: usize) -> Addr {
|
||||||
match self {
|
match self {
|
||||||
HeapCellValue::Addr(ref a) => {
|
HeapCellValue::Addr(ref a) => *a,
|
||||||
*a
|
HeapCellValue::Atom(..)
|
||||||
}
|
| HeapCellValue::DBRef(..)
|
||||||
HeapCellValue::Atom(..) | HeapCellValue::DBRef(..) | HeapCellValue::Integer(..) |
|
| HeapCellValue::Integer(..)
|
||||||
HeapCellValue::Rational(..) => {
|
| HeapCellValue::Rational(..) => Addr::Con(focus),
|
||||||
Addr::Con(focus)
|
HeapCellValue::LoadStatePayload(_) => Addr::LoadStatePayload(focus),
|
||||||
}
|
HeapCellValue::NamedStr(_, _, _) => Addr::Str(focus),
|
||||||
HeapCellValue::LoadStatePayload(_) => {
|
HeapCellValue::PartialString(..) => Addr::PStrLocation(focus, 0),
|
||||||
Addr::LoadStatePayload(focus)
|
HeapCellValue::Stream(_) => Addr::Stream(focus),
|
||||||
}
|
HeapCellValue::TcpListener(_) => Addr::TcpListener(focus),
|
||||||
HeapCellValue::NamedStr(_, _, _) => {
|
|
||||||
Addr::Str(focus)
|
|
||||||
}
|
|
||||||
HeapCellValue::PartialString(..) => {
|
|
||||||
Addr::PStrLocation(focus, 0)
|
|
||||||
}
|
|
||||||
HeapCellValue::Stream(_) => {
|
|
||||||
Addr::Stream(focus)
|
|
||||||
}
|
|
||||||
HeapCellValue::TcpListener(_) => {
|
|
||||||
Addr::TcpListener(focus)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn context_free_clone(&self) -> HeapCellValue {
|
pub fn context_free_clone(&self) -> HeapCellValue {
|
||||||
match self {
|
match self {
|
||||||
&HeapCellValue::Addr(addr) => {
|
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr),
|
||||||
HeapCellValue::Addr(addr)
|
&HeapCellValue::Atom(ref name, ref op) => HeapCellValue::Atom(name.clone(), op.clone()),
|
||||||
}
|
&HeapCellValue::DBRef(ref db_ref) => HeapCellValue::DBRef(db_ref.clone()),
|
||||||
&HeapCellValue::Atom(ref name, ref op) => {
|
&HeapCellValue::Integer(ref n) => HeapCellValue::Integer(n.clone()),
|
||||||
HeapCellValue::Atom(name.clone(), op.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::DBRef(ref db_ref) => {
|
|
||||||
HeapCellValue::DBRef(db_ref.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::Integer(ref n) => {
|
|
||||||
HeapCellValue::Integer(n.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::LoadStatePayload(_) => {
|
&HeapCellValue::LoadStatePayload(_) => {
|
||||||
HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
|
HeapCellValue::Atom(clause_name!("$live_term_stream"), None)
|
||||||
}
|
}
|
||||||
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
||||||
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
||||||
}
|
}
|
||||||
&HeapCellValue::Rational(ref r) => {
|
&HeapCellValue::Rational(ref r) => HeapCellValue::Rational(r.clone()),
|
||||||
HeapCellValue::Rational(r.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||||
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||||
}
|
}
|
||||||
&HeapCellValue::Stream(ref stream) => {
|
&HeapCellValue::Stream(ref stream) => HeapCellValue::Stream(stream.clone()),
|
||||||
HeapCellValue::Stream(stream.clone())
|
|
||||||
}
|
|
||||||
&HeapCellValue::TcpListener(_) => {
|
&HeapCellValue::TcpListener(_) => {
|
||||||
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
||||||
}
|
}
|
||||||
@@ -473,8 +389,7 @@ impl Deref for CodeIndex {
|
|||||||
|
|
||||||
impl CodeIndex {
|
impl CodeIndex {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn new(ptr: IndexPtr) -> Self {
|
||||||
fn new(ptr: IndexPtr) -> Self {
|
|
||||||
CodeIndex(Rc::new(Cell::new(ptr)))
|
CodeIndex(Rc::new(Cell::new(ptr)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,7 +397,7 @@ impl CodeIndex {
|
|||||||
pub fn is_undefined(&self) -> bool {
|
pub fn is_undefined(&self) -> bool {
|
||||||
match self.0.get() {
|
match self.0.get() {
|
||||||
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
|
IndexPtr::Undefined => true, // | &IndexPtr::DynamicUndefined => true,
|
||||||
_ => false
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +420,6 @@ pub enum REPLCodePtr {
|
|||||||
AddDynamicPredicate,
|
AddDynamicPredicate,
|
||||||
AddGoalExpansionClause,
|
AddGoalExpansionClause,
|
||||||
AddTermExpansionClause,
|
AddTermExpansionClause,
|
||||||
BuiltInProperty,
|
|
||||||
ClauseToEvacuable,
|
ClauseToEvacuable,
|
||||||
ConcludeLoad,
|
ConcludeLoad,
|
||||||
DeclareModule,
|
DeclareModule,
|
||||||
@@ -520,11 +434,15 @@ pub enum REPLCodePtr {
|
|||||||
PushLoadContext,
|
PushLoadContext,
|
||||||
PushLoadStatePayload,
|
PushLoadStatePayload,
|
||||||
UseModule,
|
UseModule,
|
||||||
|
BuiltInProperty,
|
||||||
MetaPredicateProperty,
|
MetaPredicateProperty,
|
||||||
CompilePendingPredicates,
|
MultifileProperty,
|
||||||
UserAsserta,
|
DiscontiguousProperty,
|
||||||
UserAssertz,
|
DynamicProperty,
|
||||||
UserRetract,
|
AbolishClause,
|
||||||
|
Asserta,
|
||||||
|
Assertz,
|
||||||
|
Retract,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@@ -533,7 +451,7 @@ pub enum CodePtr {
|
|||||||
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
|
CallN(usize, LocalCodePtr, bool), // arity, local, last call.
|
||||||
Local(LocalCodePtr),
|
Local(LocalCodePtr),
|
||||||
// DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
|
// DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer.
|
||||||
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
|
REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer.
|
||||||
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
|
VerifyAttrInterrupt(usize), // location of the verify attribute interrupt code in the CodeDir.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,10 +459,10 @@ impl CodePtr {
|
|||||||
pub fn local(&self) -> LocalCodePtr {
|
pub fn local(&self) -> LocalCodePtr {
|
||||||
match self {
|
match self {
|
||||||
&CodePtr::BuiltInClause(_, ref local)
|
&CodePtr::BuiltInClause(_, ref local)
|
||||||
| &CodePtr::CallN(_, ref local, _)
|
| &CodePtr::CallN(_, ref local, _)
|
||||||
| &CodePtr::Local(ref local) => local.clone(),
|
| &CodePtr::Local(ref local) => local.clone(),
|
||||||
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
&CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p),
|
||||||
&CodePtr::REPL(_, p) => p // | &CodePtr::DynamicTransaction(_, p) => p,
|
&CodePtr::REPL(_, p) => p, // | &CodePtr::DynamicTransaction(_, p) => p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,12 +481,11 @@ pub enum LocalCodePtr {
|
|||||||
DirEntry(usize), // offset
|
DirEntry(usize), // offset
|
||||||
Halt,
|
Halt,
|
||||||
IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
|
IndexingBuf(usize, usize, usize), // DirEntry offset, first internal offset, second internal offset
|
||||||
// TopLevel(usize, usize), // chunk_num, offset
|
// TopLevel(usize, usize), // chunk_num, offset
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalCodePtr {
|
impl LocalCodePtr {
|
||||||
pub(crate)
|
pub(crate) fn assign_if_local(&mut self, cp: CodePtr) {
|
||||||
fn assign_if_local(&mut self, cp: CodePtr) {
|
|
||||||
match cp {
|
match cp {
|
||||||
CodePtr::Local(local) => *self = local,
|
CodePtr::Local(local) => *self = local,
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -576,8 +493,7 @@ impl LocalCodePtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn abs_loc(&self) -> usize {
|
||||||
fn abs_loc(&self) -> usize {
|
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(ref p) => *p,
|
LocalCodePtr::DirEntry(ref p) => *p,
|
||||||
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
LocalCodePtr::IndexingBuf(ref p, ..) => *p,
|
||||||
@@ -585,35 +501,28 @@ impl LocalCodePtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
||||||
fn is_reset_cont_marker(&self, code_repo: &CodeRepo, last_call: bool) -> bool {
|
|
||||||
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
match code_repo.lookup_instr(last_call, &CodePtr::Local(*self)) {
|
||||||
Some(line) => {
|
Some(line) => match line.as_ref() {
|
||||||
match line.as_ref() {
|
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
||||||
Line::Control(ControlInstruction::CallClause(ref ct, ..)) => {
|
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
||||||
if let ClauseType::System(SystemClauseType::ResetContinuationMarker) = *ct {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
_ => {}
|
||||||
|
},
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
||||||
fn as_functor<T: RawBlockTraits>(&self, heap: &mut HeapTemplate<T>) -> Addr {
|
|
||||||
let addr = Addr::HeapCell(heap.h());
|
let addr = Addr::HeapCell(heap.h());
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(p) => {
|
LocalCodePtr::DirEntry(p) => {
|
||||||
heap.append(functor!(
|
heap.append(functor!("dir_entry", [integer(*p)]));
|
||||||
"dir_entry",
|
|
||||||
[integer(*p)]
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
LocalCodePtr::Halt => {
|
LocalCodePtr::Halt => {
|
||||||
heap.append(functor!("halt"));
|
heap.append(functor!("halt"));
|
||||||
@@ -655,7 +564,7 @@ impl PartialOrd<CodePtr> for CodePtr {
|
|||||||
impl PartialOrd<LocalCodePtr> for LocalCodePtr {
|
impl PartialOrd<LocalCodePtr> for LocalCodePtr {
|
||||||
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &LocalCodePtr) -> Option<Ordering> {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
|
(&LocalCodePtr::DirEntry(p1), &LocalCodePtr::DirEntry(ref p2)) |
|
||||||
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
|
(&LocalCodePtr::TopLevel(_, p1), &LocalCodePtr::TopLevel(_, ref p2)) => {
|
||||||
p1.partial_cmp(p2)
|
p1.partial_cmp(p2)
|
||||||
}
|
}
|
||||||
@@ -690,12 +599,9 @@ impl Add<usize> for LocalCodePtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(p) =>
|
LocalCodePtr::DirEntry(p) => LocalCodePtr::DirEntry(p + rhs),
|
||||||
LocalCodePtr::DirEntry(p + rhs),
|
LocalCodePtr::Halt => unreachable!(),
|
||||||
LocalCodePtr::Halt =>
|
LocalCodePtr::IndexingBuf(p, o, i) => LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
||||||
unreachable!(),
|
|
||||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
|
||||||
LocalCodePtr::IndexingBuf(p, o, i + rhs),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -706,12 +612,11 @@ impl Sub<usize> for LocalCodePtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn sub(self, rhs: usize) -> Self::Output {
|
fn sub(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(p) =>
|
LocalCodePtr::DirEntry(p) => p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
||||||
p.checked_sub(rhs).map(LocalCodePtr::DirEntry),
|
LocalCodePtr::Halt => unreachable!(),
|
||||||
LocalCodePtr::Halt =>
|
LocalCodePtr::IndexingBuf(p, o, i) => i
|
||||||
unreachable!(),
|
.checked_sub(rhs)
|
||||||
LocalCodePtr::IndexingBuf(p, o, i) =>
|
.map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
||||||
i.checked_sub(rhs).map(|r| LocalCodePtr::IndexingBuf(p, o, r)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -720,15 +625,12 @@ impl SubAssign<usize> for LocalCodePtr {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn sub_assign(&mut self, rhs: usize) {
|
fn sub_assign(&mut self, rhs: usize) {
|
||||||
match self {
|
match self {
|
||||||
LocalCodePtr::DirEntry(ref mut p) =>
|
LocalCodePtr::DirEntry(ref mut p) => *p -= rhs,
|
||||||
*p -= rhs,
|
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) => unreachable!(),
|
||||||
LocalCodePtr::Halt | LocalCodePtr::IndexingBuf(..) =>
|
|
||||||
unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl AddAssign<usize> for LocalCodePtr {
|
impl AddAssign<usize> for LocalCodePtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, rhs: usize) {
|
fn add_assign(&mut self, rhs: usize) {
|
||||||
@@ -746,14 +648,12 @@ impl Add<usize> for CodePtr {
|
|||||||
|
|
||||||
fn add(self, rhs: usize) -> Self::Output {
|
fn add(self, rhs: usize) -> Self::Output {
|
||||||
match self {
|
match self {
|
||||||
p @ CodePtr::REPL(..) |
|
p @ CodePtr::REPL(..) | p @ CodePtr::VerifyAttrInterrupt(_) => {
|
||||||
p @ CodePtr::VerifyAttrInterrupt(_) => { // |
|
// |
|
||||||
// p @ CodePtr::DynamicTransaction(..) => {
|
// p @ CodePtr::DynamicTransaction(..) => {
|
||||||
p
|
p
|
||||||
}
|
}
|
||||||
CodePtr::Local(local) => {
|
CodePtr::Local(local) => CodePtr::Local(local + rhs),
|
||||||
CodePtr::Local(local + rhs)
|
|
||||||
}
|
|
||||||
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
CodePtr::BuiltInClause(_, local) | CodePtr::CallN(_, local, _) => {
|
||||||
CodePtr::Local(local + rhs)
|
CodePtr::Local(local + rhs)
|
||||||
}
|
}
|
||||||
@@ -781,7 +681,6 @@ impl SubAssign<usize> for CodePtr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
||||||
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
||||||
|
|
||||||
@@ -821,29 +720,43 @@ impl Default for IndexStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IndexStore {
|
impl IndexStore {
|
||||||
pub fn get_predicate_skeleton(
|
pub fn get_predicate_skeleton_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
key: &PredicateKey,
|
key: &PredicateKey,
|
||||||
) -> Option<&mut PredicateSkeleton> {
|
) -> Option<&mut PredicateSkeleton> {
|
||||||
match (key.0.as_str(), key.1) {
|
match (key.0.as_str(), key.1) {
|
||||||
("term_expansion", 2) => {
|
("term_expansion", 2) => self.extensible_predicates.get_mut(key),
|
||||||
self.extensible_predicates.get_mut(key)
|
_ => match compilation_target {
|
||||||
}
|
CompilationTarget::User => self.extensible_predicates.get_mut(key),
|
||||||
_ => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
match compilation_target {
|
if let Some(module) = self.modules.get_mut(module_name) {
|
||||||
CompilationTarget::User => {
|
module.extensible_predicates.get_mut(key)
|
||||||
self.extensible_predicates.get_mut(key)
|
} else {
|
||||||
}
|
None
|
||||||
CompilationTarget::Module(ref module_name) => {
|
|
||||||
if let Some(module) = self.modules.get_mut(module_name) {
|
|
||||||
module.extensible_predicates.get_mut(key)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_predicate_skeleton(
|
||||||
|
&self,
|
||||||
|
compilation_target: &CompilationTarget,
|
||||||
|
key: &PredicateKey,
|
||||||
|
) -> Option<&PredicateSkeleton> {
|
||||||
|
match (key.0.as_str(), key.1) {
|
||||||
|
("term_expansion", 2) => self.extensible_predicates.get(key),
|
||||||
|
_ => match compilation_target {
|
||||||
|
CompilationTarget::User => self.extensible_predicates.get(key),
|
||||||
|
CompilationTarget::Module(ref module_name) => {
|
||||||
|
if let Some(module) = self.modules.get(module_name) {
|
||||||
|
module.extensible_predicates.get(key)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,19 +768,17 @@ impl IndexStore {
|
|||||||
match (key.0.as_str(), key.1) {
|
match (key.0.as_str(), key.1) {
|
||||||
("term_expansion", 2) => {
|
("term_expansion", 2) => {
|
||||||
self.extensible_predicates.remove(key);
|
self.extensible_predicates.remove(key);
|
||||||
},
|
}
|
||||||
_ => {
|
_ => match compilation_target {
|
||||||
match compilation_target {
|
CompilationTarget::User => {
|
||||||
CompilationTarget::User => {
|
self.extensible_predicates.remove(key);
|
||||||
self.extensible_predicates.remove(key);
|
}
|
||||||
}
|
CompilationTarget::Module(ref module_name) => {
|
||||||
CompilationTarget::Module(ref module_name) => {
|
if let Some(module) = self.modules.get_mut(module_name) {
|
||||||
if let Some(module) = self.modules.get_mut(module_name) {
|
module.extensible_predicates.remove(key);
|
||||||
module.extensible_predicates.remove(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -880,15 +791,9 @@ impl IndexStore {
|
|||||||
) -> Option<CodeIndex> {
|
) -> Option<CodeIndex> {
|
||||||
if module.as_str() == "user" {
|
if module.as_str() == "user" {
|
||||||
match ClauseType::from(name, arity, op_spec) {
|
match ClauseType::from(name, arity, op_spec) {
|
||||||
ClauseType::Named(name, arity, _) => {
|
ClauseType::Named(name, arity, _) => self.code_dir.get(&(name, arity)).cloned(),
|
||||||
self.code_dir.get(&(name, arity)).cloned()
|
ClauseType::Op(name, spec, ..) => self.code_dir.get(&(name, spec.arity())).cloned(),
|
||||||
}
|
_ => None,
|
||||||
ClauseType::Op(name, spec, ..) => {
|
|
||||||
self.code_dir.get(&(name, spec.arity())).cloned()
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.modules.get(&module).and_then(|module| {
|
self.modules.get(&module).and_then(|module| {
|
||||||
@@ -899,9 +804,7 @@ impl IndexStore {
|
|||||||
ClauseType::Op(name, spec, ..) => {
|
ClauseType::Op(name, spec, ..) => {
|
||||||
module.code_dir.get(&(name, spec.arity())).cloned()
|
module.code_dir.get(&(name, spec.arity())).cloned()
|
||||||
}
|
}
|
||||||
_ => {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -914,44 +817,32 @@ impl IndexStore {
|
|||||||
compilation_target: &CompilationTarget,
|
compilation_target: &CompilationTarget,
|
||||||
) -> Option<&Vec<MetaSpec>> {
|
) -> Option<&Vec<MetaSpec>> {
|
||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
|
||||||
self.meta_predicates.get(&(name, arity))
|
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
|
||||||
}
|
Some(ref module) => module
|
||||||
CompilationTarget::Module(ref module_name) => {
|
.meta_predicates
|
||||||
match self.modules.get(module_name) {
|
.get(&(name.clone(), arity))
|
||||||
Some(ref module) => {
|
.or_else(|| self.meta_predicates.get(&(name, arity))),
|
||||||
module.meta_predicates.get(&(name.clone(), arity))
|
None => self.meta_predicates.get(&(name, arity)),
|
||||||
.or_else(|| {
|
},
|
||||||
self.meta_predicates.get(&(name, arity))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.meta_predicates.get(&(name, arity))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool {
|
pub fn is_dynamic_predicate(&self, module_name: ClauseName, key: PredicateKey) -> bool {
|
||||||
match module_name.as_str() {
|
match module_name.as_str() {
|
||||||
"user" => {
|
"user" => self
|
||||||
self.extensible_predicates.get(&key)
|
.extensible_predicates
|
||||||
|
.get(&key)
|
||||||
|
.map(|skeleton| skeleton.is_dynamic)
|
||||||
|
.unwrap_or(false),
|
||||||
|
_ => match self.modules.get(&module_name) {
|
||||||
|
Some(ref module) => module
|
||||||
|
.extensible_predicates
|
||||||
|
.get(&key)
|
||||||
.map(|skeleton| skeleton.is_dynamic)
|
.map(|skeleton| skeleton.is_dynamic)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false),
|
||||||
}
|
None => false,
|
||||||
_ => {
|
},
|
||||||
match self.modules.get(&module_name) {
|
|
||||||
Some(ref module) => {
|
|
||||||
module.extensible_predicates.get(&key)
|
|
||||||
.map(|skeleton| skeleton.is_dynamic)
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,8 +851,7 @@ impl IndexStore {
|
|||||||
IndexStore::default()
|
IndexStore::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn get_cleaner_sites(&self) -> (usize, usize) {
|
||||||
fn get_cleaner_sites(&self) -> (usize, usize) {
|
|
||||||
let r_w_h = clause_name!("run_cleaners_with_handling");
|
let r_w_h = clause_name!("run_cleaners_with_handling");
|
||||||
let r_wo_h = clause_name!("run_cleaners_without_handling");
|
let r_wo_h = clause_name!("run_cleaners_without_handling");
|
||||||
let iso_ext = clause_name!("iso_ext");
|
let iso_ext = clause_name!("iso_ext");
|
||||||
@@ -993,10 +883,8 @@ pub enum RefOrOwned<'a, T: 'a> {
|
|||||||
impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> {
|
impl<'a, T: 'a + fmt::Debug> fmt::Debug for RefOrOwned<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&RefOrOwned::Borrowed(ref borrowed) =>
|
&RefOrOwned::Borrowed(ref borrowed) => write!(f, "Borrowed({:?})", borrowed),
|
||||||
write!(f, "Borrowed({:?})", borrowed),
|
&RefOrOwned::Owned(ref owned) => write!(f, "Owned({:?})", owned),
|
||||||
&RefOrOwned::Owned(ref owned) =>
|
|
||||||
write!(f, "Owned({:?})", owned),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1009,7 +897,9 @@ impl<'a, T> RefOrOwned<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_owned(self) -> T where T: Clone
|
pub fn to_owned(self) -> T
|
||||||
|
where
|
||||||
|
T: Clone,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
RefOrOwned::Borrowed(item) => item.clone(),
|
RefOrOwned::Borrowed(item) => item.clone(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use prolog_parser::tabled_rc::*;
|
||||||
|
use prolog_parser::{clause_name, temp_v};
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -14,9 +15,11 @@ use crate::machine::stack::*;
|
|||||||
use crate::machine::streams::*;
|
use crate::machine::streams::*;
|
||||||
use crate::rug::Integer;
|
use crate::rug::Integer;
|
||||||
|
|
||||||
use crate::downcast::Any;
|
use downcast::{
|
||||||
|
downcast, downcast_methods, downcast_methods_core, downcast_methods_std, impl_downcast, Any,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -32,33 +35,26 @@ pub struct Ball {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ball {
|
impl Ball {
|
||||||
pub(super)
|
pub(super) fn new() -> Self {
|
||||||
fn new() -> Self {
|
|
||||||
Ball {
|
Ball {
|
||||||
boundary: 0,
|
boundary: 0,
|
||||||
stub: Heap::new(),
|
stub: Heap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn reset(&mut self) {
|
||||||
fn reset(&mut self) {
|
|
||||||
self.boundary = 0;
|
self.boundary = 0;
|
||||||
self.stub.clear();
|
self.stub.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn copy_and_align(&self, h: usize) -> Heap {
|
||||||
fn copy_and_align(&self, h: usize) -> Heap {
|
|
||||||
let diff = self.boundary as i64 - h as i64;
|
let diff = self.boundary as i64 - h as i64;
|
||||||
let mut stub = Heap::new();
|
let mut stub = Heap::new();
|
||||||
|
|
||||||
for heap_value in self.stub.iter_from(0) {
|
for heap_value in self.stub.iter_from(0) {
|
||||||
stub.push(match heap_value {
|
stub.push(match heap_value {
|
||||||
&HeapCellValue::Addr(addr) => {
|
&HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
|
||||||
HeapCellValue::Addr(addr - diff)
|
heap_value => heap_value.context_free_clone(),
|
||||||
}
|
|
||||||
heap_value => {
|
|
||||||
heap_value.context_free_clone()
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +119,7 @@ pub(super) struct CopyBallTerm<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CopyBallTerm<'a> {
|
impl<'a> CopyBallTerm<'a> {
|
||||||
pub(super) fn new(
|
pub(super) fn new(stack: &'a mut Stack, heap: &'a mut Heap, stub: &'a mut Heap) -> Self {
|
||||||
stack: &'a mut Stack,
|
|
||||||
heap: &'a mut Heap,
|
|
||||||
stub: &'a mut Heap,
|
|
||||||
) -> Self {
|
|
||||||
let hb = heap.h();
|
let hb = heap.h();
|
||||||
|
|
||||||
CopyBallTerm {
|
CopyBallTerm {
|
||||||
@@ -182,12 +174,8 @@ impl<'a> CopierTarget for CopyBallTerm<'a> {
|
|||||||
let index = h - self.heap_boundary;
|
let index = h - self.heap_boundary;
|
||||||
self.stub[index].as_addr(h)
|
self.stub[index].as_addr(h)
|
||||||
}
|
}
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => self.stack.index_and_frame(fr)[sc],
|
||||||
self.stack.index_and_frame(fr)[sc]
|
addr => addr,
|
||||||
}
|
|
||||||
addr => {
|
|
||||||
addr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,9 +214,7 @@ impl Index<RegType> for MachineState {
|
|||||||
impl IndexMut<RegType> for MachineState {
|
impl IndexMut<RegType> for MachineState {
|
||||||
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
|
fn index_mut(&mut self, reg: RegType) -> &mut Self::Output {
|
||||||
match reg {
|
match reg {
|
||||||
RegType::Temp(temp) => {
|
RegType::Temp(temp) => &mut self.registers[temp],
|
||||||
&mut self.registers[temp]
|
|
||||||
}
|
|
||||||
RegType::Perm(perm) => {
|
RegType::Perm(perm) => {
|
||||||
let e = self.e;
|
let e = self.e;
|
||||||
|
|
||||||
@@ -255,15 +241,12 @@ pub(super) enum HeapPtr {
|
|||||||
|
|
||||||
impl HeapPtr {
|
impl HeapPtr {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn read(&self, heap: &Heap) -> Addr {
|
||||||
fn read(&self, heap: &Heap) -> Addr {
|
|
||||||
match self {
|
match self {
|
||||||
&HeapPtr::HeapCell(h) => {
|
&HeapPtr::HeapCell(h) => Addr::HeapCell(h),
|
||||||
Addr::HeapCell(h)
|
|
||||||
}
|
|
||||||
&HeapPtr::PStrChar(h, n) => {
|
&HeapPtr::PStrChar(h, n) => {
|
||||||
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
|
if let &HeapCellValue::PartialString(ref pstr, has_tail) = &heap[h] {
|
||||||
if let Some(c) = pstr.range_from(n ..).next() {
|
if let Some(c) = pstr.range_from(n..).next() {
|
||||||
Addr::Char(c)
|
Addr::Char(c)
|
||||||
} else if has_tail {
|
} else if has_tail {
|
||||||
Addr::HeapCell(h + 1)
|
Addr::HeapCell(h + 1)
|
||||||
@@ -274,9 +257,7 @@ impl HeapPtr {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&HeapPtr::PStrLocation(h, n) => {
|
&HeapPtr::PStrLocation(h, n) => Addr::PStrLocation(h, n),
|
||||||
Addr::PStrLocation(h, n)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,16 +294,11 @@ pub struct MachineState {
|
|||||||
pub(super) last_call: bool,
|
pub(super) last_call: bool,
|
||||||
pub(crate) heap_locs: HeapVarDict,
|
pub(crate) heap_locs: HeapVarDict,
|
||||||
pub(crate) flags: MachineFlags,
|
pub(crate) flags: MachineFlags,
|
||||||
pub(crate) at_end_of_expansion: bool
|
pub(crate) at_end_of_expansion: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(crate)
|
pub(crate) fn read_term(&mut self, mut stream: Stream, indices: &mut IndexStore) -> CallResult {
|
||||||
fn read_term(
|
|
||||||
&mut self,
|
|
||||||
mut stream: Stream,
|
|
||||||
indices: &mut IndexStore,
|
|
||||||
) -> CallResult {
|
|
||||||
self.check_stream_properties(
|
self.check_stream_properties(
|
||||||
&mut stream,
|
&mut stream,
|
||||||
StreamType::Text,
|
StreamType::Text,
|
||||||
@@ -342,11 +318,7 @@ impl MachineState {
|
|||||||
let mut orig_stream = stream.clone();
|
let mut orig_stream = stream.clone();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.read(
|
match self.read(stream.clone(), self.atom_tbl.clone(), &indices.op_dir) {
|
||||||
stream.clone(),
|
|
||||||
self.atom_tbl.clone(),
|
|
||||||
&indices.op_dir,
|
|
||||||
) {
|
|
||||||
Ok(term_write_result) => {
|
Ok(term_write_result) => {
|
||||||
let term = self[temp_v!(2)];
|
let term = self[temp_v!(2)];
|
||||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
||||||
@@ -363,7 +335,8 @@ impl MachineState {
|
|||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
|
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
|
||||||
|
|
||||||
self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
|
self.heap
|
||||||
|
.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
|
||||||
self.heap.push(HeapCellValue::Atom(var_atom, None));
|
self.heap.push(HeapCellValue::Atom(var_atom, None));
|
||||||
self.heap.push(HeapCellValue::Addr(binding));
|
self.heap.push(HeapCellValue::Addr(binding));
|
||||||
|
|
||||||
@@ -406,8 +379,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let vars_addr = self[temp_v!(4)];
|
let vars_addr = self[temp_v!(4)];
|
||||||
let vars_offset =
|
let vars_offset = Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||||
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
|
||||||
|
|
||||||
self.unify(vars_offset, vars_addr);
|
self.unify(vars_offset, vars_addr);
|
||||||
|
|
||||||
@@ -427,7 +399,7 @@ impl MachineState {
|
|||||||
self[temp_v!(2)],
|
self[temp_v!(2)],
|
||||||
&mut orig_stream,
|
&mut orig_stream,
|
||||||
clause_name!("read_term"),
|
clause_name!("read_term"),
|
||||||
3
|
3,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if orig_stream.options.eof_action == EOFAction::Reset {
|
if orig_stream.options.eof_action == EOFAction::Reset {
|
||||||
@@ -448,12 +420,10 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn write_term<'a>(
|
||||||
fn write_term<'a>(
|
|
||||||
&'a self,
|
&'a self,
|
||||||
op_dir: &'a OpDir,
|
op_dir: &'a OpDir,
|
||||||
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub>
|
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub> {
|
||||||
{
|
|
||||||
let ignore_ops = self.store(self.deref(self[temp_v!(3)]));
|
let ignore_ops = self.store(self.deref(self[temp_v!(3)]));
|
||||||
let numbervars = self.store(self.deref(self[temp_v!(4)]));
|
let numbervars = self.store(self.deref(self[temp_v!(4)]));
|
||||||
let quoted = self.store(self.deref(self[temp_v!(5)]));
|
let quoted = self.store(self.deref(self[temp_v!(5)]));
|
||||||
@@ -462,7 +432,7 @@ impl MachineState {
|
|||||||
let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
|
let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
|
||||||
|
|
||||||
if let &Addr::Con(h) = &ignore_ops {
|
if let &Addr::Con(h) = &ignore_ops {
|
||||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||||
printer.ignore_ops = name.as_str() == "true";
|
printer.ignore_ops = name.as_str() == "true";
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -470,7 +440,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let &Addr::Con(h) = &numbervars {
|
if let &Addr::Con(h) = &numbervars {
|
||||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||||
printer.numbervars = name.as_str() == "true";
|
printer.numbervars = name.as_str() == "true";
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -478,7 +448,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let &Addr::Con(h) = "ed {
|
if let &Addr::Con(h) = "ed {
|
||||||
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
|
||||||
printer.quoted = name.as_str() == "true";
|
printer.quoted = name.as_str() == "true";
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -514,9 +484,7 @@ impl MachineState {
|
|||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
match addr {
|
match addr {
|
||||||
Addr::Str(s) => match &self.heap[s] {
|
Addr::Str(s) => match &self.heap[s] {
|
||||||
&HeapCellValue::NamedStr(2, ref name, _)
|
&HeapCellValue::NamedStr(2, ref name, _) if name.as_str() == "=" => {
|
||||||
if name.as_str() == "=" =>
|
|
||||||
{
|
|
||||||
let atom = self.heap[s + 1].as_addr(s + 1);
|
let atom = self.heap[s + 1].as_addr(s + 1);
|
||||||
let var = self.heap[s + 2].as_addr(s + 2);
|
let var = self.heap[s + 2].as_addr(s + 2);
|
||||||
|
|
||||||
@@ -540,11 +508,9 @@ impl MachineState {
|
|||||||
|
|
||||||
var_names.insert(var, atom);
|
var_names.insert(var, atom);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,8 +524,7 @@ impl MachineState {
|
|||||||
Ok(Some(printer))
|
Ok(Some(printer))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
||||||
fn throw_undefined_error(&mut self, name: ClauseName, arity: usize) -> MachineStub {
|
|
||||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
let key = ExistenceError::Procedure(name, arity);
|
let key = ExistenceError::Procedure(name, arity);
|
||||||
@@ -568,13 +533,11 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
||||||
fn heap_pstr_iter<'a>(&'a self, focus: Addr) -> HeapPStrIter<'a> {
|
|
||||||
HeapPStrIter::new(self, focus)
|
HeapPStrIter::new(self, focus)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||||
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
|
||||||
let mut chars = String::new();
|
let mut chars = String::new();
|
||||||
let mut iter = addrs.iter();
|
let mut iter = addrs.iter();
|
||||||
|
|
||||||
@@ -594,55 +557,46 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let h = self.heap.h();
|
let h = self.heap.h();
|
||||||
|
|
||||||
return Err(
|
return Err(MachineError::type_error(h, ValidType::Character, addr));
|
||||||
MachineError::type_error(h, ValidType::Character, addr)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(chars)
|
Ok(chars)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
||||||
fn read_predicate_key(&self, name: Addr, arity: Addr) -> (ClauseName, usize) {
|
|
||||||
let predicate_name = atom_from!(self, self.store(self.deref(name)));
|
let predicate_name = atom_from!(self, self.store(self.deref(name)));
|
||||||
let arity = self.store(self.deref(arity));
|
let arity = self.store(self.deref(arity));
|
||||||
|
|
||||||
let arity =
|
let arity = match Number::try_from((arity, &self.heap)) {
|
||||||
match Number::try_from((arity, &self.heap)) {
|
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY => n.to_usize().unwrap(),
|
||||||
Ok(Number::Integer(n)) if &*n >= &0 && &*n <= &MAX_ARITY =>
|
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize => {
|
||||||
n.to_usize().unwrap(),
|
usize::try_from(n).unwrap()
|
||||||
Ok(Number::Fixnum(n)) if n >= 0 && n <= MAX_ARITY as isize =>
|
}
|
||||||
usize::try_from(n).unwrap(),
|
_ => unreachable!(),
|
||||||
_ =>
|
};
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
(predicate_name, arity)
|
(predicate_name, arity)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||||
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
|
||||||
self.cp.assign_if_local(self.p.clone() + 1);
|
self.cp.assign_if_local(self.p.clone() + 1);
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p = CodePtr::Local(p);
|
self.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||||
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p = CodePtr::Local(p);
|
self.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn module_lookup(
|
||||||
fn module_lookup(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &IndexStore,
|
indices: &IndexStore,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
@@ -687,10 +641,15 @@ pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
|||||||
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
||||||
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.univ_prelude
|
||||||
|
.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -706,17 +665,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st
|
||||||
|
.heap
|
||||||
|
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
.prelude
|
||||||
|
.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(
|
machine_st
|
||||||
attr_var_init_queue_b,
|
.attr_var_init
|
||||||
attr_var_init_bindings_b,
|
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||||
);
|
|
||||||
|
|
||||||
machine_st.hb = machine_st.heap.h();
|
machine_st.hb = machine_st.heap.h();
|
||||||
machine_st.p += 1;
|
machine_st.p += 1;
|
||||||
@@ -726,10 +692,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
|
|
||||||
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.univ_prelude
|
||||||
|
.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -745,14 +716,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st
|
||||||
|
.heap
|
||||||
|
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
.prelude
|
||||||
|
.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
machine_st
|
||||||
|
.attr_var_init
|
||||||
|
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||||
|
|
||||||
machine_st.hb = machine_st.heap.h();
|
machine_st.hb = machine_st.heap.h();
|
||||||
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
|
machine_st.p = CodePtr::Local(dir_entry!(machine_st.p.local().abs_loc() + offset));
|
||||||
@@ -762,10 +743,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
|
|
||||||
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.univ_prelude
|
||||||
|
.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -779,17 +765,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st
|
||||||
|
.heap
|
||||||
|
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
.prelude
|
||||||
|
.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(
|
machine_st
|
||||||
attr_var_init_queue_b,
|
.attr_var_init
|
||||||
attr_var_init_bindings_b,
|
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||||
);
|
|
||||||
|
|
||||||
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
|
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
|
||||||
machine_st.stack.truncate(b);
|
machine_st.stack.truncate(b);
|
||||||
@@ -802,10 +795,15 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
|
|
||||||
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
|
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
|
||||||
let b = machine_st.b;
|
let b = machine_st.b;
|
||||||
let n = machine_st.stack.index_or_frame(b).prelude.univ_prelude.num_cells;
|
let n = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.univ_prelude
|
||||||
|
.num_cells;
|
||||||
|
|
||||||
for i in 1 .. n + 1 {
|
for i in 1..n + 1 {
|
||||||
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i-1];
|
machine_st.registers[i] = machine_st.stack.index_or_frame(b)[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
machine_st.num_of_args = n;
|
machine_st.num_of_args = n;
|
||||||
@@ -819,17 +817,24 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st
|
||||||
|
.heap
|
||||||
|
.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b =
|
let attr_var_init_queue_b = machine_st
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
.stack
|
||||||
let attr_var_init_bindings_b =
|
.index_or_frame(b)
|
||||||
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
.prelude
|
||||||
|
.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b = machine_st
|
||||||
|
.stack
|
||||||
|
.index_or_frame(b)
|
||||||
|
.prelude
|
||||||
|
.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(
|
machine_st
|
||||||
attr_var_init_queue_b,
|
.attr_var_init
|
||||||
attr_var_init_bindings_b,
|
.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||||
);
|
|
||||||
|
|
||||||
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
|
machine_st.b = machine_st.stack.index_or_frame(b).prelude.b;
|
||||||
machine_st.stack.truncate(b);
|
machine_st.stack.truncate(b);
|
||||||
@@ -928,13 +933,13 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
Addr::Con(h) if machine_st.heap.atom_at(h) => {
|
Addr::Con(h) if machine_st.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &machine_st.heap[h] {
|
||||||
match atom.as_str() {
|
match atom.as_str() {
|
||||||
">" | "<" | "=" => {
|
">" | "<" | "=" => {}
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
let stub =
|
let stub =
|
||||||
MachineError::functor_stub(clause_name!("compare"), 3);
|
MachineError::functor_stub(clause_name!("compare"), 3);
|
||||||
|
|
||||||
let err = MachineError::domain_error(DomainErrorType::Order, a1);
|
let err =
|
||||||
|
MachineError::domain_error(DomainErrorType::Order, a1);
|
||||||
return Err(machine_st.error_form(err, stub));
|
return Err(machine_st.error_form(err, stub));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -948,8 +953,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
let err = MachineError::type_error(h, ValidType::Atom, a1);
|
let err = MachineError::type_error(h, ValidType::Atom, a1);
|
||||||
return Err(machine_st.error_form(err, stub));
|
return Err(machine_st.error_form(err, stub));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
let atom = match machine_st.compare_term_test(&a2, &a3) {
|
||||||
@@ -998,9 +1002,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
let addr = machine_st[temp_v!(1)];
|
let addr = machine_st[temp_v!(1)];
|
||||||
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
|
let eof = clause_name!("end_of_file".to_string(), machine_st.atom_tbl);
|
||||||
|
|
||||||
let atom = machine_st.heap.to_unifiable(
|
let atom = machine_st.heap.to_unifiable(HeapCellValue::Atom(eof, None));
|
||||||
HeapCellValue::Atom(eof, None)
|
|
||||||
);
|
|
||||||
|
|
||||||
machine_st.unify(addr, atom);
|
machine_st.unify(addr, atom);
|
||||||
}
|
}
|
||||||
@@ -1056,7 +1058,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
let mut list = machine_st.try_from_list(temp_v!(1), stub)?;
|
let mut list = machine_st.try_from_list(temp_v!(1), stub)?;
|
||||||
|
|
||||||
list.sort_unstable_by(|a1, a2| {
|
list.sort_unstable_by(|a1, a2| {
|
||||||
machine_st.compare_term_test(a1, a2).unwrap_or(Ordering::Less)
|
machine_st
|
||||||
|
.compare_term_test(a1, a2)
|
||||||
|
.unwrap_or(Ordering::Less)
|
||||||
});
|
});
|
||||||
|
|
||||||
machine_st.term_dedup(&mut list);
|
machine_st.term_dedup(&mut list);
|
||||||
@@ -1081,7 +1085,9 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
key_pairs.sort_by(|a1, a2| {
|
key_pairs.sort_by(|a1, a2| {
|
||||||
machine_st.compare_term_test(&a1.0, &a2.0).unwrap_or(Ordering::Less)
|
machine_st
|
||||||
|
.compare_term_test(&a1.0, &a2.0)
|
||||||
|
.unwrap_or(Ordering::Less)
|
||||||
});
|
});
|
||||||
|
|
||||||
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
|
let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
|
||||||
@@ -1155,11 +1161,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
let stub = MachineError::functor_stub(clause_name!("call"), arity + 1);
|
||||||
|
|
||||||
return Err(machine_st.error_form(
|
return Err(machine_st.error_form(
|
||||||
MachineError::type_error(
|
MachineError::type_error(machine_st.heap.h(), ValidType::Callable, name),
|
||||||
machine_st.heap.h(),
|
|
||||||
ValidType::Callable,
|
|
||||||
name
|
|
||||||
),
|
|
||||||
stub,
|
stub,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -1200,7 +1202,8 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
arity: usize,
|
arity: usize,
|
||||||
idx: &CodeIndex,
|
idx: &CodeIndex,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
self.prev_policy.context_call(machine_st, name, arity, idx)?;//, indices)?;
|
self.prev_policy
|
||||||
|
.context_call(machine_st, name, arity, idx)?; //, indices)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1239,7 +1242,7 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
code_dir,
|
code_dir,
|
||||||
op_dir,
|
op_dir,
|
||||||
current_input_stream,
|
current_input_stream,
|
||||||
current_output_stream
|
current_output_stream,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
@@ -1283,8 +1286,7 @@ pub(crate) struct CWILCallPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CWILCallPolicy {
|
impl CWILCallPolicy {
|
||||||
pub(crate)
|
pub(crate) fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
||||||
fn new_in_place(policy: &mut Box<dyn CallPolicy>) {
|
|
||||||
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
let mut prev_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||||
mem::swap(&mut prev_policy, policy);
|
mem::swap(&mut prev_policy, policy);
|
||||||
|
|
||||||
@@ -1319,8 +1321,7 @@ impl CWILCallPolicy {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
||||||
fn add_limit(&mut self, mut limit: Integer, b: usize) -> &Integer {
|
|
||||||
limit += &self.count;
|
limit += &self.count;
|
||||||
|
|
||||||
match self.limits.last().cloned() {
|
match self.limits.last().cloned() {
|
||||||
@@ -1331,8 +1332,7 @@ impl CWILCallPolicy {
|
|||||||
&self.count
|
&self.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn remove_limit(&mut self, b: usize) -> &Integer {
|
||||||
fn remove_limit(&mut self, b: usize) -> &Integer {
|
|
||||||
if let Some((_, bp)) = self.limits.last().cloned() {
|
if let Some((_, bp)) = self.limits.last().cloned() {
|
||||||
if bp == b {
|
if bp == b {
|
||||||
self.limits.pop();
|
self.limits.pop();
|
||||||
@@ -1342,13 +1342,11 @@ impl CWILCallPolicy {
|
|||||||
&self.count
|
&self.count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
fn is_empty(&self) -> bool {
|
|
||||||
self.limits.is_empty()
|
self.limits.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate) fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
||||||
fn into_inner(&mut self) -> Box<dyn CallPolicy> {
|
|
||||||
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
let mut new_inner: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
|
||||||
mem::swap(&mut self.prev_policy, &mut new_inner);
|
mem::swap(&mut self.prev_policy, &mut new_inner);
|
||||||
new_inner
|
new_inner
|
||||||
@@ -1369,7 +1367,6 @@ fn cut_body(machine_st: &mut MachineState, addr: &Addr) -> bool {
|
|||||||
&Addr::CutPoint(b0) | &Addr::Usize(b0) => {
|
&Addr::CutPoint(b0) | &Addr::Usize(b0) => {
|
||||||
if b > b0 {
|
if b > b0 {
|
||||||
machine_st.b = b0;
|
machine_st.b = b0;
|
||||||
machine_st.tidy_trail();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -1457,7 +1454,6 @@ impl CutPolicy for SCCCutPolicy {
|
|||||||
Addr::Usize(b0) | Addr::CutPoint(b0) => {
|
Addr::Usize(b0) | Addr::CutPoint(b0) => {
|
||||||
if b > b0 {
|
if b > b0 {
|
||||||
machine_st.b = b0;
|
machine_st.b = b0;
|
||||||
machine_st.tidy_trail();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,8 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use prolog_parser::tabled_rc::*;
|
||||||
|
use prolog_parser::{clause_name, temp_v};
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
@@ -34,17 +37,18 @@ mod machine_state_impl;
|
|||||||
mod system_calls;
|
mod system_calls;
|
||||||
|
|
||||||
//use crate::machine::attributed_variables::*;
|
//use crate::machine::attributed_variables::*;
|
||||||
use crate::machine::compile::*;
|
|
||||||
use crate::machine::code_repo::*;
|
use crate::machine::code_repo::*;
|
||||||
|
use crate::machine::compile::*;
|
||||||
// use crate::machine::loader::*;
|
// use crate::machine::loader::*;
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
use crate::machine::machine_indices::*;
|
use crate::machine::machine_indices::*;
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
use crate::machine::streams::*;
|
use crate::machine::streams::*;
|
||||||
|
|
||||||
use crate::indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
//use std::convert::TryFrom;
|
//use std::convert::TryFrom;
|
||||||
|
use prolog_parser::ast::ClauseName;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -119,39 +123,6 @@ include!(concat!(env!("OUT_DIR"), "/libraries.rs"));
|
|||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
/*
|
/*
|
||||||
fn compile_special_forms(&mut self)
|
|
||||||
{
|
|
||||||
let verify_attrs_src = ListingSource::User;
|
|
||||||
|
|
||||||
match compile_special_form(
|
|
||||||
self,
|
|
||||||
Stream::from(VERIFY_ATTRS),
|
|
||||||
verify_attrs_src,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Ok(p) => {
|
|
||||||
self.machine_st.attr_var_init.verify_attrs_loc = p;
|
|
||||||
}
|
|
||||||
Err(_) =>
|
|
||||||
panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
|
|
||||||
}
|
|
||||||
|
|
||||||
let project_attrs_src = ListingSource::User;
|
|
||||||
|
|
||||||
match compile_special_form(
|
|
||||||
self,
|
|
||||||
Stream::from(PROJECT_ATTRS),
|
|
||||||
project_attrs_src,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Ok(p) => {
|
|
||||||
self.machine_st.attr_var_init.project_attrs_loc = p;
|
|
||||||
}
|
|
||||||
Err(e) =>
|
|
||||||
panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compile_scryerrc(&mut self) {
|
fn compile_scryerrc(&mut self) {
|
||||||
let mut path = match dirs_next::home_dir() {
|
let mut path = match dirs_next::home_dir() {
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
@@ -177,13 +148,7 @@ impl Machine {
|
|||||||
compile_user_module(self, file_src, rc_src);
|
compile_user_module(self, file_src, rc_src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
#[cfg(test)]
|
|
||||||
pub fn reset(&mut self) {
|
|
||||||
self.current_input_stream = readline::input_stream();
|
|
||||||
self.policies.cut_policy = Box::new(DefaultCutPolicy {});
|
|
||||||
self.machine_st.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_module_predicate(&mut self, module_name: ClauseName, key: PredicateKey) {
|
fn run_module_predicate(&mut self, module_name: ClauseName, key: PredicateKey) {
|
||||||
if let Some(module) = self.indices.modules.get(&module_name) {
|
if let Some(module) = self.indices.modules.get(&module_name) {
|
||||||
@@ -201,18 +166,13 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_file(&mut self, path: String, stream: Stream) {
|
fn load_file(&mut self, path: String, stream: Stream) {
|
||||||
self.machine_st[temp_v!(1)] = Addr::Stream(
|
self.machine_st[temp_v!(1)] =
|
||||||
self.machine_st.heap.push(HeapCellValue::Stream(
|
Addr::Stream(self.machine_st.heap.push(HeapCellValue::Stream(stream)));
|
||||||
stream,
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
self.machine_st[temp_v!(2)] = Addr::Con(
|
self.machine_st[temp_v!(2)] = Addr::Con(self.machine_st.heap.push(HeapCellValue::Atom(
|
||||||
self.machine_st.heap.push(HeapCellValue::Atom(
|
clause_name!(path, self.machine_st.atom_tbl),
|
||||||
clause_name!(path, self.machine_st.atom_tbl),
|
None,
|
||||||
None,
|
)));
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
|
self.run_module_predicate(clause_name!("loader"), (clause_name!("file_load"), 2));
|
||||||
}
|
}
|
||||||
@@ -245,11 +205,9 @@ impl Machine {
|
|||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(include_str!("attributed_variables.pl")),
|
Stream::from(include_str!("attributed_variables.pl")),
|
||||||
self,
|
self,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("attributed_variables"), path_buf),
|
||||||
clause_name!("attributed_variables"),
|
)
|
||||||
path_buf,
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
let mut path_buf = current_dir();
|
let mut path_buf = current_dir();
|
||||||
path_buf.push("machine/project_attributes.pl");
|
path_buf.push("machine/project_attributes.pl");
|
||||||
@@ -257,11 +215,9 @@ impl Machine {
|
|||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(include_str!("project_attributes.pl")),
|
Stream::from(include_str!("project_attributes.pl")),
|
||||||
self,
|
self,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("project_attributes"), path_buf),
|
||||||
clause_name!("project_attributes"),
|
)
|
||||||
path_buf,
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
|
if let Some(module) = self.indices.modules.get(&clause_name!("$atts")) {
|
||||||
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
|
if let Some(code_index) = module.code_dir.get(&(clause_name!("driver"), 2)) {
|
||||||
@@ -289,15 +245,66 @@ impl Machine {
|
|||||||
|
|
||||||
self.machine_st[temp_v!(1)] = list_addr;
|
self.machine_st[temp_v!(1)] = list_addr;
|
||||||
|
|
||||||
// WAS:
|
self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("$repl"), 1));
|
||||||
// self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("$repl"), 1));
|
|
||||||
|
|
||||||
self.run_module_predicate(clause_name!("$toplevel"), (clause_name!("repl"), 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(user_input: Stream, user_output: Stream) -> Self
|
fn configure_modules(&mut self) {
|
||||||
{
|
fn update_call_n_indices(loader: &Module, target_module: &mut Module) {
|
||||||
use crate::ref_thread_local::RefThreadLocal;
|
for arity in 1..66 {
|
||||||
|
let key = (clause_name!("call"), arity);
|
||||||
|
|
||||||
|
match loader.code_dir.get(&key) {
|
||||||
|
Some(src_code_index) => {
|
||||||
|
let target_code_index = target_module
|
||||||
|
.code_dir
|
||||||
|
.entry(key.clone())
|
||||||
|
.or_insert_with(|| CodeIndex::new(IndexPtr::Undefined));
|
||||||
|
|
||||||
|
target_code_index.set(src_code_index.get());
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(loader) = self.indices.modules.swap_remove(&clause_name!("loader")) {
|
||||||
|
if let Some(builtins) = self.indices.modules.get_mut(&clause_name!("builtins")) {
|
||||||
|
// Import loader's exports into the builtins module so they will be
|
||||||
|
// implicitly included in every further module.
|
||||||
|
load_module(
|
||||||
|
&mut builtins.code_dir,
|
||||||
|
&mut builtins.op_dir,
|
||||||
|
&mut builtins.meta_predicates,
|
||||||
|
&CompilationTarget::Module(clause_name!("builtins")),
|
||||||
|
&loader,
|
||||||
|
);
|
||||||
|
|
||||||
|
for export in &loader.module_decl.exports {
|
||||||
|
builtins.module_decl.exports.push(export.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
for arity in 10..66 {
|
||||||
|
builtins
|
||||||
|
.module_decl
|
||||||
|
.exports
|
||||||
|
.push(ModuleExport::PredicateKey((clause_name!("call"), arity)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (_, target_module) in self.indices.modules.iter_mut() {
|
||||||
|
update_call_n_indices(&loader, target_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.indices.modules.insert(clause_name!("loader"), loader);
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(user_input: Stream, user_output: Stream) -> Self {
|
||||||
|
use ref_thread_local::RefThreadLocal;
|
||||||
|
|
||||||
let mut wam = Machine {
|
let mut wam = Machine {
|
||||||
machine_st: MachineState::new(),
|
machine_st: MachineState::new(),
|
||||||
@@ -322,16 +329,15 @@ impl Machine {
|
|||||||
clause_name!("ops_and_meta_predicates.pl"),
|
clause_name!("ops_and_meta_predicates.pl"),
|
||||||
lib_path.clone(),
|
lib_path.clone(),
|
||||||
),
|
),
|
||||||
).unwrap();
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(LIBRARIES.borrow()["builtins"]),
|
Stream::from(LIBRARIES.borrow()["builtins"]),
|
||||||
&mut wam,
|
&mut wam,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("builtins.pl"), lib_path.clone()),
|
||||||
clause_name!("builtins.pl"),
|
)
|
||||||
lib_path.clone(),
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
|
if let Some(builtins) = wam.indices.modules.get(&clause_name!("builtins")) {
|
||||||
load_module(
|
load_module(
|
||||||
@@ -350,38 +356,20 @@ impl Machine {
|
|||||||
bootstrapping_compile(
|
bootstrapping_compile(
|
||||||
Stream::from(include_str!("../loader.pl")),
|
Stream::from(include_str!("../loader.pl")),
|
||||||
&mut wam,
|
&mut wam,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(clause_name!("loader.pl"), lib_path.clone()),
|
||||||
clause_name!("loader.pl"),
|
)
|
||||||
lib_path.clone(),
|
.unwrap();
|
||||||
),
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
if let Some(loader) = wam.indices.modules.swap_remove(&clause_name!("loader")) {
|
wam.configure_modules();
|
||||||
if let Some(builtins) = wam.indices.modules.get_mut(&clause_name!("builtins")) {
|
|
||||||
// Import loader's exports into the builtins module so they will be
|
|
||||||
// implicitly included every further module.
|
|
||||||
load_module(
|
|
||||||
&mut builtins.code_dir,
|
|
||||||
&mut builtins.op_dir,
|
|
||||||
&mut builtins.meta_predicates,
|
|
||||||
&CompilationTarget::Module(clause_name!("builtins")),
|
|
||||||
&loader,
|
|
||||||
);
|
|
||||||
|
|
||||||
for export in &loader.module_decl.exports {
|
|
||||||
builtins.module_decl.exports.push(export.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if let Some(loader) = wam.indices.modules.get(&clause_name!("loader")) {
|
||||||
load_module(
|
load_module(
|
||||||
&mut wam.indices.code_dir,
|
&mut wam.indices.code_dir,
|
||||||
&mut wam.indices.op_dir,
|
&mut wam.indices.op_dir,
|
||||||
&mut wam.indices.meta_predicates,
|
&mut wam.indices.meta_predicates,
|
||||||
&CompilationTarget::User,
|
&CompilationTarget::User,
|
||||||
&loader,
|
loader,
|
||||||
);
|
);
|
||||||
|
|
||||||
wam.indices.modules.insert(clause_name!("loader"), loader);
|
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -396,25 +384,19 @@ impl Machine {
|
|||||||
pub fn configure_streams(&mut self) {
|
pub fn configure_streams(&mut self) {
|
||||||
self.user_input.options.alias = Some(clause_name!("user_input"));
|
self.user_input.options.alias = Some(clause_name!("user_input"));
|
||||||
|
|
||||||
self.indices.stream_aliases.insert(
|
self.indices
|
||||||
clause_name!("user_input"),
|
.stream_aliases
|
||||||
self.user_input.clone(),
|
.insert(clause_name!("user_input"), self.user_input.clone());
|
||||||
);
|
|
||||||
|
|
||||||
self.indices.streams.insert(
|
self.indices.streams.insert(self.user_input.clone());
|
||||||
self.user_input.clone()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.user_output.options.alias = Some(clause_name!("user_output"));
|
self.user_output.options.alias = Some(clause_name!("user_output"));
|
||||||
|
|
||||||
self.indices.stream_aliases.insert(
|
self.indices
|
||||||
clause_name!("user_output"),
|
.stream_aliases
|
||||||
self.user_output.clone(),
|
.insert(clause_name!("user_output"), self.user_output.clone());
|
||||||
);
|
|
||||||
|
|
||||||
self.indices.streams.insert(
|
self.indices.streams.insert(self.user_output.clone());
|
||||||
self.user_output.clone()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
|
fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
|
||||||
@@ -487,25 +469,33 @@ impl Machine {
|
|||||||
REPLCodePtr::BuiltInProperty => {
|
REPLCodePtr::BuiltInProperty => {
|
||||||
self.builtin_property();
|
self.builtin_property();
|
||||||
}
|
}
|
||||||
REPLCodePtr::CompilePendingPredicates => {
|
REPLCodePtr::MultifileProperty => {
|
||||||
self.compile_pending_predicates();
|
self.multifile_property();
|
||||||
}
|
}
|
||||||
REPLCodePtr::UserAssertz => {
|
REPLCodePtr::DiscontiguousProperty => {
|
||||||
self.compile_user_assert(AppendOrPrepend::Append);
|
self.discontiguous_property();
|
||||||
}
|
}
|
||||||
REPLCodePtr::UserAsserta => {
|
REPLCodePtr::DynamicProperty => {
|
||||||
self.compile_user_assert(AppendOrPrepend::Prepend);
|
self.dynamic_property();
|
||||||
}
|
}
|
||||||
REPLCodePtr::UserRetract => {
|
REPLCodePtr::Assertz => {
|
||||||
self.retract_user_clause();
|
self.compile_assert(AppendOrPrepend::Append);
|
||||||
|
}
|
||||||
|
REPLCodePtr::Asserta => {
|
||||||
|
self.compile_assert(AppendOrPrepend::Prepend);
|
||||||
|
}
|
||||||
|
REPLCodePtr::Retract => {
|
||||||
|
self.retract_clause();
|
||||||
|
}
|
||||||
|
REPLCodePtr::AbolishClause => {
|
||||||
|
self.abolish_clause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.p = CodePtr::Local(p);
|
self.machine_st.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn run_query(&mut self) {
|
||||||
fn run_query(&mut self) {
|
|
||||||
while !self.machine_st.p.is_halt() {
|
while !self.machine_st.p.is_halt() {
|
||||||
self.machine_st.query_stepper(
|
self.machine_st.query_stepper(
|
||||||
&mut self.indices,
|
&mut self.indices,
|
||||||
@@ -523,23 +513,6 @@ impl Machine {
|
|||||||
self.machine_st.backtrack();
|
self.machine_st.backtrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
CodePtr::DynamicTransaction(_trans_type, _p) => {
|
|
||||||
// self.code_repo.cached_query is about to be overwritten by the term expander,
|
|
||||||
// so hold onto it locally and restore it after the compiler has finished.
|
|
||||||
self.machine_st.fail = false;
|
|
||||||
/*
|
|
||||||
let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]);
|
|
||||||
|
|
||||||
// self.dynamic_transaction(trans_type, p);
|
|
||||||
self.code_repo.cached_query = cached_query;
|
|
||||||
|
|
||||||
if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
_ => {
|
_ => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -559,26 +532,22 @@ impl MachineState {
|
|||||||
user_output: &mut Stream,
|
user_output: &mut Stream,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&Line::Arithmetic(ref arith_instr) => {
|
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||||
self.execute_arith_instr(arith_instr)
|
|
||||||
}
|
|
||||||
&Line::Choice(ref choice_instr) => {
|
&Line::Choice(ref choice_instr) => {
|
||||||
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
|
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
|
||||||
}
|
}
|
||||||
&Line::Cut(ref cut_instr) => {
|
&Line::Cut(ref cut_instr) => {
|
||||||
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
||||||
}
|
}
|
||||||
&Line::Control(ref control_instr) => {
|
&Line::Control(ref control_instr) => self.execute_ctrl_instr(
|
||||||
self.execute_ctrl_instr(
|
indices,
|
||||||
indices,
|
code_repo,
|
||||||
code_repo,
|
&mut policies.call_policy,
|
||||||
&mut policies.call_policy,
|
&mut policies.cut_policy,
|
||||||
&mut policies.cut_policy,
|
user_input,
|
||||||
user_input,
|
user_output,
|
||||||
user_output,
|
control_instr,
|
||||||
control_instr,
|
),
|
||||||
)
|
|
||||||
}
|
|
||||||
&Line::Fact(ref fact_instr) => {
|
&Line::Fact(ref fact_instr) => {
|
||||||
self.execute_fact_instr(&fact_instr);
|
self.execute_fact_instr(&fact_instr);
|
||||||
self.p += 1;
|
self.p += 1;
|
||||||
@@ -620,44 +589,23 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn backtrack(&mut self) {
|
fn backtrack(&mut self) {
|
||||||
// if self.b > 0 {
|
|
||||||
let b = self.b;
|
let b = self.b;
|
||||||
|
|
||||||
self.b0 = self.stack.index_or_frame(b).prelude.b0;
|
self.b0 = self.stack.index_or_frame(b).prelude.b0;
|
||||||
self.p = CodePtr::Local(self.stack.index_or_frame(b).prelude.bp);
|
self.p = CodePtr::Local(self.stack.index_or_frame(b).prelude.bp);
|
||||||
|
|
||||||
/*
|
|
||||||
if let CodePtr::Local(LocalCodePtr::TopLevel(_, p)) = self.p {
|
|
||||||
self.fail = p == 0;
|
|
||||||
} else {
|
|
||||||
*/
|
|
||||||
self.fail = false;
|
self.fail = false;
|
||||||
// }
|
|
||||||
/*} else {
|
|
||||||
self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
|
fn check_machine_index(&mut self, code_repo: &CodeRepo) -> bool {
|
||||||
match self.p {
|
match self.p {
|
||||||
CodePtr::Local(LocalCodePtr::DirEntry(p)) |
|
CodePtr::Local(LocalCodePtr::DirEntry(p))
|
||||||
CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
| CodePtr::Local(LocalCodePtr::IndexingBuf(p, ..))
|
||||||
if p < code_repo.code.len() => {
|
if p < code_repo.code.len() => {}
|
||||||
}
|
|
||||||
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
|
CodePtr::Local(LocalCodePtr::Halt) | CodePtr::REPL(..) => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
_ => {}
|
||||||
CodePtr::DynamicTransaction(..) => {
|
|
||||||
// prevent use of dynamic transactions from
|
|
||||||
// succeeding in expansions. self.fail will be toggled
|
|
||||||
// back to false later.
|
|
||||||
self.fail = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
_ => {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -721,13 +669,7 @@ impl MachineState {
|
|||||||
user_output: &mut Stream,
|
user_output: &mut Stream,
|
||||||
) {
|
) {
|
||||||
loop {
|
loop {
|
||||||
self.execute_instr(
|
self.execute_instr(indices, policies, code_repo, user_input, user_output);
|
||||||
indices,
|
|
||||||
policies,
|
|
||||||
code_repo,
|
|
||||||
user_input,
|
|
||||||
user_output,
|
|
||||||
);
|
|
||||||
|
|
||||||
if self.fail {
|
if self.fail {
|
||||||
self.backtrack();
|
self.backtrack();
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::*;
|
use prolog_parser::tabled_rc::*;
|
||||||
|
use prolog_parser::{atom, clause_name, rc_atom};
|
||||||
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::iterators::*;
|
use crate::iterators::*;
|
||||||
use crate::machine::*;
|
|
||||||
use crate::machine::load_state::*;
|
use crate::machine::load_state::*;
|
||||||
use crate::machine::machine_errors::*;
|
use crate::machine::machine_errors::*;
|
||||||
|
use crate::machine::*;
|
||||||
|
|
||||||
use crate::indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
@@ -85,28 +86,25 @@ fn setup_op_decl(
|
|||||||
to_op_decl(prec, spec.as_str(), name)
|
to_op_decl(prec, spec.as_str(), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError>
|
fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, CompilationError> {
|
||||||
{
|
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(_, ref slash, ref mut terms, Some(_))
|
Term::Clause(_, ref slash, ref mut terms, Some(_))
|
||||||
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
|
if (slash.as_str() == "/" || slash.as_str() == "//") && terms.len() == 2 =>
|
||||||
{
|
{
|
||||||
let arity = *terms.pop().unwrap();
|
let arity = *terms.pop().unwrap();
|
||||||
let name = *terms.pop().unwrap();
|
let name = *terms.pop().unwrap();
|
||||||
|
|
||||||
let arity = arity
|
let arity = arity
|
||||||
.to_constant()
|
.into_constant()
|
||||||
.and_then(|c| {
|
.and_then(|c| match c {
|
||||||
match c {
|
Constant::Integer(n) => n.to_usize(),
|
||||||
Constant::Integer(n) => n.to_usize(),
|
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
||||||
Constant::Fixnum(n) => usize::try_from(n).ok(),
|
_ => None,
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||||
|
|
||||||
let name = name
|
let name = name
|
||||||
.to_constant()
|
.into_constant()
|
||||||
.and_then(|c| c.to_atom())
|
.and_then(|c| c.to_atom())
|
||||||
.ok_or(CompilationError::InvalidModuleExport)?;
|
.ok_or(CompilationError::InvalidModuleExport)?;
|
||||||
|
|
||||||
@@ -116,9 +114,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
|
|||||||
Ok((name, arity + 2))
|
Ok((name, arity + 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(CompilationError::InvalidModuleExport),
|
||||||
Err(CompilationError::InvalidModuleExport)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +151,7 @@ fn setup_module_export(
|
|||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
if let Term::Clause(_, name, terms, _) = term {
|
if let Term::Clause(_, name, terms, _) = term {
|
||||||
if terms.len() == 3 && name.as_str() == "op" {
|
if terms.len() == 3 && name.as_str() == "op" {
|
||||||
Ok(ModuleExport::OpDecl(setup_op_decl(
|
Ok(ModuleExport::OpDecl(setup_op_decl(terms, atom_tbl)?))
|
||||||
terms,
|
|
||||||
atom_tbl
|
|
||||||
)?))
|
|
||||||
} else {
|
} else {
|
||||||
Err(CompilationError::InvalidModuleDecl)
|
Err(CompilationError::InvalidModuleDecl)
|
||||||
}
|
}
|
||||||
@@ -168,8 +161,7 @@ fn setup_module_export(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn setup_module_export_list(
|
||||||
fn setup_module_export_list(
|
|
||||||
mut export_list: Term,
|
mut export_list: Term,
|
||||||
atom_tbl: TabledData<Atom>,
|
atom_tbl: TabledData<Atom>,
|
||||||
) -> Result<Vec<ModuleExport>, CompilationError> {
|
) -> Result<Vec<ModuleExport>, CompilationError> {
|
||||||
@@ -182,7 +174,7 @@ fn setup_module_export_list(
|
|||||||
export_list = *t2;
|
export_list = *t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if export_list.to_constant() != Some(Constant::EmptyList) {
|
if export_list.into_constant() != Some(Constant::EmptyList) {
|
||||||
Err(CompilationError::InvalidModuleDecl)
|
Err(CompilationError::InvalidModuleDecl)
|
||||||
} else {
|
} else {
|
||||||
Ok(exports)
|
Ok(exports)
|
||||||
@@ -197,7 +189,7 @@ fn setup_module_decl(
|
|||||||
let name = terms
|
let name = terms
|
||||||
.pop()
|
.pop()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_constant()
|
.into_constant()
|
||||||
.and_then(|c| c.to_atom())
|
.and_then(|c| c.to_atom())
|
||||||
.ok_or(CompilationError::InvalidModuleDecl)?;
|
.ok_or(CompilationError::InvalidModuleDecl)?;
|
||||||
|
|
||||||
@@ -213,13 +205,12 @@ fn setup_use_module_decl(mut terms: Vec<Box<Term>>) -> Result<ModuleSource, Comp
|
|||||||
terms
|
terms
|
||||||
.pop()
|
.pop()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_constant()
|
.into_constant()
|
||||||
.and_then(|c| c.to_atom())
|
.and_then(|c| c.to_atom())
|
||||||
.map(|c| ModuleSource::Library(c))
|
.map(|c| ModuleSource::Library(c))
|
||||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Atom(ref name, _)) =>
|
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||||
Ok(ModuleSource::File(name.clone())),
|
|
||||||
_ => Err(CompilationError::InvalidUseModuleDecl),
|
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,17 +257,13 @@ fn setup_qualified_import(
|
|||||||
terms
|
terms
|
||||||
.pop()
|
.pop()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_constant()
|
.into_constant()
|
||||||
.and_then(|c| c.to_atom())
|
.and_then(|c| c.to_atom())
|
||||||
.map(|c| ModuleSource::Library(c))
|
.map(|c| ModuleSource::Library(c))
|
||||||
.ok_or(CompilationError::InvalidUseModuleDecl)
|
.ok_or(CompilationError::InvalidUseModuleDecl)
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Atom(ref name, _)) => {
|
Term::Constant(_, Constant::Atom(ref name, _)) => Ok(ModuleSource::File(name.clone())),
|
||||||
Ok(ModuleSource::File(name.clone()))
|
_ => Err(CompilationError::InvalidUseModuleDecl),
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InvalidUseModuleDecl)
|
|
||||||
}
|
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let mut exports = IndexSet::new();
|
let mut exports = IndexSet::new();
|
||||||
@@ -286,7 +273,7 @@ fn setup_qualified_import(
|
|||||||
export_list = *t2;
|
export_list = *t2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if export_list.to_constant() != Some(Constant::EmptyList) {
|
if export_list.into_constant() != Some(Constant::EmptyList) {
|
||||||
Err(CompilationError::InvalidModuleDecl)
|
Err(CompilationError::InvalidModuleDecl)
|
||||||
} else {
|
} else {
|
||||||
Ok((module_src, exports))
|
Ok((module_src, exports))
|
||||||
@@ -334,8 +321,7 @@ fn setup_qualified_import(
|
|||||||
fn setup_meta_predicate<'a>(
|
fn setup_meta_predicate<'a>(
|
||||||
mut terms: Vec<Box<Term>>,
|
mut terms: Vec<Box<Term>>,
|
||||||
load_state: &LoadState<'a>,
|
load_state: &LoadState<'a>,
|
||||||
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError>
|
) -> Result<(ClauseName, ClauseName, Vec<MetaSpec>), CompilationError> {
|
||||||
{
|
|
||||||
fn get_name_and_meta_specs(
|
fn get_name_and_meta_specs(
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
terms: &mut [Box<Term>],
|
terms: &mut [Box<Term>],
|
||||||
@@ -345,26 +331,23 @@ fn setup_meta_predicate<'a>(
|
|||||||
for meta_spec in terms.into_iter() {
|
for meta_spec in terms.into_iter() {
|
||||||
match &**meta_spec {
|
match &**meta_spec {
|
||||||
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
|
Term::Constant(_, Constant::Atom(meta_spec, _)) => {
|
||||||
let meta_spec =
|
let meta_spec = match meta_spec.as_str() {
|
||||||
match meta_spec.as_str() {
|
"+" => MetaSpec::Plus,
|
||||||
"+" => MetaSpec::Plus,
|
"-" => MetaSpec::Minus,
|
||||||
"-" => MetaSpec::Minus,
|
"?" => MetaSpec::Either,
|
||||||
"?" => MetaSpec::Either,
|
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
|
||||||
_ => return Err(CompilationError::InvalidMetaPredicateDecl),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
meta_specs.push(meta_spec);
|
meta_specs.push(meta_spec);
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Fixnum(n)) => {
|
Term::Constant(_, Constant::Fixnum(n)) => match usize::try_from(*n) {
|
||||||
match usize::try_from(*n) {
|
Ok(n) if n <= MAX_ARITY => {
|
||||||
Ok(n) if n <= MAX_ARITY => {
|
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
||||||
meta_specs.push(MetaSpec::RequiresExpansionWithArgument(n));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
_ => {
|
||||||
|
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CompilationError::InvalidMetaPredicateDecl);
|
return Err(CompilationError::InvalidMetaPredicateDecl);
|
||||||
}
|
}
|
||||||
@@ -375,42 +358,35 @@ fn setup_meta_predicate<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match *terms.pop().unwrap() {
|
match *terms.pop().unwrap() {
|
||||||
Term::Clause(_, name, mut terms, _)
|
Term::Clause(_, name, mut terms, _) if name.as_str() == ":" && terms.len() == 2 => {
|
||||||
if name.as_str() == ":" && terms.len() == 2 => {
|
let spec = *terms.pop().unwrap();
|
||||||
let spec = *terms.pop().unwrap();
|
let module_name = *terms.pop().unwrap();
|
||||||
let module_name = *terms.pop().unwrap();
|
|
||||||
|
|
||||||
match module_name {
|
match module_name {
|
||||||
Term::Constant(_, Constant::Atom(module_name, _)) => {
|
Term::Constant(_, Constant::Atom(module_name, _)) => match spec {
|
||||||
match spec {
|
Term::Clause(_, name, mut terms, _) => {
|
||||||
Term::Clause(_, name, mut terms, _) => {
|
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||||
let (name, meta_specs) =
|
|
||||||
get_name_and_meta_specs(name, &mut terms)?;
|
|
||||||
|
|
||||||
Ok((module_name, name, meta_specs))
|
Ok((module_name, name, meta_specs))
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
},
|
||||||
}
|
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Term::Clause(_, name, mut terms, _) => {
|
Term::Clause(_, name, mut terms, _) => {
|
||||||
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
let (name, meta_specs) = get_name_and_meta_specs(name, &mut terms)?;
|
||||||
Ok((load_state.module_name(), name, meta_specs))
|
Ok((
|
||||||
}
|
load_state.compilation_target.module_name(),
|
||||||
_ => {
|
name,
|
||||||
Err(CompilationError::InvalidMetaPredicateDecl)
|
meta_specs,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
_ => Err(CompilationError::InvalidMetaPredicateDecl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError>
|
fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationError> {
|
||||||
{
|
|
||||||
let mut clauses = vec![];
|
let mut clauses = vec![];
|
||||||
|
|
||||||
while let Some(tl) = tls.pop_front() {
|
while let Some(tl) = tls.pop_front() {
|
||||||
@@ -432,9 +408,7 @@ fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, CompilationEr
|
|||||||
let clause = PredicateClause::Rule(rule);
|
let clause = PredicateClause::Rule(rule);
|
||||||
clauses.push(clause);
|
clauses.push(clause);
|
||||||
}
|
}
|
||||||
TopLevel::Predicate(predicate) => {
|
TopLevel::Predicate(predicate) => clauses.extend(predicate.into_iter()),
|
||||||
clauses.extend(predicate.into_iter())
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
tls.push_front(tl);
|
tls.push_front(tl);
|
||||||
break;
|
break;
|
||||||
@@ -506,8 +480,8 @@ fn check_for_internal_if_then(terms: &mut Vec<Term>) {
|
|||||||
|
|
||||||
conq_terms.push_front(Term::Constant(
|
conq_terms.push_front(Term::Constant(
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
Constant::Atom(clause_name!("blocked_!"), None))
|
Constant::Atom(clause_name!("blocked_!"), None),
|
||||||
);
|
));
|
||||||
|
|
||||||
while let Some(term) = pre_cut_terms.pop_back() {
|
while let Some(term) = pre_cut_terms.pop_back() {
|
||||||
conq_terms.push_front(term);
|
conq_terms.push_front(term);
|
||||||
@@ -531,38 +505,29 @@ fn setup_declaration<'a>(
|
|||||||
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
|
let atom_tbl = load_state.wam.machine_st.atom_tbl.clone();
|
||||||
|
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(_, name, mut terms, _) =>
|
Term::Clause(_, name, mut terms, _) => match (name.as_str(), terms.len()) {
|
||||||
match (name.as_str(), terms.len()) {
|
("dynamic", 1) => {
|
||||||
("dynamic", 1) => {
|
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
Ok(Declaration::Dynamic(name, arity))
|
||||||
Ok(Declaration::Dynamic(name, arity))
|
}
|
||||||
}
|
("module", 2) => Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
||||||
("module", 2) =>
|
("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
||||||
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?)),
|
("non_counted_backtracking", 1) => {
|
||||||
("op", 3) =>
|
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
||||||
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?)),
|
Ok(Declaration::NonCountedBacktracking(name, arity))
|
||||||
("non_counted_backtracking", 1) => {
|
}
|
||||||
let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?;
|
("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||||
Ok(Declaration::NonCountedBacktracking(name, arity))
|
("use_module", 2) => {
|
||||||
}
|
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
||||||
("use_module", 1) => {
|
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||||
Ok(Declaration::UseModule(setup_use_module_decl(terms)?))
|
}
|
||||||
}
|
("meta_predicate", 1) => {
|
||||||
("use_module", 2) => {
|
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
||||||
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
|
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
||||||
Ok(Declaration::UseQualifiedModule(name, exports))
|
}
|
||||||
}
|
_ => Err(CompilationError::InconsistentEntry),
|
||||||
("meta_predicate", 1) => {
|
},
|
||||||
let (module_name, name, meta_specs) = setup_meta_predicate(terms, load_state)?;
|
_ => Err(CompilationError::InconsistentEntry),
|
||||||
Ok(Declaration::MetaPredicate(module_name, name, meta_specs))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InconsistentEntry)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InconsistentEntry)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,8 +561,7 @@ pub(crate) struct Preprocessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Preprocessor {
|
impl Preprocessor {
|
||||||
pub(super)
|
pub(super) fn new(flags: MachineFlags) -> Self {
|
||||||
fn new(flags: MachineFlags) -> Self {
|
|
||||||
Preprocessor {
|
Preprocessor {
|
||||||
flags,
|
flags,
|
||||||
queue: VecDeque::new(),
|
queue: VecDeque::new(),
|
||||||
@@ -606,12 +570,8 @@ impl Preprocessor {
|
|||||||
|
|
||||||
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
|
fn setup_fact(&mut self, term: Term) -> Result<Term, CompilationError> {
|
||||||
match term {
|
match term {
|
||||||
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => {
|
Term::Clause(..) | Term::Constant(_, Constant::Atom(..)) => Ok(term),
|
||||||
Ok(term)
|
_ => Err(CompilationError::InadmissibleFact),
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InadmissibleFact)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,109 +672,97 @@ impl Preprocessor {
|
|||||||
Ok(clause_to_query_term(load_state, name, vec![], fixity))
|
Ok(clause_to_query_term(load_state, name, vec![], fixity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Term::Constant(_, Constant::Char('!')) => {
|
Term::Constant(_, Constant::Char('!')) => Ok(QueryTerm::BlockedCut),
|
||||||
Ok(QueryTerm::BlockedCut)
|
|
||||||
}
|
|
||||||
Term::Var(_, ref v) if v.as_str() == "!" => {
|
Term::Var(_, ref v) if v.as_str() == "!" => {
|
||||||
Ok(QueryTerm::UnblockedCut(Cell::default()))
|
Ok(QueryTerm::UnblockedCut(Cell::default()))
|
||||||
}
|
}
|
||||||
Term::Clause(r, name, mut terms, fixity) => {
|
Term::Clause(r, name, mut terms, fixity) => match (name.as_str(), terms.len()) {
|
||||||
match (name.as_str(), terms.len()) {
|
(";", 2) => {
|
||||||
(";", 2) => {
|
let term = Term::Clause(r, name.clone(), terms, fixity);
|
||||||
let term = Term::Clause(r, name.clone(), terms, fixity);
|
|
||||||
|
|
||||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||||
self.queue.push_back(clauses);
|
self.queue.push_back(clauses);
|
||||||
|
|
||||||
Ok(QueryTerm::Jump(stub))
|
Ok(QueryTerm::Jump(stub))
|
||||||
}
|
}
|
||||||
("->", 2) => {
|
("->", 2) => {
|
||||||
let conq = *terms.pop().unwrap();
|
let conq = *terms.pop().unwrap();
|
||||||
let prec = *terms.pop().unwrap();
|
let prec = *terms.pop().unwrap();
|
||||||
|
|
||||||
let (stub, clauses) = self.fabricate_if_then(prec, conq);
|
let (stub, clauses) = self.fabricate_if_then(prec, conq);
|
||||||
self.queue.push_back(clauses);
|
self.queue.push_back(clauses);
|
||||||
|
|
||||||
Ok(QueryTerm::Jump(stub))
|
Ok(QueryTerm::Jump(stub))
|
||||||
}
|
}
|
||||||
("\\+", 1) => {
|
("\\+", 1) => {
|
||||||
terms.push(Box::new(Term::Constant(
|
terms.push(Box::new(Term::Constant(
|
||||||
Cell::default(),
|
Cell::default(),
|
||||||
Constant::Atom(clause_name!("$fail"), None)
|
Constant::Atom(clause_name!("$fail"), None),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
let conq = Term::Constant(
|
let conq =
|
||||||
Cell::default(),
|
Term::Constant(Cell::default(), Constant::Atom(clause_name!("true"), None));
|
||||||
Constant::Atom(clause_name!("true"), None)
|
|
||||||
);
|
|
||||||
|
|
||||||
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
let prec = Term::Clause(Cell::default(), clause_name!("->"), terms, None);
|
||||||
let terms = vec![Box::new(prec), Box::new(conq)];
|
let terms = vec![Box::new(prec), Box::new(conq)];
|
||||||
|
|
||||||
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
|
let term = Term::Clause(Cell::default(), clause_name!(";"), terms, None);
|
||||||
let (stub, clauses) = self.fabricate_disjunct(term);
|
let (stub, clauses) = self.fabricate_disjunct(term);
|
||||||
|
|
||||||
debug_assert!(clauses.len() > 0);
|
debug_assert!(clauses.len() > 0);
|
||||||
self.queue.push_back(clauses);
|
self.queue.push_back(clauses);
|
||||||
|
|
||||||
Ok(QueryTerm::Jump(stub))
|
Ok(QueryTerm::Jump(stub))
|
||||||
}
|
}
|
||||||
("$get_level", 1) => {
|
("$get_level", 1) => {
|
||||||
if let Term::Var(_, ref var) = *terms[0] {
|
if let Term::Var(_, ref var) = *terms[0] {
|
||||||
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
|
Ok(QueryTerm::GetLevelAndUnify(Cell::default(), var.clone()))
|
||||||
} else {
|
} else {
|
||||||
Err(CompilationError::InadmissibleQueryTerm)
|
Err(CompilationError::InadmissibleQueryTerm)
|
||||||
}
|
|
||||||
}
|
|
||||||
(":", 2) => {
|
|
||||||
let predicate_name = *terms.pop().unwrap();
|
|
||||||
let module_name = *terms.pop().unwrap();
|
|
||||||
|
|
||||||
match (module_name, predicate_name) {
|
|
||||||
(Term::Constant(_, Constant::Atom(module_name, _)),
|
|
||||||
Term::Constant(_, Constant::Atom(predicate_name, fixity))) => {
|
|
||||||
Ok(qualified_clause_to_query_term(
|
|
||||||
load_state,
|
|
||||||
module_name,
|
|
||||||
predicate_name,
|
|
||||||
vec![],
|
|
||||||
fixity,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(Term::Constant(_, Constant::Atom(module_name, _)),
|
|
||||||
Term::Clause(_, name, terms, fixity)) => {
|
|
||||||
Ok(qualified_clause_to_query_term(
|
|
||||||
load_state,
|
|
||||||
module_name,
|
|
||||||
name,
|
|
||||||
terms,
|
|
||||||
fixity,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
(module_name, predicate_name) => {
|
|
||||||
terms.push(Box::new(module_name));
|
|
||||||
terms.push(Box::new(predicate_name));
|
|
||||||
|
|
||||||
Ok(clause_to_query_term(load_state, name, terms, fixity))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Ok(clause_to_query_term(load_state, name, terms, fixity))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
(":", 2) => {
|
||||||
Term::Var(..) => {
|
let predicate_name = *terms.pop().unwrap();
|
||||||
Ok(QueryTerm::Clause(
|
let module_name = *terms.pop().unwrap();
|
||||||
Cell::default(),
|
|
||||||
ClauseType::CallN,
|
match (module_name, predicate_name) {
|
||||||
vec![Box::new(term)],
|
(
|
||||||
false,
|
Term::Constant(_, Constant::Atom(module_name, _)),
|
||||||
))
|
Term::Constant(_, Constant::Atom(predicate_name, fixity)),
|
||||||
}
|
) => Ok(qualified_clause_to_query_term(
|
||||||
_ => {
|
load_state,
|
||||||
Err(CompilationError::InadmissibleQueryTerm)
|
module_name,
|
||||||
}
|
predicate_name,
|
||||||
|
vec![],
|
||||||
|
fixity,
|
||||||
|
)),
|
||||||
|
(
|
||||||
|
Term::Constant(_, Constant::Atom(module_name, _)),
|
||||||
|
Term::Clause(_, name, terms, fixity),
|
||||||
|
) => Ok(qualified_clause_to_query_term(
|
||||||
|
load_state,
|
||||||
|
module_name,
|
||||||
|
name,
|
||||||
|
terms,
|
||||||
|
fixity,
|
||||||
|
)),
|
||||||
|
(module_name, predicate_name) => {
|
||||||
|
terms.push(Box::new(module_name));
|
||||||
|
terms.push(Box::new(predicate_name));
|
||||||
|
|
||||||
|
Ok(clause_to_query_term(load_state, name, terms, fixity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Ok(clause_to_query_term(load_state, name, terms, fixity)),
|
||||||
|
},
|
||||||
|
Term::Var(..) => Ok(QueryTerm::Clause(
|
||||||
|
Cell::default(),
|
||||||
|
ClauseType::CallN,
|
||||||
|
vec![Box::new(term)],
|
||||||
|
false,
|
||||||
|
)),
|
||||||
|
_ => Err(CompilationError::InadmissibleQueryTerm),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,9 +783,7 @@ impl Preprocessor {
|
|||||||
self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity))
|
self.to_query_term(load_state, Term::Clause(r, name, subterms, fixity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => self.to_query_term(load_state, term),
|
||||||
self.to_query_term(load_state, term)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -884,30 +830,23 @@ impl Preprocessor {
|
|||||||
mut terms: Vec<Box<Term>>,
|
mut terms: Vec<Box<Term>>,
|
||||||
cut_context: CutContext,
|
cut_context: CutContext,
|
||||||
) -> Result<Rule, CompilationError> {
|
) -> Result<Rule, CompilationError> {
|
||||||
let post_head_terms: Vec<_> = terms.drain(1 ..).collect();
|
let post_head_terms: Vec<_> = terms.drain(1..).collect();
|
||||||
|
|
||||||
let mut query_terms =
|
let mut query_terms = self.setup_query(load_state, post_head_terms, cut_context)?;
|
||||||
self.setup_query(load_state, post_head_terms, cut_context)?;
|
|
||||||
|
|
||||||
let clauses = query_terms.drain(1 ..).collect();
|
let clauses = query_terms.drain(1..).collect();
|
||||||
let qt = query_terms.pop().unwrap();
|
let qt = query_terms.pop().unwrap();
|
||||||
|
|
||||||
match *terms.pop().unwrap() {
|
match *terms.pop().unwrap() {
|
||||||
Term::Clause(_, name, terms, _) => {
|
Term::Clause(_, name, terms, _) => Ok(Rule {
|
||||||
Ok(Rule {
|
head: (name, terms, qt),
|
||||||
head: (name, terms, qt),
|
clauses,
|
||||||
clauses,
|
}),
|
||||||
})
|
Term::Constant(_, Constant::Atom(name, _)) => Ok(Rule {
|
||||||
}
|
head: (name, vec![], qt),
|
||||||
Term::Constant(_, Constant::Atom(name, _)) => {
|
clauses,
|
||||||
Ok(Rule {
|
}),
|
||||||
head: (name, vec![], qt),
|
_ => Err(CompilationError::InvalidRuleHead),
|
||||||
clauses,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
Err(CompilationError::InvalidRuleHead)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,11 +856,14 @@ impl Preprocessor {
|
|||||||
terms: Vec<Box<Term>>,
|
terms: Vec<Box<Term>>,
|
||||||
cut_context: CutContext,
|
cut_context: CutContext,
|
||||||
) -> Result<TopLevel, CompilationError> {
|
) -> Result<TopLevel, CompilationError> {
|
||||||
Ok(TopLevel::Query(self.setup_query(load_state, terms, cut_context)?))
|
Ok(TopLevel::Query(self.setup_query(
|
||||||
|
load_state,
|
||||||
|
terms,
|
||||||
|
cut_context,
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn try_term_to_tl<'a>(
|
||||||
fn try_term_to_tl<'a>(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
load_state: &mut LoadState<'a>,
|
load_state: &mut LoadState<'a>,
|
||||||
term: Term,
|
term: Term,
|
||||||
@@ -944,9 +886,7 @@ impl Preprocessor {
|
|||||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
term => {
|
term => Ok(TopLevel::Fact(self.setup_fact(term)?)),
|
||||||
Ok(TopLevel::Fact(self.setup_fact(term)?))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -965,21 +905,18 @@ impl Preprocessor {
|
|||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super)
|
pub(super) fn parse_queue<'a>(
|
||||||
fn parse_queue<'a>(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
load_state: &mut LoadState<'a>,
|
load_state: &mut LoadState<'a>,
|
||||||
) -> Result<VecDeque<TopLevel>, CompilationError> {
|
) -> Result<VecDeque<TopLevel>, CompilationError> {
|
||||||
let mut queue = VecDeque::new();
|
let mut queue = VecDeque::new();
|
||||||
|
|
||||||
while let Some(terms) = self.queue.pop_front() {
|
while let Some(terms) = self.queue.pop_front() {
|
||||||
let clauses = merge_clauses(
|
let clauses = merge_clauses(&mut self.try_terms_to_tls(
|
||||||
&mut self.try_terms_to_tls(
|
load_state,
|
||||||
load_state,
|
terms,
|
||||||
terms,
|
CutContext::HasCutVariable,
|
||||||
CutContext::HasCutVariable,
|
)?)?;
|
||||||
)?
|
|
||||||
)?;
|
|
||||||
|
|
||||||
queue.push_back(clauses);
|
queue.push_back(clauses);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,16 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::parser::*;
|
use prolog_parser::parser::*;
|
||||||
|
|
||||||
use crate::machine::*;
|
|
||||||
use crate::machine::machine_errors::CompilationError;
|
use crate::machine::machine_errors::CompilationError;
|
||||||
use crate::machine::preprocessor::*;
|
use crate::machine::preprocessor::*;
|
||||||
|
use crate::machine::*;
|
||||||
|
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub(crate) trait TermStream : Sized {
|
pub(crate) trait TermStream: Sized {
|
||||||
type Evacuable;
|
type Evacuable;
|
||||||
|
|
||||||
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError>;
|
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError>;
|
||||||
@@ -27,15 +27,17 @@ pub(super) struct BootstrappingTermStream<'a> {
|
|||||||
|
|
||||||
impl<'a> BootstrappingTermStream<'a> {
|
impl<'a> BootstrappingTermStream<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn from_prolog_stream(
|
||||||
fn from_prolog_stream(
|
|
||||||
stream: &'a mut PrologStream,
|
stream: &'a mut PrologStream,
|
||||||
atom_tbl: TabledData<Atom>,
|
atom_tbl: TabledData<Atom>,
|
||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
listing_src: ListingSource,
|
listing_src: ListingSource,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let parser = Parser::new(stream, atom_tbl, flags);
|
let parser = Parser::new(stream, atom_tbl, flags);
|
||||||
Self { parser, listing_src }
|
Self {
|
||||||
|
parser,
|
||||||
|
listing_src,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,13 +47,14 @@ impl<'a> TermStream for BootstrappingTermStream<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError> {
|
fn next(&mut self, op_dir: &CompositeOpDir) -> Result<Term, CompilationError> {
|
||||||
self.parser.reset();
|
self.parser.reset();
|
||||||
self.parser.read_term(op_dir)
|
self.parser
|
||||||
|
.read_term(op_dir)
|
||||||
.map_err(CompilationError::from)
|
.map_err(CompilationError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eof(&mut self) -> Result<bool, CompilationError> {
|
fn eof(&mut self) -> Result<bool, CompilationError> {
|
||||||
self.parser.devour_whitespace()?; // eliminate dangling comments before checking for EOF.
|
self.parser.devour_whitespace()?; // eliminate dangling comments before checking for EOF.
|
||||||
Ok(self.parser.eof()?)
|
Ok(self.parser.eof()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,9 +68,10 @@ impl<'a> TermStream for BootstrappingTermStream<'a> {
|
|||||||
loader.compile_and_submit()?;
|
loader.compile_and_submit()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
loader.load_state.retraction_info.reset(
|
loader
|
||||||
loader.load_state.wam.code_repo.code.len(),
|
.load_state
|
||||||
);
|
.retraction_info
|
||||||
|
.reset(loader.load_state.wam.code_repo.code.len());
|
||||||
|
|
||||||
loader.load_state.remove_module_op_exports();
|
loader.load_state.remove_module_op_exports();
|
||||||
|
|
||||||
@@ -82,8 +86,7 @@ pub struct LiveTermStream {
|
|||||||
|
|
||||||
impl LiveTermStream {
|
impl LiveTermStream {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super)
|
pub(super) fn new(listing_src: ListingSource) -> Self {
|
||||||
fn new(listing_src: ListingSource) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
term_queue: VecDeque::new(),
|
term_queue: VecDeque::new(),
|
||||||
listing_src,
|
listing_src,
|
||||||
@@ -109,8 +112,7 @@ impl fmt::Debug for LoadStatePayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LoadStatePayload {
|
impl LoadStatePayload {
|
||||||
pub(super)
|
pub(super) fn new(wam: &Machine) -> Self {
|
||||||
fn new(wam: &Machine) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
term_stream: LiveTermStream::new(ListingSource::User),
|
term_stream: LiveTermStream::new(ListingSource::User),
|
||||||
compilation_target: CompilationTarget::default(),
|
compilation_target: CompilationTarget::default(),
|
||||||
|
|||||||
43
src/main.rs
43
src/main.rs
@@ -1,43 +1,14 @@
|
|||||||
extern crate blake2;
|
|
||||||
extern crate chrono;
|
|
||||||
extern crate cpu_time;
|
|
||||||
extern crate crossterm;
|
|
||||||
extern crate divrem;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate downcast;
|
|
||||||
extern crate git_version;
|
|
||||||
extern crate hostname;
|
|
||||||
extern crate indexmap;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
extern crate libc;
|
|
||||||
extern crate native_tls;
|
|
||||||
extern crate nix;
|
|
||||||
extern crate openssl;
|
|
||||||
extern crate ordered_float;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate prolog_parser_rebis;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate ref_thread_local;
|
|
||||||
extern crate ring;
|
|
||||||
extern crate ripemd160;
|
|
||||||
#[cfg(feature = "rug")]
|
|
||||||
extern crate rug;
|
|
||||||
#[cfg(feature = "num-rug-adapter")]
|
#[cfg(feature = "num-rug-adapter")]
|
||||||
extern crate num_rug_adapter as rug;
|
use num_rug_adapter as rug;
|
||||||
extern crate rustyline;
|
#[cfg(feature = "rug")]
|
||||||
extern crate sha3;
|
use rug;
|
||||||
extern crate unicode_reader;
|
|
||||||
|
|
||||||
use crate::nix::sys::signal;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
mod allocator;
|
mod allocator;
|
||||||
mod arithmetic;
|
mod arithmetic;
|
||||||
mod machine;
|
|
||||||
mod codegen;
|
|
||||||
mod clause_types;
|
mod clause_types;
|
||||||
|
mod codegen;
|
||||||
mod debray_allocator;
|
mod debray_allocator;
|
||||||
mod fixtures;
|
mod fixtures;
|
||||||
mod forms;
|
mod forms;
|
||||||
@@ -46,17 +17,19 @@ mod heap_print;
|
|||||||
mod indexing;
|
mod indexing;
|
||||||
mod instructions;
|
mod instructions;
|
||||||
mod iterators;
|
mod iterators;
|
||||||
|
mod machine;
|
||||||
mod read;
|
mod read;
|
||||||
mod targets;
|
mod targets;
|
||||||
mod write;
|
mod write;
|
||||||
|
|
||||||
use machine::*;
|
|
||||||
use machine::streams::*;
|
use machine::streams::*;
|
||||||
|
use machine::*;
|
||||||
use read::*;
|
use read::*;
|
||||||
|
|
||||||
|
use nix::sys::signal;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
extern fn handle_sigint(signal: libc::c_int) {
|
extern "C" fn handle_sigint(signal: libc::c_int) {
|
||||||
let signal = signal::Signal::from_c_int(signal).unwrap();
|
let signal = signal::Signal::from_c_int(signal).unwrap();
|
||||||
if signal == signal::Signal::SIGINT {
|
if signal == signal::Signal::SIGINT {
|
||||||
INTERRUPT.store(true, Ordering::Relaxed);
|
INTERRUPT.store(true, Ordering::Relaxed);
|
||||||
|
|||||||
129
src/read.rs
129
src/read.rs
@@ -1,6 +1,6 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use crate::prolog_parser_rebis::parser::*;
|
use prolog_parser::parser::*;
|
||||||
use crate::prolog_parser_rebis::tabled_rc::TabledData;
|
use prolog_parser::tabled_rc::TabledData;
|
||||||
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::iterators::*;
|
use crate::iterators::*;
|
||||||
@@ -16,8 +16,8 @@ pub type PrologStream = ParsingStream<Stream>;
|
|||||||
|
|
||||||
pub mod readline {
|
pub mod readline {
|
||||||
use crate::machine::streams::Stream;
|
use crate::machine::streams::Stream;
|
||||||
use crate::rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
use crate::rustyline::{Cmd, Editor, KeyEvent};
|
use rustyline::{Cmd, Config, Editor, KeyEvent};
|
||||||
use std::io::{Cursor, Error, ErrorKind, Read};
|
use std::io::{Cursor, Error, ErrorKind, Read};
|
||||||
|
|
||||||
static mut PROMPT: bool = false;
|
static mut PROMPT: bool = false;
|
||||||
@@ -33,7 +33,11 @@ pub mod readline {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn get_prompt() -> &'static str {
|
fn get_prompt() -> &'static str {
|
||||||
unsafe {
|
unsafe {
|
||||||
if PROMPT { "?- " } else { "" }
|
if PROMPT {
|
||||||
|
"?- "
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +50,11 @@ pub mod readline {
|
|||||||
impl ReadlineStream {
|
impl ReadlineStream {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(pending_input: String) -> Self {
|
pub fn new(pending_input: String) -> Self {
|
||||||
let mut rl = Editor::<()>::new();
|
let config = Config::builder()
|
||||||
|
.check_cursor_position(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let mut rl = Editor::<()>::with_config(config); //Editor::<()>::new();
|
||||||
if let Some(mut path) = dirs_next::home_dir() {
|
if let Some(mut path) = dirs_next::home_dir() {
|
||||||
path.push(HISTORY_FILE);
|
path.push(HISTORY_FILE);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
@@ -57,7 +65,10 @@ pub mod readline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rl.bind_sequence(KeyEvent::from('\t'), Cmd::Insert(1, "\t".to_string()));
|
rl.bind_sequence(KeyEvent::from('\t'), Cmd::Insert(1, "\t".to_string()));
|
||||||
ReadlineStream { rl, pending_input: Cursor::new(pending_input) }
|
ReadlineStream {
|
||||||
|
rl,
|
||||||
|
pending_input: Cursor::new(pending_input),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -85,12 +96,8 @@ pub mod readline {
|
|||||||
|
|
||||||
self.pending_input.read(buf)
|
self.pending_input.read(buf)
|
||||||
}
|
}
|
||||||
Err(ReadlineError::Eof) => {
|
Err(ReadlineError::Eof) => Ok(0),
|
||||||
Ok(0)
|
Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)),
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
Err(Error::new(ErrorKind::InvalidInput, e))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,21 +124,15 @@ pub mod readline {
|
|||||||
Some(b) => {
|
Some(b) => {
|
||||||
return Ok(b);
|
return Ok(b);
|
||||||
}
|
}
|
||||||
None => {
|
None => match self.call_readline(&mut []) {
|
||||||
match self.call_readline(&mut []) {
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(e);
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
Ok(0) => {
|
|
||||||
return Err(Error::new(
|
|
||||||
ErrorKind::UnexpectedEof,
|
|
||||||
"end of file",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
Ok(0) => {
|
||||||
|
return Err(Error::new(ErrorKind::UnexpectedEof, "end of file"));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,21 +145,15 @@ pub mod readline {
|
|||||||
Some(c) => {
|
Some(c) => {
|
||||||
return Ok(c);
|
return Ok(c);
|
||||||
}
|
}
|
||||||
None => {
|
None => match self.call_readline(&mut []) {
|
||||||
match self.call_readline(&mut []) {
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(e);
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
Ok(0) => {
|
|
||||||
return Err(Error::new(
|
|
||||||
ErrorKind::UnexpectedEof,
|
|
||||||
"end of file",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
Ok(0) => {
|
||||||
|
return Err(Error::new(ErrorKind::UnexpectedEof, "end of file"));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,12 +162,8 @@ pub mod readline {
|
|||||||
impl Read for ReadlineStream {
|
impl Read for ReadlineStream {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
match self.pending_input.read(buf) {
|
match self.pending_input.read(buf) {
|
||||||
Ok(0) => {
|
Ok(0) => self.call_readline(buf),
|
||||||
self.call_readline(buf)
|
result => result,
|
||||||
}
|
|
||||||
result => {
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,8 +201,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate)
|
pub(crate) fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
|
||||||
fn write_term_to_heap(term: &Term, machine_st: &mut MachineState) -> TermWriteResult {
|
|
||||||
let term_writer = TermWriter::new(machine_st);
|
let term_writer = TermWriter::new(machine_st);
|
||||||
term_writer.write_term_to_heap(term)
|
term_writer.write_term_to_heap(term)
|
||||||
}
|
}
|
||||||
@@ -242,8 +232,7 @@ impl<'a> TermWriter<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn modify_head_of_queue(&mut self, term: &TermRef<'a>, h: usize) {
|
fn modify_head_of_queue(&mut self, term: &TermRef<'a>, h: usize) {
|
||||||
if let Some((arity, site_h)) = self.queue.pop_front() {
|
if let Some((arity, site_h)) = self.queue.pop_front() {
|
||||||
self.machine_st.heap[site_h] =
|
self.machine_st.heap[site_h] = HeapCellValue::Addr(self.term_as_addr(term, h));
|
||||||
HeapCellValue::Addr(self.term_as_addr(term, h));
|
|
||||||
|
|
||||||
if arity > 1 {
|
if arity > 1 {
|
||||||
self.queue.push_front((arity - 1, site_h + 1));
|
self.queue.push_front((arity - 1, site_h + 1));
|
||||||
@@ -254,26 +243,18 @@ impl<'a> TermWriter<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn push_stub_addr(&mut self) {
|
fn push_stub_addr(&mut self) {
|
||||||
let h = self.machine_st.heap.h();
|
let h = self.machine_st.heap.h();
|
||||||
self.machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
self.machine_st
|
||||||
|
.heap
|
||||||
|
.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn term_as_addr(&mut self, term: &TermRef<'a>, h: usize) -> Addr {
|
fn term_as_addr(&mut self, term: &TermRef<'a>, h: usize) -> Addr {
|
||||||
match term {
|
match term {
|
||||||
&TermRef::AnonVar(_) | &TermRef::Var(..) => {
|
&TermRef::AnonVar(_) | &TermRef::Var(..) => Addr::HeapCell(h),
|
||||||
Addr::HeapCell(h)
|
&TermRef::Cons(..) => Addr::HeapCell(h),
|
||||||
}
|
&TermRef::Constant(_, _, c) => self.machine_st.heap.put_constant(c.clone()),
|
||||||
&TermRef::Cons(..) => {
|
&TermRef::Clause(..) => Addr::Str(h),
|
||||||
Addr::HeapCell(h)
|
&TermRef::PartialString(..) => Addr::PStrLocation(h, 0),
|
||||||
}
|
|
||||||
&TermRef::Constant(_, _, c) => {
|
|
||||||
self.machine_st.heap.put_constant(c.clone())
|
|
||||||
}
|
|
||||||
&TermRef::Clause(..) => {
|
|
||||||
Addr::Str(h)
|
|
||||||
}
|
|
||||||
&TermRef::PartialString(..) => {
|
|
||||||
Addr::PStrLocation(h, 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +267,9 @@ impl<'a> TermWriter<'a> {
|
|||||||
match &term {
|
match &term {
|
||||||
&TermRef::Cons(lvl, ..) => {
|
&TermRef::Cons(lvl, ..) => {
|
||||||
self.queue.push_back((2, h + 1));
|
self.queue.push_back((2, h + 1));
|
||||||
self.machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
self.machine_st
|
||||||
|
.heap
|
||||||
|
.push(HeapCellValue::Addr(Addr::Lis(h + 1)));
|
||||||
|
|
||||||
self.push_stub_addr();
|
self.push_stub_addr();
|
||||||
self.push_stub_addr();
|
self.push_stub_addr();
|
||||||
@@ -355,13 +338,15 @@ impl<'a> TermWriter<'a> {
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.modify_head_of_queue(&term, h);
|
self.modify_head_of_queue(&term, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
TermWriteResult { heap_loc, var_dict: self.var_dict }
|
TermWriteResult {
|
||||||
|
heap_loc,
|
||||||
|
var_dict: self.var_dict,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::prolog_parser_rebis::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
|
||||||
use crate::clause_types::*;
|
use crate::clause_types::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
:- module('$toplevel', [argv/1,
|
:- module('$toplevel', [argv/1,
|
||||||
copy_term/3,
|
copy_term/3]).
|
||||||
predicate_property/2,
|
|
||||||
prolog_load_context/2]).
|
|
||||||
|
|
||||||
:- use_module(library(loader)).
|
|
||||||
|
|
||||||
:- use_module(library(charsio)).
|
:- use_module(library(charsio)).
|
||||||
:- use_module(library(iso_ext)).
|
:- use_module(library(iso_ext)).
|
||||||
@@ -18,15 +14,15 @@
|
|||||||
'$repl'([_|Args0]) :-
|
'$repl'([_|Args0]) :-
|
||||||
\+ argv(_),
|
\+ argv(_),
|
||||||
( append(Args1, ["--"|Args2], Args0) ->
|
( append(Args1, ["--"|Args2], Args0) ->
|
||||||
asserta(argv(Args2)),
|
asserta('$toplevel':argv(Args2)),
|
||||||
Args = Args1
|
Args = Args1
|
||||||
; asserta(argv([])),
|
; asserta('$toplevel':argv([])),
|
||||||
Args = Args0
|
Args = Args0
|
||||||
),
|
),
|
||||||
delegate_task(Args, []),
|
delegate_task(Args, []),
|
||||||
repl.
|
repl.
|
||||||
'$repl'(_) :-
|
'$repl'(_) :-
|
||||||
( \+ argv(_) -> asserta(argv([]))
|
( \+ argv(_) -> asserta('$toplevel':argv([]))
|
||||||
; true
|
; true
|
||||||
),
|
),
|
||||||
repl.
|
repl.
|
||||||
@@ -41,7 +37,8 @@ delegate_task([Arg0|Args], Goals0) :-
|
|||||||
; member(Arg0, ["-v", "--version"]) -> print_version
|
; member(Arg0, ["-v", "--version"]) -> print_version
|
||||||
; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0)
|
; member(Arg0, ["-g", "--goal"]) -> gather_goal(g, Args, Goals0)
|
||||||
; atom_chars(Mod, Arg0),
|
; atom_chars(Mod, Arg0),
|
||||||
catch(use_module(Mod), E, print_exception(E))
|
catch(use_module(Mod), E, print_exception(E)),
|
||||||
|
nl
|
||||||
),
|
),
|
||||||
delegate_task(Args, Goals0).
|
delegate_task(Args, Goals0).
|
||||||
|
|
||||||
@@ -126,7 +123,7 @@ instruction_match(Term, VarList) :-
|
|||||||
( Item == user ->
|
( Item == user ->
|
||||||
catch(load(user_input), E, print_exception_with_check(E))
|
catch(load(user_input), E, print_exception_with_check(E))
|
||||||
;
|
;
|
||||||
consult(Item)
|
submit_query_and_print_results(consult(Item), [])
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
catch(type_error(atom, Item, repl/0),
|
catch(type_error(atom, Item, repl/0),
|
||||||
|
|||||||
44
src/write.rs
44
src/write.rs
@@ -26,14 +26,14 @@ impl fmt::Display for REPLCodePtr {
|
|||||||
write!(f, "REPLCodePtr::AddGoalExpansionClause"),
|
write!(f, "REPLCodePtr::AddGoalExpansionClause"),
|
||||||
REPLCodePtr::AddTermExpansionClause =>
|
REPLCodePtr::AddTermExpansionClause =>
|
||||||
write!(f, "REPLCodePtr::AddTermExpansionClause"),
|
write!(f, "REPLCodePtr::AddTermExpansionClause"),
|
||||||
REPLCodePtr::BuiltInProperty =>
|
REPLCodePtr::AbolishClause =>
|
||||||
write!(f, "REPLCodePtr::BuiltInProperty"),
|
write!(f, "REPLCodePtr::AbolishClause"),
|
||||||
REPLCodePtr::UserAssertz =>
|
REPLCodePtr::Assertz =>
|
||||||
write!(f, "REPLCodePtr::UserAssertz"),
|
write!(f, "REPLCodePtr::Assertz"),
|
||||||
REPLCodePtr::UserAsserta =>
|
REPLCodePtr::Asserta =>
|
||||||
write!(f, "REPLCodePtr::UserAsserta"),
|
write!(f, "REPLCodePtr::Asserta"),
|
||||||
REPLCodePtr::UserRetract =>
|
REPLCodePtr::Retract =>
|
||||||
write!(f, "REPLCodePtr::UserRetract"),
|
write!(f, "REPLCodePtr::Retract"),
|
||||||
REPLCodePtr::ClauseToEvacuable =>
|
REPLCodePtr::ClauseToEvacuable =>
|
||||||
write!(f, "REPLCodePtr::ClauseToEvacuable"),
|
write!(f, "REPLCodePtr::ClauseToEvacuable"),
|
||||||
REPLCodePtr::ConcludeLoad =>
|
REPLCodePtr::ConcludeLoad =>
|
||||||
@@ -64,8 +64,14 @@ impl fmt::Display for REPLCodePtr {
|
|||||||
write!(f, "REPLCodePtr::UseModule"),
|
write!(f, "REPLCodePtr::UseModule"),
|
||||||
REPLCodePtr::MetaPredicateProperty =>
|
REPLCodePtr::MetaPredicateProperty =>
|
||||||
write!(f, "REPLCodePtr::MetaPredicateProperty"),
|
write!(f, "REPLCodePtr::MetaPredicateProperty"),
|
||||||
REPLCodePtr::CompilePendingPredicates =>
|
REPLCodePtr::BuiltInProperty =>
|
||||||
write!(f, "REPLCodePtr::CompilePendingPredicates"),
|
write!(f, "REPLCodePtr::BuiltInProperty"),
|
||||||
|
REPLCodePtr::DynamicProperty =>
|
||||||
|
write!(f, "REPLCodePtr::DynamicProperty"),
|
||||||
|
REPLCodePtr::MultifileProperty =>
|
||||||
|
write!(f, "REPLCodePtr::MultifileProperty"),
|
||||||
|
REPLCodePtr::DiscontiguousProperty =>
|
||||||
|
write!(f, "REPLCodePtr::DiscontiguousProperty"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,15 +377,15 @@ impl fmt::Display for SessionError {
|
|||||||
// &SessionError::InvalidFileName(ref filename) => {
|
// &SessionError::InvalidFileName(ref filename) => {
|
||||||
// write!(f, "filename {} is invalid", filename)
|
// write!(f, "filename {} is invalid", filename)
|
||||||
// }
|
// }
|
||||||
// &SessionError::ModuleDoesNotContainExport(ref module, ref key) => {
|
&SessionError::ModuleDoesNotContainExport(ref module, ref key) => {
|
||||||
// write!(
|
write!(
|
||||||
// f,
|
f,
|
||||||
// "module {} does not contain claimed export {}/{}",
|
"module {} does not contain claimed export {}/{}",
|
||||||
// module,
|
module,
|
||||||
// key.0,
|
key.0,
|
||||||
// key.1,
|
key.1,
|
||||||
// )
|
)
|
||||||
// }
|
}
|
||||||
&SessionError::OpIsInfixAndPostFix(_) => {
|
&SessionError::OpIsInfixAndPostFix(_) => {
|
||||||
write!(f, "cannot define an op to be both postfix and infix.")
|
write!(f, "cannot define an op to be both postfix and infix.")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user