remove partial strings, but represent strings as lists when warranted by double_quotes
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -316,8 +316,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.8.39"
|
version = "0.8.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -453,7 +452,7 @@ dependencies = [
|
|||||||
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.8.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prolog_parser 0.8.40",
|
||||||
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -614,7 +613,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
||||||
"checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d"
|
"checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
"checksum prolog_parser 0.8.39 (registry+https://github.com/rust-lang/crates.io-index)" = "021e4a08146013070183a4289404a0a5b8e14e1ea7df80d859e06ea98f67976b"
|
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ libc = "0.2.62"
|
|||||||
nix = "0.15.0"
|
nix = "0.15.0"
|
||||||
num-rug-adapter = { optional = true, version = "0.1.1" }
|
num-rug-adapter = { optional = true, version = "0.1.1" }
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = { version = "0.8.39", default-features = false }
|
prolog_parser = { version = "0.8.40", path = "../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 = "5.0.3"
|
rustyline = "5.0.3"
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ pub enum InlinedClauseType {
|
|||||||
IsString(RegType),
|
IsString(RegType),
|
||||||
IsFloat(RegType),
|
IsFloat(RegType),
|
||||||
IsNonVar(RegType),
|
IsNonVar(RegType),
|
||||||
IsPartialString(RegType),
|
|
||||||
IsVar(RegType),
|
IsVar(RegType),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +108,6 @@ ref_thread_local! {
|
|||||||
m.insert(("string", 1), ClauseType::Inlined(InlinedClauseType::IsString(r1)));
|
m.insert(("string", 1), ClauseType::Inlined(InlinedClauseType::IsString(r1)));
|
||||||
m.insert(("float", 1), ClauseType::Inlined(InlinedClauseType::IsFloat(r1)));
|
m.insert(("float", 1), ClauseType::Inlined(InlinedClauseType::IsFloat(r1)));
|
||||||
m.insert(("nonvar", 1), ClauseType::Inlined(InlinedClauseType::IsNonVar(r1)));
|
m.insert(("nonvar", 1), ClauseType::Inlined(InlinedClauseType::IsNonVar(r1)));
|
||||||
m.insert(("is_partial_string", 1), ClauseType::Inlined(InlinedClauseType::IsPartialString(r1)));
|
|
||||||
m.insert(("var", 1), ClauseType::Inlined(InlinedClauseType::IsVar(r1)));
|
m.insert(("var", 1), ClauseType::Inlined(InlinedClauseType::IsVar(r1)));
|
||||||
m.insert(("acyclic_term", 1), ClauseType::BuiltIn(BuiltInClauseType::AcyclicTerm));
|
m.insert(("acyclic_term", 1), ClauseType::BuiltIn(BuiltInClauseType::AcyclicTerm));
|
||||||
m.insert(("arg", 3), ClauseType::BuiltIn(BuiltInClauseType::Arg));
|
m.insert(("arg", 3), ClauseType::BuiltIn(BuiltInClauseType::Arg));
|
||||||
@@ -127,7 +125,6 @@ ref_thread_local! {
|
|||||||
m.insert(("keysort", 2), ClauseType::BuiltIn(BuiltInClauseType::KeySort));
|
m.insert(("keysort", 2), ClauseType::BuiltIn(BuiltInClauseType::KeySort));
|
||||||
m.insert(("nl", 0), ClauseType::BuiltIn(BuiltInClauseType::Nl));
|
m.insert(("nl", 0), ClauseType::BuiltIn(BuiltInClauseType::Nl));
|
||||||
m.insert(("\\==", 2), ClauseType::BuiltIn(BuiltInClauseType::NotEq));
|
m.insert(("\\==", 2), ClauseType::BuiltIn(BuiltInClauseType::NotEq));
|
||||||
m.insert(("partial_string", 2), ClauseType::BuiltIn(BuiltInClauseType::PartialString));
|
|
||||||
m.insert(("read", 1), ClauseType::BuiltIn(BuiltInClauseType::Read));
|
m.insert(("read", 1), ClauseType::BuiltIn(BuiltInClauseType::Read));
|
||||||
m.insert(("sort", 2), ClauseType::BuiltIn(BuiltInClauseType::Sort));
|
m.insert(("sort", 2), ClauseType::BuiltIn(BuiltInClauseType::Sort));
|
||||||
|
|
||||||
@@ -147,7 +144,6 @@ impl InlinedClauseType {
|
|||||||
&InlinedClauseType::IsString(..) => "string",
|
&InlinedClauseType::IsString(..) => "string",
|
||||||
&InlinedClauseType::IsFloat(..) => "float",
|
&InlinedClauseType::IsFloat(..) => "float",
|
||||||
&InlinedClauseType::IsNonVar(..) => "nonvar",
|
&InlinedClauseType::IsNonVar(..) => "nonvar",
|
||||||
&InlinedClauseType::IsPartialString(..) => "is_partial_string",
|
|
||||||
&InlinedClauseType::IsVar(..) => "var",
|
&InlinedClauseType::IsVar(..) => "var",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,7 +541,6 @@ pub enum BuiltInClauseType {
|
|||||||
KeySort,
|
KeySort,
|
||||||
Nl,
|
Nl,
|
||||||
NotEq,
|
NotEq,
|
||||||
PartialString,
|
|
||||||
Read,
|
Read,
|
||||||
Sort,
|
Sort,
|
||||||
}
|
}
|
||||||
@@ -577,7 +572,6 @@ impl BuiltInClauseType {
|
|||||||
&BuiltInClauseType::KeySort => clause_name!("keysort"),
|
&BuiltInClauseType::KeySort => clause_name!("keysort"),
|
||||||
&BuiltInClauseType::Nl => clause_name!("nl"),
|
&BuiltInClauseType::Nl => clause_name!("nl"),
|
||||||
&BuiltInClauseType::NotEq => clause_name!("\\=="),
|
&BuiltInClauseType::NotEq => clause_name!("\\=="),
|
||||||
&BuiltInClauseType::PartialString => clause_name!("partial_string"),
|
|
||||||
&BuiltInClauseType::Read => clause_name!("read"),
|
&BuiltInClauseType::Read => clause_name!("read"),
|
||||||
&BuiltInClauseType::Sort => clause_name!("sort"),
|
&BuiltInClauseType::Sort => clause_name!("sort"),
|
||||||
}
|
}
|
||||||
@@ -598,7 +592,6 @@ impl BuiltInClauseType {
|
|||||||
&BuiltInClauseType::KeySort => 2,
|
&BuiltInClauseType::KeySort => 2,
|
||||||
&BuiltInClauseType::NotEq => 2,
|
&BuiltInClauseType::NotEq => 2,
|
||||||
&BuiltInClauseType::Nl => 0,
|
&BuiltInClauseType::Nl => 0,
|
||||||
&BuiltInClauseType::PartialString => 1,
|
|
||||||
&BuiltInClauseType::Read => 1,
|
&BuiltInClauseType::Read => 1,
|
||||||
&BuiltInClauseType::Sort => 2,
|
&BuiltInClauseType::Sort => 2,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ use std::rc::Rc;
|
|||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
pub struct CodeGenerator<TermMarker> {
|
pub struct CodeGenerator<TermMarker> {
|
||||||
flags: MachineFlags,
|
|
||||||
marker: TermMarker,
|
marker: TermMarker,
|
||||||
pub var_count: IndexMap<Rc<Var>, usize>,
|
pub var_count: IndexMap<Rc<Var>, usize>,
|
||||||
non_counted_bt: bool,
|
non_counted_bt: bool,
|
||||||
@@ -107,12 +106,11 @@ impl<'a> ConjunctInfo<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
||||||
pub fn new(non_counted_bt: bool, flags: MachineFlags) -> Self {
|
pub fn new(non_counted_bt: bool) -> Self {
|
||||||
CodeGenerator {
|
CodeGenerator {
|
||||||
marker: Allocator::new(),
|
marker: Allocator::new(),
|
||||||
var_count: IndexMap::new(),
|
var_count: IndexMap::new(),
|
||||||
non_counted_bt,
|
non_counted_bt,
|
||||||
flags,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,7 +433,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsString(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsString(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::String(_)) => {
|
&Term::Constant(_, Constant::String(..)) => {
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -459,8 +457,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
|
||||||
&Term::Constant(_, Constant::CharCode(_))
|
&Term::Constant(_, Constant::Integer(_)) => {
|
||||||
| &Term::Constant(_, Constant::Integer(_)) => {
|
|
||||||
code.push(succeed!());
|
code.push(succeed!());
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
@@ -483,13 +480,6 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
code.push(is_var!(r));
|
code.push(is_var!(r));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsPartialString(..) => match terms[0].as_ref() {
|
|
||||||
&Term::Var(ref vr, ref name) => {
|
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
code.push(is_partial_string!(r));
|
|
||||||
}
|
|
||||||
_ => code.push(fail!()),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -867,7 +857,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
|
|||||||
clauses: &'b [PredicateClause],
|
clauses: &'b [PredicateClause],
|
||||||
) -> Result<Code, ParserError> {
|
) -> Result<Code, ParserError> {
|
||||||
let mut code_body = Vec::new();
|
let mut code_body = Vec::new();
|
||||||
let mut code_offsets = CodeOffsets::new(self.flags);
|
let mut code_offsets = CodeOffsets::new();
|
||||||
|
|
||||||
let num_clauses = clauses.len();
|
let num_clauses = clauses.len();
|
||||||
|
|
||||||
|
|||||||
@@ -46,39 +46,42 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
let da = self.machine_st.store(self.machine_st.deref(addr));
|
let da = self.machine_st.store(self.machine_st.deref(addr));
|
||||||
|
|
||||||
match da {
|
match da {
|
||||||
Addr::Con(Constant::String(ref s)) => {
|
Addr::Con(Constant::String(n, s)) => {
|
||||||
match self.machine_st.machine_flags().double_quotes {
|
if !self.machine_st.machine_flags().double_quotes.is_atom() {
|
||||||
DoubleQuotes::Chars => {
|
if s.len() > n {
|
||||||
if let Some(c) = s.head() {
|
if let Some(c) = s[n ..].chars().next() {
|
||||||
let tail = s.tail();
|
let o = c.len_utf8();
|
||||||
|
|
||||||
|
self.state_stack.push(Addr::Con(Constant::String(n+o, s.clone())));
|
||||||
|
|
||||||
self.state_stack.push(Addr::Con(Constant::String(tail)));
|
if self.machine_st.machine_flags().double_quotes.is_codes() {
|
||||||
self.state_stack.push(Addr::Con(Constant::Char(c)));
|
self.state_stack.push(Addr::Con(Constant::CharCode(c as u32)));
|
||||||
|
} else {
|
||||||
|
self.state_stack.push(Addr::Con(Constant::Char(c)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return Addr::Con(Constant::EmptyList);
|
||||||
}
|
}
|
||||||
DoubleQuotes::Codes => {
|
|
||||||
if let Some(c) = s.head() {
|
|
||||||
let tail = s.tail();
|
|
||||||
|
|
||||||
self.state_stack.push(Addr::Con(Constant::String(tail)));
|
|
||||||
self.state_stack
|
|
||||||
.push(Addr::Con(Constant::CharCode(c as u8)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr::Con(Constant::String(s.clone()))
|
Addr::Con(Constant::String(n, s))
|
||||||
|
}
|
||||||
|
Addr::Con(_) | Addr::DBRef(_) => {
|
||||||
|
da
|
||||||
}
|
}
|
||||||
Addr::Con(_) | Addr::DBRef(_) => da,
|
|
||||||
Addr::Lis(a) => {
|
Addr::Lis(a) => {
|
||||||
self.state_stack.push(Addr::HeapCell(a + 1));
|
self.state_stack.push(Addr::HeapCell(a + 1));
|
||||||
self.state_stack.push(Addr::HeapCell(a));
|
self.state_stack.push(Addr::HeapCell(a));
|
||||||
|
|
||||||
da
|
da
|
||||||
}
|
}
|
||||||
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => da,
|
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
|
||||||
Addr::Str(s) => self.follow_heap(s), // record terms of structure.
|
da
|
||||||
|
}
|
||||||
|
Addr::Str(s) => {
|
||||||
|
self.follow_heap(s) // record terms of structure.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,11 +91,15 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
|
|||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.state_stack.pop().map(|a| match self.follow(a) {
|
self.state_stack.pop().map(|a| match self.follow(a) {
|
||||||
Addr::HeapCell(h) => self.machine_st.heap[h].clone(),
|
Addr::HeapCell(h) => {
|
||||||
|
self.machine_st.heap[h].clone()
|
||||||
|
}
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
HeapCellValue::Addr(self.machine_st.stack.index_and_frame(fr)[sc].clone())
|
HeapCellValue::Addr(self.machine_st.stack.index_and_frame(fr)[sc].clone())
|
||||||
}
|
}
|
||||||
da => HeapCellValue::Addr(da),
|
da => {
|
||||||
|
HeapCellValue::Addr(da)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use prolog_parser::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use prolog_parser::string_list::*;
|
|
||||||
|
|
||||||
use crate::prolog::clause_types::*;
|
use crate::prolog::clause_types::*;
|
||||||
use crate::prolog::forms::*;
|
use crate::prolog::forms::*;
|
||||||
@@ -12,7 +11,7 @@ use crate::prolog::rug::Integer;
|
|||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::iter::once;
|
use std::iter::{FromIterator, once};
|
||||||
use std::ops::{Range, RangeFrom};
|
use std::ops::{Range, RangeFrom};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@@ -789,12 +788,15 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Constant::CharCode(c) => {
|
||||||
|
self.append_str(&format!("{}", c as u32));
|
||||||
|
}
|
||||||
Constant::Char(c) if non_quoted_token(once(c)) => {
|
Constant::Char(c) if non_quoted_token(once(c)) => {
|
||||||
let c = char_to_string(c);
|
let c = char_to_string(c);
|
||||||
|
|
||||||
push_space_if_amb!(self, &c, {
|
push_space_if_amb!(self, &c, {
|
||||||
self.append_str(c.as_str());
|
self.append_str(c.as_str());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Constant::Char(c) => {
|
Constant::Char(c) => {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
@@ -806,51 +808,38 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
} else {
|
} else {
|
||||||
result += &char_to_string(c);
|
result += &char_to_string(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
push_space_if_amb!(self, &result, {
|
push_space_if_amb!(self, &result, {
|
||||||
self.append_str(result.as_str());
|
self.append_str(result.as_str());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Constant::CharCode(c) => self.append_str(&format!("{}", c)),
|
|
||||||
Constant::CutPoint(b) => self.append_str(&format!("{}", b)),
|
Constant::CutPoint(b) => self.append_str(&format!("{}", b)),
|
||||||
Constant::EmptyList => self.append_str("[]"),
|
Constant::EmptyList => self.append_str("[]"),
|
||||||
Constant::Integer(n) => self.print_number(Number::Integer(n), op),
|
Constant::Integer(n) => self.print_number(Number::Integer(n), op),
|
||||||
Constant::Float(n) => self.print_number(Number::Float(n), op),
|
Constant::Float(n) => self.print_number(Number::Float(n), op),
|
||||||
Constant::Rational(n) => self.print_number(Number::Rational(n), op),
|
Constant::Rational(n) => self.print_number(Number::Rational(n), op),
|
||||||
Constant::String(s) => self.print_string(s),
|
Constant::String(n, s) => self.print_string(n, s),
|
||||||
Constant::Usize(i) => self.append_str(&format!("u{}", i)),
|
Constant::Usize(i) => self.append_str(&format!("u{}", i)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_string(&mut self, s: StringList) {
|
fn print_string(&mut self, offset: usize, s: Rc<String>) {
|
||||||
match self.machine_st.machine_flags().double_quotes {
|
if !self.machine_st.machine_flags().double_quotes.is_atom() {
|
||||||
DoubleQuotes::Chars | DoubleQuotes::Codes => {
|
if !s[offset ..].is_empty() {
|
||||||
if !s.is_empty() {
|
if self.ignore_ops {
|
||||||
if self.ignore_ops {
|
self.format_struct(2, clause_name!("."));
|
||||||
self.format_struct(2, clause_name!("."));
|
} else {
|
||||||
} else {
|
self.push_list();
|
||||||
self.push_list();
|
|
||||||
}
|
|
||||||
} else if s.is_expandable() {
|
|
||||||
if !self.at_cdr("|_") {
|
|
||||||
self.push_char('_');
|
|
||||||
}
|
|
||||||
} else if !self.at_cdr("") {
|
|
||||||
self.append_str("[]");
|
|
||||||
}
|
}
|
||||||
|
} else if !self.at_cdr("") {
|
||||||
|
self.append_str("[]");
|
||||||
}
|
}
|
||||||
DoubleQuotes::Atom => {
|
} else {
|
||||||
let borrowed_str = s.borrow();
|
let atom = String::from_iter(s[offset ..].chars().map(char_to_string));
|
||||||
let mut atom = String::new();
|
|
||||||
|
|
||||||
for c in borrowed_str[s.cursor()..].chars() {
|
self.push_char('"');
|
||||||
atom += &char_to_string(c);
|
self.append_str(&atom);
|
||||||
}
|
self.push_char('"');
|
||||||
|
|
||||||
self.push_char('"');
|
|
||||||
self.append_str(&atom);
|
|
||||||
self.push_char('"');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,16 +15,14 @@ enum IntIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CodeOffsets {
|
pub struct CodeOffsets {
|
||||||
flags: MachineFlags,
|
|
||||||
pub constants: IndexMap<Constant, ThirdLevelIndex>,
|
pub constants: IndexMap<Constant, ThirdLevelIndex>,
|
||||||
pub lists: ThirdLevelIndex,
|
pub lists: ThirdLevelIndex,
|
||||||
pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
|
pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeOffsets {
|
impl CodeOffsets {
|
||||||
pub fn new(flags: MachineFlags) -> Self {
|
pub fn new() -> Self {
|
||||||
CodeOffsets {
|
CodeOffsets {
|
||||||
flags,
|
|
||||||
constants: IndexMap::new(),
|
constants: IndexMap::new(),
|
||||||
lists: Vec::new(),
|
lists: Vec::new(),
|
||||||
structures: IndexMap::new(),
|
structures: IndexMap::new(),
|
||||||
@@ -65,18 +63,15 @@ impl CodeOffsets {
|
|||||||
let is_initial_index = self.lists.is_empty();
|
let is_initial_index = self.lists.is_empty();
|
||||||
self.lists.push(Self::add_index(is_initial_index, index));
|
self.lists.push(Self::add_index(is_initial_index, index));
|
||||||
}
|
}
|
||||||
&Term::Constant(_, Constant::String(ref s))
|
&Term::Constant(_, Constant::String(n, ref s)) => {
|
||||||
if !self.flags.double_quotes.is_atom() && !s.is_empty() =>
|
|
||||||
{
|
|
||||||
// strings are lists in this case.
|
|
||||||
let is_initial_index = self.lists.is_empty();
|
|
||||||
self.lists.push(Self::add_index(is_initial_index, index));
|
|
||||||
}
|
|
||||||
&Term::Constant(_, Constant::String(ref s))
|
|
||||||
if !self.flags.double_quotes.is_atom() && s.is_expandable() =>
|
|
||||||
{
|
|
||||||
let is_initial_index = self.lists.is_empty();
|
let is_initial_index = self.lists.is_empty();
|
||||||
self.lists.push(Self::add_index(is_initial_index, index));
|
self.lists.push(Self::add_index(is_initial_index, index));
|
||||||
|
|
||||||
|
let constant = Constant::String(n, s.clone());
|
||||||
|
let code = self.constants.entry(constant).or_insert(Vec::new());
|
||||||
|
|
||||||
|
let is_initial_index = code.is_empty();
|
||||||
|
code.push(Self::add_index(is_initial_index, index));
|
||||||
}
|
}
|
||||||
&Term::Constant(_, ref constant) => {
|
&Term::Constant(_, ref constant) => {
|
||||||
let code = self.constants.entry(constant.clone()).or_insert(Vec::new());
|
let code = self.constants.entry(constant.clone()).or_insert(Vec::new());
|
||||||
@@ -260,8 +255,8 @@ impl CodeOffsets {
|
|||||||
for (index, line) in prelude.iter_mut().enumerate() {
|
for (index, line) in prelude.iter_mut().enumerate() {
|
||||||
match line {
|
match line {
|
||||||
&mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i))
|
&mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i))
|
||||||
| &mut Line::IndexedChoice(IndexedChoiceInstruction::Retry(ref mut i))
|
| &mut Line::IndexedChoice(IndexedChoiceInstruction::Retry(ref mut i))
|
||||||
| &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => {
|
| &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => {
|
||||||
*i += prelude_length - index
|
*i += prelude_length - index
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -928,8 +928,12 @@ must_be_number(N, PI) :-
|
|||||||
; throw(error(instantiation_error, PI))
|
; throw(error(instantiation_error, PI))
|
||||||
).
|
).
|
||||||
|
|
||||||
can_be_chars_or_vars(Cs, _) :- var(Cs), !.
|
can_be_chars_or_vars(Cs, _) :- var(Cs), !.
|
||||||
can_be_chars_or_vars(Cs, PI) :- chars_or_vars(Cs, PI).
|
can_be_chars_or_vars(Cs, PI) :-
|
||||||
|
( string(Cs) ->
|
||||||
|
current_prolog_flag(double_quotes, chars)
|
||||||
|
; chars_or_vars(Cs, PI)
|
||||||
|
).
|
||||||
|
|
||||||
chars_or_vars([], _).
|
chars_or_vars([], _).
|
||||||
chars_or_vars([C|Cs], PI) :-
|
chars_or_vars([C|Cs], PI) :-
|
||||||
@@ -943,8 +947,12 @@ chars_or_vars([C|Cs], PI) :-
|
|||||||
; chars_or_vars(Cs, PI)
|
; chars_or_vars(Cs, PI)
|
||||||
).
|
).
|
||||||
|
|
||||||
can_be_codes_or_vars(Cs, _) :- var(Cs), !.
|
can_be_codes_or_vars(Cs, _) :- var(Cs), !.
|
||||||
can_be_codes_or_vars(Cs, PI) :- codes_or_vars(Cs, PI).
|
can_be_codes_or_vars(Cs, PI) :-
|
||||||
|
( string(Cs) ->
|
||||||
|
current_prolog_flag(double_quotes, codes)
|
||||||
|
; codes_or_vars(Cs, PI)
|
||||||
|
).
|
||||||
|
|
||||||
codes_or_vars([], _).
|
codes_or_vars([], _).
|
||||||
codes_or_vars([C|Cs], PI) :-
|
codes_or_vars([C|Cs], PI) :-
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use prolog_parser::ast::MachineFlags;
|
|
||||||
|
|
||||||
use crate::prolog::clause_types::*;
|
use crate::prolog::clause_types::*;
|
||||||
use crate::prolog::codegen::*;
|
use crate::prolog::codegen::*;
|
||||||
use crate::prolog::debray_allocator::*;
|
use crate::prolog::debray_allocator::*;
|
||||||
@@ -67,7 +65,6 @@ impl CodeRepo {
|
|||||||
result: &CompiledResult,
|
result: &CompiledResult,
|
||||||
in_situ_code_dir: &mut InSituCodeDir,
|
in_situ_code_dir: &mut InSituCodeDir,
|
||||||
in_situ_module_dir: &mut ModuleStubDir,
|
in_situ_module_dir: &mut ModuleStubDir,
|
||||||
flags: MachineFlags,
|
|
||||||
non_counted_bt_preds: &IndexSet<PredicateKey>,
|
non_counted_bt_preds: &IndexSet<PredicateKey>,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let (ref decl, ref queue) = result;
|
let (ref decl, ref queue) = result;
|
||||||
@@ -94,10 +91,10 @@ impl CodeRepo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt);
|
||||||
let mut decl_code = cg.compile_predicate(&decl.0)?;
|
let mut decl_code = cg.compile_predicate(&decl.0)?;
|
||||||
|
|
||||||
compile_appendix(&mut decl_code, queue, non_counted_bt, flags)?;
|
compile_appendix(&mut decl_code, queue, non_counted_bt)?;
|
||||||
|
|
||||||
Ok(self.in_situ_code.extend(decl_code.into_iter()))
|
Ok(self.in_situ_code.extend(decl_code.into_iter()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,11 +196,10 @@ pub fn compile_appendix(
|
|||||||
code: &mut Code,
|
code: &mut Code,
|
||||||
queue: &VecDeque<TopLevel>,
|
queue: &VecDeque<TopLevel>,
|
||||||
non_counted_bt: bool,
|
non_counted_bt: bool,
|
||||||
flags: MachineFlags,
|
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
for tl in queue.iter() {
|
for tl in queue.iter() {
|
||||||
set_first_index(code);
|
set_first_index(code);
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt);
|
||||||
let decl_code = compile_relation(&mut cg, tl)?;
|
let decl_code = compile_relation(&mut cg, tl)?;
|
||||||
code.extend(decl_code.into_iter());
|
code.extend(decl_code.into_iter());
|
||||||
}
|
}
|
||||||
@@ -230,7 +229,6 @@ impl CodeRepo {
|
|||||||
pub fn compile_hook(
|
pub fn compile_hook(
|
||||||
&mut self,
|
&mut self,
|
||||||
hook: CompileTimeHook,
|
hook: CompileTimeHook,
|
||||||
flags: MachineFlags,
|
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
let key = (hook.name(), hook.arity());
|
let key = (hook.name(), hook.arity());
|
||||||
|
|
||||||
@@ -238,10 +236,10 @@ impl CodeRepo {
|
|||||||
Some(ref mut preds) => {
|
Some(ref mut preds) => {
|
||||||
append_trivial_goal(&key.0, &mut preds.0);
|
append_trivial_goal(&key.0, &mut preds.0);
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false);
|
||||||
let mut code = cg.compile_predicate(&(preds.0).0)?;
|
let mut code = cg.compile_predicate(&(preds.0).0)?;
|
||||||
|
|
||||||
compile_appendix(&mut code, &preds.1, false, flags)?;
|
compile_appendix(&mut code, &preds.1, false)?;
|
||||||
|
|
||||||
(preds.0).0.pop();
|
(preds.0).0.pop();
|
||||||
|
|
||||||
@@ -260,7 +258,7 @@ impl CodeRepo {
|
|||||||
let mut preds = Predicate::new();
|
let mut preds = Predicate::new();
|
||||||
append_trivial_goal(&key.0, &mut preds);
|
append_trivial_goal(&key.0, &mut preds);
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false);
|
||||||
self.term_expanders = cg.compile_predicate(&preds.0)?;
|
self.term_expanders = cg.compile_predicate(&preds.0)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,7 +267,7 @@ impl CodeRepo {
|
|||||||
let mut preds = Predicate::new();
|
let mut preds = Predicate::new();
|
||||||
append_trivial_goal(&key.0, &mut preds);
|
append_trivial_goal(&key.0, &mut preds);
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false);
|
||||||
self.goal_expanders = cg.compile_predicate(&preds.0)?;
|
self.goal_expanders = cg.compile_predicate(&preds.0)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,13 +279,12 @@ impl CodeRepo {
|
|||||||
fn compile_query(
|
fn compile_query(
|
||||||
terms: Vec<QueryTerm>,
|
terms: Vec<QueryTerm>,
|
||||||
queue: VecDeque<TopLevel>,
|
queue: VecDeque<TopLevel>,
|
||||||
flags: MachineFlags,
|
|
||||||
) -> Result<(Code, AllocVarDict), ParserError> {
|
) -> Result<(Code, AllocVarDict), ParserError> {
|
||||||
// count backtracking inferences.
|
// count backtracking inferences.
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false);
|
||||||
let mut code = cg.compile_query(&terms)?;
|
let mut code = cg.compile_query(&terms)?;
|
||||||
|
|
||||||
compile_appendix(&mut code, &queue, false, flags)?;
|
compile_appendix(&mut code, &queue, false)?;
|
||||||
Ok((code, cg.take_vars()))
|
Ok((code, cg.take_vars()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +342,7 @@ pub(super) fn compile_into_module<R: Read>(
|
|||||||
wam.indices.insert_module(module);
|
wam.indices.insert_module(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo);
|
compiler.drop_expansions(&mut wam.code_repo);
|
||||||
EvalSession::from(e)
|
EvalSession::from(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -363,10 +360,8 @@ fn compile_into_module_impl<R: Read>(
|
|||||||
let module_name = module.module_decl.name.clone();
|
let module_name = module.module_decl.name.clone();
|
||||||
compiler.module = Some(module);
|
compiler.module = Some(module);
|
||||||
|
|
||||||
let flags = wam.machine_flags();
|
wam.code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
|
||||||
|
wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
|
||||||
wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
|
|
||||||
wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?;
|
|
||||||
|
|
||||||
let mut results = compiler.gather_items(wam, src, &mut indices)?;
|
let mut results = compiler.gather_items(wam, src, &mut indices)?;
|
||||||
|
|
||||||
@@ -400,7 +395,7 @@ fn compile_into_module_impl<R: Read>(
|
|||||||
|
|
||||||
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
|
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
|
||||||
|
|
||||||
Ok(compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo))
|
Ok(compiler.drop_expansions(&mut wam.code_repo))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GatherResult {
|
pub struct GatherResult {
|
||||||
@@ -462,14 +457,14 @@ impl ClauseCodeGenerator {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let p = self.code.len() + wam.code_repo.code.len() + self.len_offset;
|
let p = self.code.len() + wam.code_repo.code.len() + self.len_offset;
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, wam.machine_flags());
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false);
|
||||||
|
|
||||||
let mut decl_code = compile_relation(
|
let mut decl_code = compile_relation(
|
||||||
&mut cg,
|
&mut cg,
|
||||||
&TopLevel::Predicate(predicate),
|
&TopLevel::Predicate(predicate),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
compile_appendix(&mut decl_code, &VecDeque::new(), false, wam.machine_flags())?;
|
compile_appendix(&mut decl_code, &VecDeque::new(), false)?;
|
||||||
|
|
||||||
self.pi_to_loc.insert((name.clone(), *arity), p);
|
self.pi_to_loc.insert((name.clone(), *arity), p);
|
||||||
self.code.extend(decl_code.into_iter());
|
self.code.extend(decl_code.into_iter());
|
||||||
@@ -735,12 +730,11 @@ impl ListingCompiler {
|
|||||||
|
|
||||||
fn generate_init_goal_code(
|
fn generate_init_goal_code(
|
||||||
&mut self,
|
&mut self,
|
||||||
flags: MachineFlags
|
|
||||||
) -> Result<Code, SessionError> {
|
) -> Result<Code, SessionError> {
|
||||||
let query_terms = mem::replace(&mut self.initialization_goals.0, vec![]);
|
let query_terms = mem::replace(&mut self.initialization_goals.0, vec![]);
|
||||||
let queue = mem::replace(&mut self.initialization_goals.1, VecDeque::new());
|
let queue = mem::replace(&mut self.initialization_goals.1, VecDeque::new());
|
||||||
|
|
||||||
compile_query(query_terms, queue, flags)
|
compile_query(query_terms, queue)
|
||||||
.map(|(code, _)| code)
|
.map(|(code, _)| code)
|
||||||
.map_err(SessionError::from)
|
.map_err(SessionError::from)
|
||||||
}
|
}
|
||||||
@@ -766,13 +760,12 @@ impl ListingCompiler {
|
|||||||
self.localize_self_calls(key, in_situ_code, *in_situ_p, p + *in_situ_p);
|
self.localize_self_calls(key, in_situ_code, *in_situ_p, p + *in_situ_p);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let flags = wam.machine_flags();
|
|
||||||
let (decl, queue) = decl;
|
let (decl, queue) = decl;
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
let mut cg = CodeGenerator::<DebrayAllocator>::new(false);
|
||||||
let mut decl_code = cg.compile_predicate(&decl.0)?;
|
let mut decl_code = cg.compile_predicate(&decl.0)?;
|
||||||
|
|
||||||
compile_appendix(&mut decl_code, &queue, false, flags)?;
|
compile_appendix(&mut decl_code, &queue, false)?;
|
||||||
|
|
||||||
let in_situ_p = in_situ_code.len();
|
let in_situ_p = in_situ_code.len();
|
||||||
|
|
||||||
@@ -934,7 +927,7 @@ impl ListingCompiler {
|
|||||||
|
|
||||||
let result = wam
|
let result = wam
|
||||||
.code_repo
|
.code_repo
|
||||||
.compile_hook(hook, flags)
|
.compile_hook(hook)
|
||||||
.map_err(SessionError::from);
|
.map_err(SessionError::from);
|
||||||
|
|
||||||
wam.code_repo.truncate_terms(key, len, queue_len);
|
wam.code_repo.truncate_terms(key, len, queue_len);
|
||||||
@@ -1170,15 +1163,15 @@ impl ListingCompiler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_expansions(&self, flags: MachineFlags, code_repo: &mut CodeRepo) {
|
fn drop_expansions(&self, code_repo: &mut CodeRepo) {
|
||||||
let (te_len, te_queue_len) = self.orig_term_expansion_lens;
|
let (te_len, te_queue_len) = self.orig_term_expansion_lens;
|
||||||
let (ge_len, ge_queue_len) = self.orig_goal_expansion_lens;
|
let (ge_len, ge_queue_len) = self.orig_goal_expansion_lens;
|
||||||
|
|
||||||
code_repo.truncate_terms((clause_name!("term_expansion"), 2), te_len, te_queue_len);
|
code_repo.truncate_terms((clause_name!("term_expansion"), 2), te_len, te_queue_len);
|
||||||
code_repo.truncate_terms((clause_name!("goal_expansion"), 2), ge_len, ge_queue_len);
|
code_repo.truncate_terms((clause_name!("goal_expansion"), 2), ge_len, ge_queue_len);
|
||||||
|
|
||||||
discard_result!(code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags));
|
discard_result!(code_repo.compile_hook(CompileTimeHook::UserGoalExpansion));
|
||||||
discard_result!(code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags));
|
discard_result!(code_repo.compile_hook(CompileTimeHook::UserTermExpansion));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_error(&self, e: &SessionError) {
|
fn print_error(&self, e: &SessionError) {
|
||||||
@@ -1244,10 +1237,8 @@ fn compile_work_impl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let flags = wam.machine_flags();
|
wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion)?;
|
||||||
|
wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion)?;
|
||||||
wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags)?;
|
|
||||||
wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags)?;
|
|
||||||
|
|
||||||
if let Some(mut module) = compiler.module.take() {
|
if let Some(mut module) = compiler.module.take() {
|
||||||
if module.is_impromptu_module {
|
if module.is_impromptu_module {
|
||||||
@@ -1280,7 +1271,7 @@ fn compile_work_impl(
|
|||||||
|
|
||||||
add_toplevel(wam, results.toplevel_indices, top_level_term_dir);
|
add_toplevel(wam, results.toplevel_indices, top_level_term_dir);
|
||||||
wam.code_repo.code.extend(code.into_iter());
|
wam.code_repo.code.extend(code.into_iter());
|
||||||
|
|
||||||
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
|
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
|
||||||
} else {
|
} else {
|
||||||
add_non_module_code(
|
add_non_module_code(
|
||||||
@@ -1292,9 +1283,7 @@ fn compile_work_impl(
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let init_goal_code = compiler.generate_init_goal_code(
|
let init_goal_code = compiler.generate_init_goal_code()?;
|
||||||
wam.machine_flags()
|
|
||||||
)?;
|
|
||||||
|
|
||||||
if init_goal_code.len() > 0 {
|
if init_goal_code.len() > 0 {
|
||||||
if !wam.run_init_code(init_goal_code) {
|
if !wam.run_init_code(init_goal_code) {
|
||||||
@@ -1370,7 +1359,7 @@ pub fn compile_listing<R: Read>(
|
|||||||
|
|
||||||
match compile_work(&mut compiler, wam, src, indices) {
|
match compile_work(&mut compiler, wam, src, indices) {
|
||||||
EvalSession::Error(e) => {
|
EvalSession::Error(e) => {
|
||||||
compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo);
|
compiler.drop_expansions(&mut wam.code_repo);
|
||||||
compiler.print_error(&e);
|
compiler.print_error(&e);
|
||||||
|
|
||||||
EvalSession::Error(e)
|
EvalSession::Error(e)
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use prolog_parser::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use prolog_parser::string_list::*;
|
|
||||||
|
|
||||||
use crate::prolog::forms::PredicateKey;
|
use crate::prolog::forms::PredicateKey;
|
||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::machine_state::*;
|
use crate::prolog::machine::machine_state::*;
|
||||||
use crate::prolog::rug::Integer;
|
use crate::prolog::rug::Integer;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub(crate) type MachineStub = Vec<HeapCellValue>;
|
pub(crate) type MachineStub = Vec<HeapCellValue>;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -392,7 +393,7 @@ pub(super) enum CycleSearchResult {
|
|||||||
NotList,
|
NotList,
|
||||||
PartialList(usize, usize), // the list length (up to max), and an offset into the heap.
|
PartialList(usize, usize), // the list length (up to max), and an offset into the heap.
|
||||||
ProperList(usize), // the list length.
|
ProperList(usize), // the list length.
|
||||||
String(usize, StringList), // the number of elements iterated, the string tail.
|
String(usize, usize, Rc<String>), // the number of bytes iterated, the offset, the string.
|
||||||
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
UntouchedList(usize), // the address of an uniterated Addr::Lis(address).
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use prolog_parser::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use prolog_parser::string_list::*;
|
|
||||||
|
|
||||||
use crate::prolog::clause_types::*;
|
use crate::prolog::clause_types::*;
|
||||||
use crate::prolog::forms::*;
|
use crate::prolog::forms::*;
|
||||||
@@ -250,8 +249,6 @@ pub struct MachineState {
|
|||||||
pub(crate) stack: Stack,
|
pub(crate) stack: Stack,
|
||||||
pub(super) registers: Registers,
|
pub(super) registers: Registers,
|
||||||
pub(super) trail: Vec<TrailRef>,
|
pub(super) trail: Vec<TrailRef>,
|
||||||
pub(super) pstr_trail: Vec<(usize, StringList, usize)>, // b, String, trunc_pt
|
|
||||||
pub(super) pstr_tr: usize,
|
|
||||||
pub(super) tr: usize,
|
pub(super) tr: usize,
|
||||||
pub(super) hb: usize,
|
pub(super) hb: usize,
|
||||||
pub(super) block: usize, // an offset into the OR stack.
|
pub(super) block: usize, // an offset into the OR stack.
|
||||||
@@ -265,72 +262,58 @@ pub struct MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(super) fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
pub(super)
|
||||||
|
fn try_char_list(&self, addrs: Vec<Addr>) -> Result<String, MachineError> {
|
||||||
let mut chars = String::new();
|
let mut chars = String::new();
|
||||||
let mut iter = addrs.iter();
|
let mut iter = addrs.iter();
|
||||||
|
|
||||||
while let Some(addr) = iter.next() {
|
while let Some(addr) = iter.next() {
|
||||||
match addr {
|
match addr {
|
||||||
&Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => {
|
&Addr::Con(Constant::String(n, ref s))
|
||||||
chars += s.borrow().as_str();
|
if self.flags.double_quotes.is_chars() => {
|
||||||
|
if s.len() < n {
|
||||||
|
chars += &s[n ..];
|
||||||
|
}
|
||||||
|
|
||||||
if iter.next().is_some() {
|
if iter.next().is_some() {
|
||||||
return Err(MachineError::type_error(ValidType::Character, addr.clone()));
|
return Err(MachineError::type_error(ValidType::Character, addr.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&Addr::Con(Constant::Char(c)) => {
|
||||||
|
chars.push(c);
|
||||||
|
}
|
||||||
|
&Addr::Con(Constant::Atom(ref name, _))
|
||||||
|
if name.as_str().len() == 1 => {
|
||||||
|
chars += name.as_str();
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(
|
||||||
|
MachineError::type_error(ValidType::Character, addr.clone())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
&Addr::Con(Constant::Char(c)) => chars.push(c),
|
|
||||||
&Addr::Con(Constant::Atom(ref name, _)) if name.as_str().len() == 1 => {
|
|
||||||
chars += name.as_str();
|
|
||||||
}
|
|
||||||
_ => return Err(MachineError::type_error(ValidType::Character, addr.clone())),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(chars)
|
Ok(chars)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn try_code_list(&self, addrs: Vec<Addr>) -> Result<Vec<u8>, MachineError> {
|
pub(super)
|
||||||
let mut codes = vec![];
|
fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||||
let mut iter = addrs.iter();
|
|
||||||
|
|
||||||
while let Some(addr) = iter.next() {
|
|
||||||
match addr {
|
|
||||||
&Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_codes() => {
|
|
||||||
codes.extend(s.borrow().chars().map(|c| c as u8));
|
|
||||||
|
|
||||||
if iter.next().is_some() {
|
|
||||||
return Err(MachineError::representation_error(RepFlag::CharacterCode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&Addr::Con(Constant::CharCode(c)) => codes.push(c),
|
|
||||||
&Addr::Con(Constant::Integer(ref n)) => {
|
|
||||||
if let Some(c) = n.to_u8() {
|
|
||||||
codes.push(c);
|
|
||||||
} else {
|
|
||||||
return Err(MachineError::representation_error(RepFlag::CharacterCode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => return Err(MachineError::representation_error(RepFlag::CharacterCode)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(codes)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) 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) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
pub(super)
|
||||||
|
fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
|
||||||
self.num_of_args = arity;
|
self.num_of_args = arity;
|
||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p = CodePtr::Local(p);
|
self.p = CodePtr::Local(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn module_lookup(
|
pub(super)
|
||||||
|
fn module_lookup(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &IndexStore,
|
indices: &IndexStore,
|
||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
@@ -379,7 +362,7 @@ impl MachineState {
|
|||||||
self.call_at_index(arity, LocalCodePtr::InSituDirEntry(p));
|
self.call_at_index(arity, LocalCodePtr::InSituDirEntry(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -460,19 +443,12 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
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);
|
||||||
|
|
||||||
let old_pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
let curr_pstr_tr = machine_st.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
|
|
||||||
machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
|
|
||||||
|
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
let attr_var_init_queue_b =
|
||||||
let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b =
|
||||||
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(
|
machine_st.attr_var_init.backtrack(
|
||||||
attr_var_init_queue_b,
|
attr_var_init_queue_b,
|
||||||
@@ -506,18 +482,12 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
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);
|
||||||
|
|
||||||
let old_pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
let curr_pstr_tr = machine_st.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
|
|
||||||
machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
|
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
let attr_var_init_queue_b =
|
||||||
let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b =
|
||||||
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
|
||||||
|
|
||||||
@@ -546,18 +516,12 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
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);
|
||||||
|
|
||||||
let old_pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
let curr_pstr_tr = machine_st.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
|
|
||||||
machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
|
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
let attr_var_init_queue_b =
|
||||||
let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b =
|
||||||
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(
|
machine_st.attr_var_init.backtrack(
|
||||||
attr_var_init_queue_b,
|
attr_var_init_queue_b,
|
||||||
@@ -591,20 +555,12 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
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);
|
||||||
|
|
||||||
let old_pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
let curr_pstr_tr = machine_st.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.unwind_pstr_trail(old_pstr_tr, curr_pstr_tr);
|
|
||||||
machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
|
|
||||||
machine_st.pstr_tr = machine_st.stack.index_or_frame(b).prelude.pstr_tr;
|
|
||||||
machine_st.pstr_trail.truncate(machine_st.pstr_tr);
|
|
||||||
|
|
||||||
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
machine_st.heap.truncate(machine_st.stack.index_or_frame(b).prelude.h);
|
||||||
|
|
||||||
let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
let attr_var_init_queue_b =
|
||||||
let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
|
||||||
|
let attr_var_init_bindings_b =
|
||||||
|
machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
|
||||||
|
|
||||||
machine_st.attr_var_init.backtrack(
|
machine_st.attr_var_init.backtrack(
|
||||||
attr_var_init_queue_b,
|
attr_var_init_queue_b,
|
||||||
@@ -802,15 +758,6 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
|
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::PartialString => {
|
|
||||||
let s = machine_st.try_string_list(temp_v!(1))?;
|
|
||||||
let a2 = machine_st[temp_v!(2)].clone();
|
|
||||||
|
|
||||||
s.set_expandable(true);
|
|
||||||
machine_st.write_constant_to_var(a2, Constant::String(s));
|
|
||||||
|
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
|
||||||
}
|
|
||||||
&BuiltInClauseType::Sort => {
|
&BuiltInClauseType::Sort => {
|
||||||
machine_st.check_sort_errors()?;
|
machine_st.check_sort_errors()?;
|
||||||
|
|
||||||
@@ -1087,7 +1034,6 @@ fn cut_body(machine_st: &mut MachineState, addr: Addr) -> bool {
|
|||||||
if b > b0 {
|
if b > b0 {
|
||||||
machine_st.b = b0;
|
machine_st.b = b0;
|
||||||
machine_st.tidy_trail();
|
machine_st.tidy_trail();
|
||||||
machine_st.tidy_pstr_trail();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -1174,7 +1120,6 @@ impl CutPolicy for SCCCutPolicy {
|
|||||||
if b > b0 {
|
if b > b0 {
|
||||||
machine_st.b = b0;
|
machine_st.b = b0;
|
||||||
machine_st.tidy_trail();
|
machine_st.tidy_trail();
|
||||||
machine_st.tidy_pstr_trail();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -161,27 +161,27 @@ impl SubModuleUser for IndexStore {
|
|||||||
fn use_qualified_module(
|
fn use_qualified_module(
|
||||||
&mut self,
|
&mut self,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
flags: MachineFlags,
|
_: MachineFlags,
|
||||||
submodule: &Module,
|
submodule: &Module,
|
||||||
exports: &Vec<ModuleExport>,
|
exports: &Vec<ModuleExport>,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
use_qualified_module(self, submodule, exports)?;
|
use_qualified_module(self, submodule, exports)?;
|
||||||
submodule
|
submodule
|
||||||
.dump_expansions(code_repo, flags)
|
.dump_expansions(code_repo)
|
||||||
.map_err(SessionError::from)
|
.map_err(SessionError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_module(
|
fn use_module(
|
||||||
&mut self,
|
&mut self,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
flags: MachineFlags,
|
_: MachineFlags,
|
||||||
submodule: &Module,
|
submodule: &Module,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
use_module(self, submodule)?;
|
use_module(self, submodule)?;
|
||||||
|
|
||||||
if !submodule.inserted_expansions {
|
if !submodule.inserted_expansions {
|
||||||
submodule
|
submodule
|
||||||
.dump_expansions(code_repo, flags)
|
.dump_expansions(code_repo)
|
||||||
.map_err(SessionError::from)
|
.map_err(SessionError::from)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -699,12 +699,10 @@ impl Machine {
|
|||||||
snapshot.b0 = self.machine_st.b0;
|
snapshot.b0 = self.machine_st.b0;
|
||||||
snapshot.s = self.machine_st.s;
|
snapshot.s = self.machine_st.s;
|
||||||
snapshot.tr = self.machine_st.tr;
|
snapshot.tr = self.machine_st.tr;
|
||||||
snapshot.pstr_tr = self.machine_st.pstr_tr;
|
|
||||||
snapshot.num_of_args = self.machine_st.num_of_args;
|
snapshot.num_of_args = self.machine_st.num_of_args;
|
||||||
|
|
||||||
snapshot.fail = self.machine_st.fail;
|
snapshot.fail = self.machine_st.fail;
|
||||||
snapshot.trail = mem::replace(&mut self.machine_st.trail, vec![]);
|
snapshot.trail = mem::replace(&mut self.machine_st.trail, vec![]);
|
||||||
snapshot.pstr_trail = mem::replace(&mut self.machine_st.pstr_trail, vec![]);
|
|
||||||
snapshot.heap = self.machine_st.heap.take();
|
snapshot.heap = self.machine_st.heap.take();
|
||||||
snapshot.mode = self.machine_st.mode;
|
snapshot.mode = self.machine_st.mode;
|
||||||
snapshot.stack = self.machine_st.stack.take();
|
snapshot.stack = self.machine_st.stack.take();
|
||||||
@@ -724,12 +722,10 @@ impl Machine {
|
|||||||
self.machine_st.b0 = snapshot.b0;
|
self.machine_st.b0 = snapshot.b0;
|
||||||
self.machine_st.s = snapshot.s;
|
self.machine_st.s = snapshot.s;
|
||||||
self.machine_st.tr = snapshot.tr;
|
self.machine_st.tr = snapshot.tr;
|
||||||
self.machine_st.pstr_tr = snapshot.pstr_tr;
|
|
||||||
self.machine_st.num_of_args = snapshot.num_of_args;
|
self.machine_st.num_of_args = snapshot.num_of_args;
|
||||||
|
|
||||||
self.machine_st.fail = snapshot.fail;
|
self.machine_st.fail = snapshot.fail;
|
||||||
self.machine_st.trail = mem::replace(&mut snapshot.trail, vec![]);
|
self.machine_st.trail = mem::replace(&mut snapshot.trail, vec![]);
|
||||||
self.machine_st.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]);
|
|
||||||
|
|
||||||
self.inner_heap = self.machine_st.heap.take();
|
self.inner_heap = self.machine_st.heap.take();
|
||||||
self.inner_heap.truncate(0);
|
self.inner_heap.truncate(0);
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ impl Module {
|
|||||||
pub fn dump_expansions(
|
pub fn dump_expansions(
|
||||||
&self,
|
&self,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
flags: MachineFlags,
|
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
{
|
{
|
||||||
let te = code_repo
|
let te = code_repo
|
||||||
@@ -64,8 +63,8 @@ impl Module {
|
|||||||
ge.1.extend(self.user_goal_expansions.1.iter().cloned());
|
ge.1.extend(self.user_goal_expansions.1.iter().cloned());
|
||||||
}
|
}
|
||||||
|
|
||||||
code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
|
code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
|
||||||
code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?;
|
code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use prolog_parser::ast::*;
|
use prolog_parser::ast::*;
|
||||||
use prolog_parser::parser::*;
|
use prolog_parser::parser::*;
|
||||||
use prolog_parser::string_list::*;
|
|
||||||
use prolog_parser::tabled_rc::*;
|
use prolog_parser::tabled_rc::*;
|
||||||
|
|
||||||
use crate::prolog::clause_types::*;
|
use crate::prolog::clause_types::*;
|
||||||
@@ -88,8 +87,8 @@ impl MachineState {
|
|||||||
brent_st.steps,
|
brent_st.steps,
|
||||||
brent_st.hare,
|
brent_st.hare,
|
||||||
)),
|
)),
|
||||||
Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => {
|
Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
|
||||||
Some(CycleSearchResult::String(brent_st.steps, s.clone()))
|
Some(CycleSearchResult::String(brent_st.steps, n, s.clone()))
|
||||||
}
|
}
|
||||||
Addr::Lis(l) => {
|
Addr::Lis(l) => {
|
||||||
brent_st.hare = l + 1;
|
brent_st.hare = l + 1;
|
||||||
@@ -104,7 +103,9 @@ impl MachineState {
|
|||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
_ => Some(CycleSearchResult::NotList),
|
_ => {
|
||||||
|
Some(CycleSearchResult::NotList)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,8 +116,8 @@ impl MachineState {
|
|||||||
Addr::Lis(offset) if max_steps > 0 => offset + 1,
|
Addr::Lis(offset) if max_steps > 0 => offset + 1,
|
||||||
Addr::Lis(offset) => return CycleSearchResult::UntouchedList(offset),
|
Addr::Lis(offset) => return CycleSearchResult::UntouchedList(offset),
|
||||||
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
|
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
|
||||||
Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
|
Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
|
||||||
return CycleSearchResult::String(0, s.clone())
|
return CycleSearchResult::String(0, n, s.clone())
|
||||||
}
|
}
|
||||||
_ => return CycleSearchResult::NotList,
|
_ => return CycleSearchResult::NotList,
|
||||||
};
|
};
|
||||||
@@ -139,8 +140,8 @@ impl MachineState {
|
|||||||
let hare = match addr {
|
let hare = match addr {
|
||||||
Addr::Lis(offset) => offset + 1,
|
Addr::Lis(offset) => offset + 1,
|
||||||
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
|
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
|
||||||
Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
|
Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
|
||||||
return CycleSearchResult::String(0, s.clone())
|
return CycleSearchResult::String(0, n, s.clone())
|
||||||
}
|
}
|
||||||
_ => return CycleSearchResult::NotList,
|
_ => return CycleSearchResult::NotList,
|
||||||
};
|
};
|
||||||
@@ -198,10 +199,10 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match search_result {
|
match search_result {
|
||||||
CycleSearchResult::String(n, s) => {
|
CycleSearchResult::String(n, offset, s) => {
|
||||||
if max_steps == -1 {
|
if max_steps == -1 {
|
||||||
self.finalize_skip_max_list(
|
self.finalize_skip_max_list(
|
||||||
n + s.len(),
|
s[offset ..].len(),
|
||||||
Addr::Con(Constant::EmptyList),
|
Addr::Con(Constant::EmptyList),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -209,15 +210,13 @@ impl MachineState {
|
|||||||
|
|
||||||
if s.len() < i {
|
if s.len() < i {
|
||||||
self.finalize_skip_max_list(
|
self.finalize_skip_max_list(
|
||||||
n + s.len(),
|
s[n + offset + i..].len(),
|
||||||
Addr::Con(Constant::EmptyList),
|
Addr::Con(Constant::EmptyList),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let s =
|
|
||||||
StringList::new(s.char_span(i), s.is_expandable());
|
|
||||||
self.finalize_skip_max_list(
|
self.finalize_skip_max_list(
|
||||||
i + n,
|
i + n + offset,
|
||||||
Addr::Con(Constant::String(s)),
|
Addr::Con(Constant::String(n + i + offset, s)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,8 +435,8 @@ impl MachineState {
|
|||||||
n: &Integer,
|
n: &Integer,
|
||||||
stub: &'static str,
|
stub: &'static str,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
) -> Result<u8, MachineStub> {
|
) -> Result<u32, MachineStub> {
|
||||||
if let Some(c) = n.to_u8() {
|
if let Some(c) = n.to_u32() {
|
||||||
Ok(c)
|
Ok(c)
|
||||||
} else {
|
} else {
|
||||||
let stub = MachineError::functor_stub(clause_name!(stub), arity);
|
let stub = MachineError::functor_stub(clause_name!(stub), arity);
|
||||||
@@ -644,7 +643,16 @@ impl MachineState {
|
|||||||
let list_of_chars = Addr::HeapCell(self.heap.to_list(iter));
|
let list_of_chars = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
self.unify(a2, list_of_chars);
|
|
||||||
|
match self.store(self.deref(a2)) {
|
||||||
|
Addr::Con(Constant::String(..))
|
||||||
|
if !self.flags.double_quotes.is_chars() => {
|
||||||
|
self.fail = true;
|
||||||
|
}
|
||||||
|
a2 => {
|
||||||
|
self.unify(a2, list_of_chars);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::EmptyList) => {
|
Addr::Con(Constant::EmptyList) => {
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
@@ -682,31 +690,50 @@ impl MachineState {
|
|||||||
|
|
||||||
match self.store(self.deref(a1)) {
|
match self.store(self.deref(a1)) {
|
||||||
Addr::Con(Constant::Char(c)) => {
|
Addr::Con(Constant::Char(c)) => {
|
||||||
let iter = once(Addr::Con(Constant::CharCode(c as u8)));
|
let iter = once(Addr::Con(Constant::CharCode(c as u32)));
|
||||||
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
self.unify(a2, list_of_codes);
|
self.unify(a2, list_of_codes);
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::Atom(name, _)) => {
|
Addr::Con(Constant::Atom(name, _)) => {
|
||||||
let iter = name
|
|
||||||
.as_str()
|
|
||||||
.chars()
|
|
||||||
.map(|c| Addr::Con(Constant::CharCode(c as u8)));
|
|
||||||
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
|
||||||
|
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
self.unify(a2, list_of_codes);
|
match self.store(self.deref(a2)) {
|
||||||
|
a2 @ Addr::Con(Constant::String(..)) => {
|
||||||
|
if !self.flags.double_quotes.is_codes() {
|
||||||
|
self.fail = true;
|
||||||
|
} else {
|
||||||
|
let iter = name
|
||||||
|
.as_str()
|
||||||
|
.chars()
|
||||||
|
.map(|c| Addr::Con(Constant::Char(c)));
|
||||||
|
|
||||||
|
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
|
|
||||||
|
self.unify(a2, list_of_codes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a2 => {
|
||||||
|
let iter = name
|
||||||
|
.as_str()
|
||||||
|
.chars()
|
||||||
|
.map(|c| Addr::Con(Constant::CharCode(c as u32)));
|
||||||
|
|
||||||
|
let list_of_codes = Addr::HeapCell(self.heap.to_list(iter));
|
||||||
|
|
||||||
|
self.unify(a2, list_of_codes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::EmptyList) => {
|
Addr::Con(Constant::EmptyList) => {
|
||||||
let a2 = self[temp_v!(2)].clone();
|
|
||||||
let chars = vec![
|
let chars = vec![
|
||||||
Addr::Con(Constant::CharCode('[' as u8)),
|
Addr::Con(Constant::CharCode('[' as u32)),
|
||||||
Addr::Con(Constant::CharCode(']' as u8)),
|
Addr::Con(Constant::CharCode(']' as u32)),
|
||||||
];
|
];
|
||||||
|
|
||||||
let list_of_codes = Addr::HeapCell(self.heap.to_list(chars.into_iter()));
|
let list_of_codes = Addr::HeapCell(self.heap.to_list(chars.into_iter()));
|
||||||
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
self.unify(a2, list_of_codes);
|
self.unify(a2, list_of_codes);
|
||||||
}
|
}
|
||||||
@@ -718,14 +745,15 @@ impl MachineState {
|
|||||||
Ok(addrs) => {
|
Ok(addrs) => {
|
||||||
let mut chars = String::new();
|
let mut chars = String::new();
|
||||||
|
|
||||||
for addr in addrs.iter() {
|
for addr in addrs {
|
||||||
match addr {
|
match addr {
|
||||||
&Addr::Con(Constant::Integer(ref n)) => {
|
Addr::Con(Constant::Integer(n)) => {
|
||||||
let c = self.int_to_char_code(&n, "atom_codes", 2)?;
|
let c = self.int_to_char_code(&n, "atom_codes", 2)?;
|
||||||
chars.push(c as char);
|
chars.push(std::char::from_u32(c).unwrap());
|
||||||
|
}
|
||||||
|
Addr::Con(Constant::CharCode(c)) => {
|
||||||
|
chars.push(std::char::from_u32(c).unwrap());
|
||||||
}
|
}
|
||||||
&Addr::Con(Constant::CharCode(c)) =>
|
|
||||||
chars.push(c as char),
|
|
||||||
_ => {
|
_ => {
|
||||||
let err = MachineError::type_error(
|
let err = MachineError::type_error(
|
||||||
ValidType::Integer,
|
ValidType::Integer,
|
||||||
@@ -754,7 +782,7 @@ impl MachineState {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let len = Integer::from(atom.as_str().len());
|
let len = Integer::from(atom.as_str().chars().count());
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
self.unify(a2, Addr::Con(Constant::Integer(len)));
|
self.unify(a2, Addr::Con(Constant::Integer(len)));
|
||||||
@@ -831,7 +859,7 @@ impl MachineState {
|
|||||||
let codes = string
|
let codes = string
|
||||||
.trim()
|
.trim()
|
||||||
.chars()
|
.chars()
|
||||||
.map(|c| Addr::Con(Constant::CharCode(c as u8)));
|
.map(|c| Addr::Con(Constant::CharCode(c as u32)));
|
||||||
let codes_list = Addr::HeapCell(self.heap.to_list(codes));
|
let codes_list = Addr::HeapCell(self.heap.to_list(codes));
|
||||||
|
|
||||||
self.unify(codes_list, chs);
|
self.unify(codes_list, chs);
|
||||||
@@ -841,10 +869,9 @@ impl MachineState {
|
|||||||
|
|
||||||
match self.try_from_list(temp_v!(1), stub.clone()) {
|
match self.try_from_list(temp_v!(1), stub.clone()) {
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
Ok(addrs) => match self.try_code_list(addrs) {
|
Ok(addrs) => match self.try_char_list(addrs) {
|
||||||
Ok(codes) => {
|
Ok(chars) => {
|
||||||
let string = codes.iter().map(|c| *c as char).collect();
|
self.parse_number_from_string(chars, indices, stub)?
|
||||||
self.parse_number_from_string(string, indices, stub)?
|
|
||||||
}
|
}
|
||||||
Err(err) => return Err(self.error_form(err, stub)),
|
Err(err) => return Err(self.error_form(err, stub)),
|
||||||
},
|
},
|
||||||
@@ -878,22 +905,24 @@ impl MachineState {
|
|||||||
let c = name.as_str().chars().next().unwrap();
|
let c = name.as_str().chars().next().unwrap();
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
self.unify(Addr::Con(Constant::CharCode(c as u8)), a2);
|
self.unify(Addr::Con(Constant::CharCode(c as u32)), a2);
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::Char(c)) => {
|
Addr::Con(Constant::Char(c)) => {
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
self.unify(Addr::Con(Constant::CharCode(c as u8)), a2);
|
self.unify(Addr::Con(Constant::CharCode(c as u32)), a2);
|
||||||
}
|
}
|
||||||
ref addr if addr.is_ref() => {
|
ref addr if addr.is_ref() => {
|
||||||
let a2 = self[temp_v!(2)].clone();
|
let a2 = self[temp_v!(2)].clone();
|
||||||
|
|
||||||
match self.store(self.deref(a2)) {
|
match self.store(self.deref(a2)) {
|
||||||
Addr::Con(Constant::CharCode(code)) => {
|
Addr::Con(Constant::Char(code)) => {
|
||||||
self.unify(Addr::Con(Constant::Char(code as char)), addr.clone())
|
self.unify(Addr::Con(Constant::Char(code)), addr.clone())
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::Integer(n)) => {
|
Addr::Con(Constant::Integer(n)) => {
|
||||||
let c = self.int_to_char_code(&n, "char_code", 2)?;
|
let c = self.int_to_char_code(&n, "char_code", 2)?;
|
||||||
self.unify(Addr::Con(Constant::Char(c as char)), addr.clone());
|
let c = std::char::from_u32(c).unwrap();
|
||||||
|
|
||||||
|
self.unify(Addr::Con(Constant::Char(c)), addr.clone());
|
||||||
}
|
}
|
||||||
_ => self.fail = true,
|
_ => self.fail = true,
|
||||||
};
|
};
|
||||||
@@ -2325,7 +2354,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let mut h = self.heap.h;
|
let mut h = self.heap.h;
|
||||||
let mut functors = vec![];
|
let mut functors = vec![];
|
||||||
|
|
||||||
walk_code(
|
walk_code(
|
||||||
&code_repo.code,
|
&code_repo.code,
|
||||||
first_idx,
|
first_idx,
|
||||||
@@ -2334,10 +2363,10 @@ impl MachineState {
|
|||||||
functors.push(Addr::HeapCell(h));
|
functors.push(Addr::HeapCell(h));
|
||||||
|
|
||||||
h += section.len();
|
h += section.len();
|
||||||
self.heap.extend(section.into_iter());
|
self.heap.extend(section.into_iter());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
|
let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
|
||||||
let listing_var = self[temp_v!(3)].clone();
|
let listing_var = self[temp_v!(3)].clone();
|
||||||
|
|
||||||
|
|||||||
@@ -209,10 +209,10 @@ impl<'a, R: Read> TermStream<'a, R> {
|
|||||||
|
|
||||||
self.wam
|
self.wam
|
||||||
.code_repo
|
.code_repo
|
||||||
.compile_hook(CompileTimeHook::TermExpansion, self.flags)?;
|
.compile_hook(CompileTimeHook::TermExpansion)?;
|
||||||
self.wam
|
self.wam
|
||||||
.code_repo
|
.code_repo
|
||||||
.compile_hook(CompileTimeHook::GoalExpansion, self.flags)?;
|
.compile_hook(CompileTimeHook::GoalExpansion)?;
|
||||||
|
|
||||||
Ok(ExpansionAdditionResult {
|
Ok(ExpansionAdditionResult {
|
||||||
term_expansion_additions,
|
term_expansion_additions,
|
||||||
|
|||||||
@@ -828,10 +828,6 @@ impl RelationWorker {
|
|||||||
Err(ParserError::InadmissibleQueryTerm)
|
Err(ParserError::InadmissibleQueryTerm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
("partial_string", 2) => {
|
|
||||||
let ct = ClauseType::BuiltIn(BuiltInClauseType::PartialString);
|
|
||||||
return Ok(QueryTerm::Clause(Cell::default(), ct, terms, false));
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
let ct = indices.get_clause_type(name, terms.len(), fixity);
|
let ct = indices.get_clause_type(name, terms.len(), fixity);
|
||||||
Ok(QueryTerm::Clause(Cell::default(), ct, terms, false))
|
Ok(QueryTerm::Clause(Cell::default(), ct, terms, false))
|
||||||
@@ -1190,7 +1186,6 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
|
|||||||
&result,
|
&result,
|
||||||
&mut indices.term_stream.wam.indices.in_situ_code_dir,
|
&mut indices.term_stream.wam.indices.in_situ_code_dir,
|
||||||
&mut indices.term_stream.wam.indices.in_situ_module_dir,
|
&mut indices.term_stream.wam.indices.in_situ_module_dir,
|
||||||
indices.term_stream.flags,
|
|
||||||
&self.non_counted_bt_preds,
|
&self.non_counted_bt_preds,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -106,16 +106,6 @@ macro_rules! is_var {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! is_partial_string {
|
|
||||||
($r:expr) => {
|
|
||||||
call_clause!(
|
|
||||||
ClauseType::Inlined(InlinedClauseType::IsPartialString($r)),
|
|
||||||
1,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! call_clause {
|
macro_rules! call_clause {
|
||||||
($ct:expr, $arity:expr, $pvs:expr) => {
|
($ct:expr, $arity:expr, $pvs:expr) => {
|
||||||
Line::Control(ControlInstruction::CallClause(
|
Line::Control(ControlInstruction::CallClause(
|
||||||
|
|||||||
Reference in New Issue
Block a user