[[package]]
name = "prolog_parser"
-version = "0.8.39"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.8.40"
dependencies = [
"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)",
"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)",
"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)",
"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)",
"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 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 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"
nix = "0.15.0"
num-rug-adapter = { optional = true, version = "0.1.1" }
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"
rug = { version = "1.4.0", optional = true }
rustyline = "5.0.3"
IsString(RegType),
IsFloat(RegType),
IsNonVar(RegType),
- IsPartialString(RegType),
IsVar(RegType),
}
m.insert(("string", 1), ClauseType::Inlined(InlinedClauseType::IsString(r1)));
m.insert(("float", 1), ClauseType::Inlined(InlinedClauseType::IsFloat(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(("acyclic_term", 1), ClauseType::BuiltIn(BuiltInClauseType::AcyclicTerm));
m.insert(("arg", 3), ClauseType::BuiltIn(BuiltInClauseType::Arg));
m.insert(("keysort", 2), ClauseType::BuiltIn(BuiltInClauseType::KeySort));
m.insert(("nl", 0), ClauseType::BuiltIn(BuiltInClauseType::Nl));
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(("sort", 2), ClauseType::BuiltIn(BuiltInClauseType::Sort));
&InlinedClauseType::IsString(..) => "string",
&InlinedClauseType::IsFloat(..) => "float",
&InlinedClauseType::IsNonVar(..) => "nonvar",
- &InlinedClauseType::IsPartialString(..) => "is_partial_string",
&InlinedClauseType::IsVar(..) => "var",
}
}
KeySort,
Nl,
NotEq,
- PartialString,
Read,
Sort,
}
&BuiltInClauseType::KeySort => clause_name!("keysort"),
&BuiltInClauseType::Nl => clause_name!("nl"),
&BuiltInClauseType::NotEq => clause_name!("\\=="),
- &BuiltInClauseType::PartialString => clause_name!("partial_string"),
&BuiltInClauseType::Read => clause_name!("read"),
&BuiltInClauseType::Sort => clause_name!("sort"),
}
&BuiltInClauseType::KeySort => 2,
&BuiltInClauseType::NotEq => 2,
&BuiltInClauseType::Nl => 0,
- &BuiltInClauseType::PartialString => 1,
&BuiltInClauseType::Read => 1,
&BuiltInClauseType::Sort => 2,
}
use std::vec::Vec;
pub struct CodeGenerator<TermMarker> {
- flags: MachineFlags,
marker: TermMarker,
pub var_count: IndexMap<Rc<Var>, usize>,
non_counted_bt: bool,
}
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 {
marker: Allocator::new(),
var_count: IndexMap::new(),
non_counted_bt,
- flags,
}
}
}
},
&InlinedClauseType::IsString(..) => match terms[0].as_ref() {
- &Term::Constant(_, Constant::String(_)) => {
+ &Term::Constant(_, Constant::String(..)) => {
code.push(succeed!());
}
&Term::Var(ref vr, ref name) => {
}
},
&InlinedClauseType::IsInteger(..) => match terms[0].as_ref() {
- &Term::Constant(_, Constant::CharCode(_))
- | &Term::Constant(_, Constant::Integer(_)) => {
+ &Term::Constant(_, Constant::Integer(_)) => {
code.push(succeed!());
}
&Term::Var(ref vr, ref name) => {
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(())
clauses: &'b [PredicateClause],
) -> Result<Code, ParserError> {
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 da = self.machine_st.store(self.machine_st.deref(addr));
match da {
- Addr::Con(Constant::String(ref s)) => {
- match self.machine_st.machine_flags().double_quotes {
- DoubleQuotes::Chars => {
- 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::Char(c)));
+ Addr::Con(Constant::String(n, s)) => {
+ if !self.machine_st.machine_flags().double_quotes.is_atom() {
+ if s.len() > n {
+ if let Some(c) = s[n ..].chars().next() {
+ let o = c.len_utf8();
+
+ self.state_stack.push(Addr::Con(Constant::String(n+o, s.clone())));
+
+ if self.machine_st.machine_flags().double_quotes.is_codes() {
+ 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) => {
self.state_stack.push(Addr::HeapCell(a + 1));
self.state_stack.push(Addr::HeapCell(a));
da
}
- Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => da,
- Addr::Str(s) => self.follow_heap(s), // record terms of structure.
+ Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
+ da
+ }
+ Addr::Str(s) => {
+ self.follow_heap(s) // record terms of structure.
+ }
}
}
}
fn next(&mut self) -> Option<Self::Item> {
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) => {
HeapCellValue::Addr(self.machine_st.stack.index_and_frame(fr)[sc].clone())
}
- da => HeapCellValue::Addr(da),
+ da => {
+ HeapCellValue::Addr(da)
+ }
})
}
}
use prolog_parser::ast::*;
-use prolog_parser::string_list::*;
use crate::prolog::clause_types::*;
use crate::prolog::forms::*;
use indexmap::{IndexMap, IndexSet};
use std::cell::Cell;
-use std::iter::once;
+use std::iter::{FromIterator, once};
use std::ops::{Range, RangeFrom};
use std::rc::Rc;
});
}
}
+ Constant::CharCode(c) => {
+ self.append_str(&format!("{}", c as u32));
+ }
Constant::Char(c) if non_quoted_token(once(c)) => {
let c = char_to_string(c);
push_space_if_amb!(self, &c, {
self.append_str(c.as_str());
- });
+ });
}
Constant::Char(c) => {
let mut result = String::new();
} else {
result += &char_to_string(c);
}
-
+
push_space_if_amb!(self, &result, {
self.append_str(result.as_str());
- });
+ });
}
- Constant::CharCode(c) => self.append_str(&format!("{}", c)),
Constant::CutPoint(b) => self.append_str(&format!("{}", b)),
Constant::EmptyList => self.append_str("[]"),
Constant::Integer(n) => self.print_number(Number::Integer(n), op),
Constant::Float(n) => self.print_number(Number::Float(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)),
}
}
- fn print_string(&mut self, s: StringList) {
- match self.machine_st.machine_flags().double_quotes {
- DoubleQuotes::Chars | DoubleQuotes::Codes => {
- if !s.is_empty() {
- if self.ignore_ops {
- self.format_struct(2, clause_name!("."));
- } else {
- self.push_list();
- }
- } else if s.is_expandable() {
- if !self.at_cdr("|_") {
- self.push_char('_');
- }
- } else if !self.at_cdr("") {
- self.append_str("[]");
+ fn print_string(&mut self, offset: usize, s: Rc<String>) {
+ if !self.machine_st.machine_flags().double_quotes.is_atom() {
+ if !s[offset ..].is_empty() {
+ if self.ignore_ops {
+ self.format_struct(2, clause_name!("."));
+ } else {
+ self.push_list();
}
+ } else if !self.at_cdr("") {
+ self.append_str("[]");
}
- DoubleQuotes::Atom => {
- let borrowed_str = s.borrow();
- let mut atom = String::new();
-
- for c in borrowed_str[s.cursor()..].chars() {
- atom += &char_to_string(c);
- }
+ } else {
+ let atom = String::from_iter(s[offset ..].chars().map(char_to_string));
- self.push_char('"');
- self.append_str(&atom);
- self.push_char('"');
- }
+ self.push_char('"');
+ self.append_str(&atom);
+ self.push_char('"');
}
}
}
pub struct CodeOffsets {
- flags: MachineFlags,
pub constants: IndexMap<Constant, ThirdLevelIndex>,
pub lists: ThirdLevelIndex,
pub structures: IndexMap<(ClauseName, usize), ThirdLevelIndex>,
}
impl CodeOffsets {
- pub fn new(flags: MachineFlags) -> Self {
+ pub fn new() -> Self {
CodeOffsets {
- flags,
constants: IndexMap::new(),
lists: Vec::new(),
structures: IndexMap::new(),
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_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() =>
- {
+ &Term::Constant(_, Constant::String(n, ref s)) => {
let is_initial_index = self.lists.is_empty();
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) => {
let code = self.constants.entry(constant.clone()).or_insert(Vec::new());
for (index, line) in prelude.iter_mut().enumerate() {
match line {
&mut Line::IndexedChoice(IndexedChoiceInstruction::Try(ref mut i))
- | &mut Line::IndexedChoice(IndexedChoiceInstruction::Retry(ref mut i))
- | &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => {
+ | &mut Line::IndexedChoice(IndexedChoiceInstruction::Retry(ref mut i))
+ | &mut Line::IndexedChoice(IndexedChoiceInstruction::Trust(ref mut i)) => {
*i += prelude_length - index
}
_ => {}
; throw(error(instantiation_error, PI))
).
-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, _) :- var(Cs), !.
+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([C|Cs], PI) :-
; chars_or_vars(Cs, PI)
).
-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, _) :- var(Cs), !.
+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([C|Cs], PI) :-
-use prolog_parser::ast::MachineFlags;
-
use crate::prolog::clause_types::*;
use crate::prolog::codegen::*;
use crate::prolog::debray_allocator::*;
result: &CompiledResult,
in_situ_code_dir: &mut InSituCodeDir,
in_situ_module_dir: &mut ModuleStubDir,
- flags: MachineFlags,
non_counted_bt_preds: &IndexSet<PredicateKey>,
) -> Result<(), SessionError> {
let (ref decl, ref queue) = result;
}
}
- 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)?;
- 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()))
}
code: &mut Code,
queue: &VecDeque<TopLevel>,
non_counted_bt: bool,
- flags: MachineFlags,
) -> Result<(), ParserError> {
for tl in queue.iter() {
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)?;
code.extend(decl_code.into_iter());
}
pub fn compile_hook(
&mut self,
hook: CompileTimeHook,
- flags: MachineFlags,
) -> Result<(), ParserError> {
let key = (hook.name(), hook.arity());
Some(ref mut preds) => {
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)?;
- compile_appendix(&mut code, &preds.1, false, flags)?;
+ compile_appendix(&mut code, &preds.1, false)?;
(preds.0).0.pop();
let mut preds = Predicate::new();
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)?;
}
}
let mut preds = Predicate::new();
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)?;
}
}
fn compile_query(
terms: Vec<QueryTerm>,
queue: VecDeque<TopLevel>,
- flags: MachineFlags,
) -> Result<(Code, AllocVarDict), ParserError> {
// 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)?;
- compile_appendix(&mut code, &queue, false, flags)?;
+ compile_appendix(&mut code, &queue, false)?;
Ok((code, cg.take_vars()))
}
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)
}
}
let module_name = module.module_decl.name.clone();
compiler.module = Some(module);
- let flags = wam.machine_flags();
-
- wam.code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
- wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?;
+ wam.code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
+ wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
let mut results = compiler.gather_items(wam, src, &mut indices)?;
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 {
);
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(
&mut cg,
&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.code.extend(decl_code.into_iter());
fn generate_init_goal_code(
&mut self,
- flags: MachineFlags
) -> Result<Code, SessionError> {
let query_terms = mem::replace(&mut self.initialization_goals.0, vec![]);
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_err(SessionError::from)
}
self.localize_self_calls(key, in_situ_code, *in_situ_p, p + *in_situ_p);
}
None => {
- let flags = wam.machine_flags();
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)?;
- compile_appendix(&mut decl_code, &queue, false, flags)?;
+ compile_appendix(&mut decl_code, &queue, false)?;
let in_situ_p = in_situ_code.len();
let result = wam
.code_repo
- .compile_hook(hook, flags)
+ .compile_hook(hook)
.map_err(SessionError::from);
wam.code_repo.truncate_terms(key, len, queue_len);
})
}
- 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 (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!("goal_expansion"), 2), ge_len, ge_queue_len);
- discard_result!(code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags));
- discard_result!(code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags));
+ discard_result!(code_repo.compile_hook(CompileTimeHook::UserGoalExpansion));
+ discard_result!(code_repo.compile_hook(CompileTimeHook::UserTermExpansion));
}
fn print_error(&self, e: &SessionError) {
}
}
- let flags = wam.machine_flags();
-
- wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion, flags)?;
- wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion, flags)?;
+ wam.code_repo.compile_hook(CompileTimeHook::UserTermExpansion)?;
+ wam.code_repo.compile_hook(CompileTimeHook::UserGoalExpansion)?;
if let Some(mut module) = compiler.module.take() {
if module.is_impromptu_module {
add_toplevel(wam, results.toplevel_indices, top_level_term_dir);
wam.code_repo.code.extend(code.into_iter());
-
+
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
} else {
add_non_module_code(
)?;
}
- let init_goal_code = compiler.generate_init_goal_code(
- wam.machine_flags()
- )?;
+ let init_goal_code = compiler.generate_init_goal_code()?;
if init_goal_code.len() > 0 {
if !wam.run_init_code(init_goal_code) {
match compile_work(&mut compiler, wam, src, indices) {
EvalSession::Error(e) => {
- compiler.drop_expansions(wam.machine_flags(), &mut wam.code_repo);
+ compiler.drop_expansions(&mut wam.code_repo);
compiler.print_error(&e);
EvalSession::Error(e)
use prolog_parser::ast::*;
-use prolog_parser::string_list::*;
use crate::prolog::forms::PredicateKey;
use crate::prolog::machine::machine_indices::*;
use crate::prolog::machine::machine_state::*;
use crate::prolog::rug::Integer;
+use std::rc::Rc;
+
pub(crate) type MachineStub = Vec<HeapCellValue>;
#[derive(Clone, Copy)]
NotList,
PartialList(usize, usize), // the list length (up to max), and an offset into the heap.
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).
}
use prolog_parser::ast::*;
-use prolog_parser::string_list::*;
use crate::prolog::clause_types::*;
use crate::prolog::forms::*;
pub(crate) stack: Stack,
pub(super) registers: Registers,
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) hb: usize,
pub(super) block: usize, // an offset into the OR stack.
}
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 iter = addrs.iter();
while let Some(addr) = iter.next() {
- match addr {
- &Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => {
- chars += s.borrow().as_str();
-
- if iter.next().is_some() {
- 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();
+ match addr {
+ &Addr::Con(Constant::String(n, ref s))
+ if self.flags.double_quotes.is_chars() => {
+ if s.len() < n {
+ chars += &s[n ..];
+ }
+
+ if iter.next().is_some() {
+ return Err(MachineError::type_error(ValidType::Character, addr.clone()));
+ }
+ }
+ &Addr::Con(Constant::Char(c)) => {
+ chars.push(c);
}
- _ => return Err(MachineError::type_error(ValidType::Character, addr.clone())),
- }
- }
-
- Ok(chars)
- }
-
- pub(super) fn try_code_list(&self, addrs: Vec<Addr>) -> Result<Vec<u8>, MachineError> {
- let mut codes = vec![];
- 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::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::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)
+ Ok(chars)
}
- pub(super) fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
+ pub(super)
+ fn call_at_index(&mut self, arity: usize, p: LocalCodePtr) {
self.cp.assign_if_local(self.p.clone() + 1);
self.num_of_args = arity;
self.b0 = self.b;
self.p = CodePtr::Local(p);
}
- pub(super) fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
+ pub(super)
+ fn execute_at_index(&mut self, arity: usize, p: LocalCodePtr) {
self.num_of_args = arity;
self.b0 = self.b;
self.p = CodePtr::Local(p);
}
- pub(super) fn module_lookup(
+ pub(super)
+ fn module_lookup(
&mut self,
indices: &IndexStore,
key: PredicateKey,
self.call_at_index(arity, LocalCodePtr::InSituDirEntry(p));
}
- return Ok(());
+ return Ok(());
}
_ => {}
}
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.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);
- let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
+ let attr_var_init_queue_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(
attr_var_init_queue_b,
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.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);
- let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
+ let attr_var_init_queue_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(attr_var_init_queue_b, attr_var_init_bindings_b);
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.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);
- let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
+ let attr_var_init_queue_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(
attr_var_init_queue_b,
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.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);
- let attr_var_init_queue_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
- let attr_var_init_bindings_b = machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
+ let attr_var_init_queue_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_queue_b;
+ let attr_var_init_bindings_b =
+ machine_st.stack.index_or_frame(b).prelude.attr_var_init_bindings_b;
machine_st.attr_var_init.backtrack(
attr_var_init_queue_b,
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 => {
machine_st.check_sort_errors()?;
if b > b0 {
machine_st.b = b0;
machine_st.tidy_trail();
- machine_st.tidy_pstr_trail();
}
}
_ => {
if b > b0 {
machine_st.b = b0;
machine_st.tidy_trail();
- machine_st.tidy_pstr_trail();
}
}
_ => {
use prolog_parser::ast::*;
-use prolog_parser::string_list::StringList;
use prolog_parser::tabled_rc::*;
use crate::prolog::arithmetic::*;
use std::cmp::{max, min, Ordering};
use std::f64;
+use std::iter::FromIterator;
use std::mem;
+use std::rc::Rc;
macro_rules! try_numeric_result {
($s: ident, $e: expr, $caller: expr) => {{
stack: Stack::new(),
registers: vec![Addr::HeapCell(0); MAX_ARITY + 1], // self.registers[0] is never used.
trail: vec![],
- pstr_trail: vec![],
- pstr_tr: 0,
tr: 0,
hb: 0,
block: 0,
stack: Stack::new(),
registers: vec![Addr::HeapCell(0); MAX_ARITY + 1], // self.registers[0] is never used.
trail: vec![],
- pstr_trail: vec![],
- pstr_tr: 0,
tr: 0,
hb: 0,
block: 0,
}
}
- pub(super) fn unify_strings(
- &mut self,
- pdl: &mut Vec<Addr>,
- s1: &mut StringList,
- s2: &mut StringList,
- ) -> bool {
- if let Some(c1) = s1.head() {
- if let Some(c2) = s2.head() {
- if c1 == c2 {
- pdl.push(Addr::Con(Constant::String(s1.tail())));
- pdl.push(Addr::Con(Constant::String(s2.tail())));
-
- return true;
- }
- } else if s2.is_expandable() {
- self.pstr_trail(s2.clone());
-
- pdl.push(Addr::Con(Constant::String(s2.push_char(c1))));
- pdl.push(Addr::Con(Constant::String(s1.tail())));
-
- return true;
- }
- } else if s1.is_expandable() {
- if let Some(c) = s2.head() {
- self.pstr_trail(s1.clone());
-
- pdl.push(Addr::Con(Constant::String(s1.push_char(c))));
- pdl.push(Addr::Con(Constant::String(s2.tail())));
- } else if s2.is_expandable() {
- return s1 == s2;
- } else {
- self.pstr_trail(s1.clone());
- s1.set_expandable(false);
- }
-
- return true;
- } else if s2.head().is_none() {
- if s2.is_expandable() {
- self.pstr_trail(s2.clone());
- }
-
- s2.set_expandable(false);
- return true;
- }
-
- false
- }
-
fn deconstruct_chars(
&mut self,
- s: &mut StringList,
- offset: usize,
- pdl: &mut Vec<Addr>,
- ) -> bool {
- if let Some(c) = s.head() {
- pdl.push(Addr::Con(Constant::String(s.tail())));
- pdl.push(Addr::HeapCell(offset + 1));
-
- pdl.push(Addr::Con(Constant::Char(c)));
- pdl.push(Addr::HeapCell(offset));
-
- return true;
- } else if s.is_expandable() {
- let prev_s = s.clone();
-
- let mut stepper = |c| {
- let new_s = s.push_char(c);
-
- pdl.push(Addr::HeapCell(offset + 1));
- pdl.push(Addr::Con(Constant::String(new_s)));
- };
-
- match self.heap[offset].clone() {
- HeapCellValue::Addr(Addr::Con(Constant::Char(c))) => {
- self.pstr_trail(prev_s);
- stepper(c);
- return true;
- }
- HeapCellValue::Addr(Addr::Con(Constant::Atom(ref a, _))) => {
- if let Some(c) = a.as_str().chars().next() {
- if c.len_utf8() == a.as_str().len() {
- self.pstr_trail(prev_s);
- stepper(c);
- return true;
- }
- }
- }
- _ => {}
- }
- }
-
- false
- }
-
- fn deconstruct_codes(
- &mut self,
- s: &mut StringList,
- offset: usize,
+ s: Rc<String>,
+ string_offset: usize,
+ list_cell: usize,
pdl: &mut Vec<Addr>,
) -> bool {
- if let Some(c) = s.head() {
- pdl.push(Addr::Con(Constant::String(s.tail())));
- pdl.push(Addr::HeapCell(offset + 1));
-
- pdl.push(Addr::Con(Constant::CharCode(c as u8)));
- pdl.push(Addr::HeapCell(offset));
-
- return true;
- } else if s.is_expandable() {
- let prev_s = s.clone();
+ if s.len() > string_offset {
+ if let Some(c) = s[string_offset ..].chars().next() {
+ pdl.push(Addr::Con(Constant::String(string_offset + c.len_utf8(), s)));
+ pdl.push(Addr::HeapCell(list_cell + 1));
- let mut stepper = |c| {
- let new_s = s.push_char(c);
+ pdl.push(Addr::Con(Constant::Char(c)));
+ pdl.push(Addr::HeapCell(list_cell));
- pdl.push(Addr::HeapCell(offset + 1));
- pdl.push(Addr::Con(Constant::String(new_s)));
- };
-
- match self.heap[offset].clone() {
- HeapCellValue::Addr(Addr::Con(Constant::CharCode(c))) => {
- self.pstr_trail(prev_s);
- stepper(c as char);
- return true;
- }
- HeapCellValue::Addr(Addr::Con(Constant::Integer(n))) => {
- if let Some(c) = n.to_u8() {
- self.pstr_trail(prev_s);
- stepper(c as char);
- return true;
- }
- }
- _ => {}
+ return true;
}
}
self.bind(r, addr);
}
- pub(super) fn unify_with_occurs_check(&mut self, a1: Addr, a2: Addr) {
+ pub(super)
+ fn unify_with_occurs_check(&mut self, a1: Addr, a2: Addr) {
let mut pdl = vec![a1, a2];
let mut tabu_list: IndexSet<(Addr, Addr)> = IndexSet::new();
self.fail = true;
}
- (Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
- | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => {
- if match self.flags.double_quotes {
- DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl),
- DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl),
- DoubleQuotes::Atom => false,
- } {
+ (Addr::Lis(a1), Addr::Con(Constant::String(n, s)))
+ | (Addr::Con(Constant::String(n, s)), Addr::Lis(a1)) => {
+ if self.deconstruct_chars(s, n, a1, &mut pdl) {
continue;
}
self.fail = true;
}
- (Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
- | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
+ (Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(n, ref s)))
+ | (Addr::Con(Constant::String(n, ref s)), Addr::Con(Constant::EmptyList))
if !self.flags.double_quotes.is_atom() =>
{
- if s.is_expandable() && s.is_empty() {
- self.pstr_trail(s.clone());
- s.set_expandable(false);
+ if n >= s.len() {
continue;
}
- self.fail = !s.is_empty();
+ self.fail = true;
}
(Addr::Lis(a1), Addr::Lis(a2)) => {
pdl.push(Addr::HeapCell(a1));
pdl.push(Addr::HeapCell(a1 + 1));
pdl.push(Addr::HeapCell(a2 + 1));
}
- (
- Addr::Con(Constant::String(ref mut s1)),
- Addr::Con(Constant::String(ref mut s2)),
- ) => {
- self.fail = !(self.unify_strings(&mut pdl, s1, s2)
- || self.unify_strings(&mut pdl, s2, s1))
- }
(Addr::Con(ref c1), Addr::Con(ref c2)) => {
if c1 != c2 {
self.fail = true;
}
}
- pub(super) fn unify(&mut self, a1: Addr, a2: Addr) {
+ pub(super)
+ fn unify(&mut self, a1: Addr, a2: Addr) {
let mut pdl = vec![a1, a2];
let mut tabu_list: IndexSet<(Addr, Addr)> = IndexSet::new();
match (d1.clone(), d2.clone()) {
(Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => {
- self.bind(Ref::AttrVar(h), addr)
+ self.bind(Ref::AttrVar(h), addr);
+ }
+ (Addr::HeapCell(h), _) => {
+ self.bind(Ref::HeapCell(h), d2);
+ }
+ (_, Addr::HeapCell(h)) => {
+ self.bind(Ref::HeapCell(h), d1);
+ }
+ (Addr::StackCell(fr, sc), _) => {
+ self.bind(Ref::StackCell(fr, sc), d2);
+ }
+ (_, Addr::StackCell(fr, sc)) => {
+ self.bind(Ref::StackCell(fr, sc), d1);
}
- (Addr::HeapCell(h), _) => self.bind(Ref::HeapCell(h), d2),
- (_, Addr::HeapCell(h)) => self.bind(Ref::HeapCell(h), d1),
- (Addr::StackCell(fr, sc), _) => self.bind(Ref::StackCell(fr, sc), d2),
- (_, Addr::StackCell(fr, sc)) => self.bind(Ref::StackCell(fr, sc), d1),
(Addr::Lis(a1), Addr::Str(a2)) | (Addr::Str(a2), Addr::Lis(a1)) => {
if let &HeapCellValue::NamedStr(n2, ref f2, _) = &self.heap[a2] {
if f2.as_str() == "." && n2 == 2 {
self.fail = true;
}
- (Addr::Lis(a1), Addr::Con(Constant::String(ref mut s)))
- | (Addr::Con(Constant::String(ref mut s)), Addr::Lis(a1)) => {
- if match self.flags.double_quotes {
- DoubleQuotes::Chars => self.deconstruct_chars(s, a1, &mut pdl),
- DoubleQuotes::Codes => self.deconstruct_codes(s, a1, &mut pdl),
- DoubleQuotes::Atom => false,
- } {
+ (Addr::Lis(a1), Addr::Con(Constant::String(n, s)))
+ | (Addr::Con(Constant::String(n, s)), Addr::Lis(a1)) => {
+ if self.deconstruct_chars(s, n, a1, &mut pdl) {
continue;
}
self.fail = true;
}
- (Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
- | (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
+ (Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(n, ref s)))
+ | (Addr::Con(Constant::String(n, ref s)), Addr::Con(Constant::EmptyList))
if !self.flags.double_quotes.is_atom() =>
{
- if s.is_expandable() && s.is_empty() {
- self.pstr_trail(s.clone());
- s.set_expandable(false);
+ if n >= s.len() {
continue;
}
- self.fail = !s.is_empty();
+ self.fail = true;
}
(Addr::Lis(a1), Addr::Lis(a2)) => {
pdl.push(Addr::HeapCell(a1));
pdl.push(Addr::HeapCell(a1 + 1));
pdl.push(Addr::HeapCell(a2 + 1));
}
- (
- Addr::Con(Constant::String(ref mut s1)),
- Addr::Con(Constant::String(ref mut s2)),
- ) => {
- self.fail = !(self.unify_strings(&mut pdl, s1, s2)
- || self.unify_strings(&mut pdl, s2, s1))
- }
(Addr::Con(ref c1), Addr::Con(ref c2)) => {
if c1 != c2 {
self.fail = true;
}
}
- #[inline]
- fn pstr_trail(&mut self, s: StringList) {
- if let Some((prev_b, prev_s, _)) = self.pstr_trail.last().cloned() {
- if prev_b == self.b && prev_s == s {
- return;
- }
- }
-
- let truncate_end = s.len() + s.cursor();
- self.pstr_trail.push((self.b, s, truncate_end));
- self.pstr_tr += 1;
- }
-
pub(super) fn trail(&mut self, r: TrailRef) {
match r {
TrailRef::Ref(Ref::HeapCell(h)) => {
}
}
- pub(super) fn unwind_pstr_trail(&mut self, a1: usize, a2: usize) {
- for i in a1..a2 {
- let (_, mut s, end) = self.pstr_trail[i].clone();
- s.truncate(end);
- }
- }
-
- pub(super) fn tidy_pstr_trail(&mut self) {
- if self.b == 0 {
- return;
- }
-
- let b = self.b;
- let mut i = self.stack.index_or_frame(b).prelude.pstr_tr;
-
- while i < self.pstr_tr {
- let str_b = self.pstr_trail[i].0;
-
- if b < str_b {
- let pstr_tr = self.pstr_tr;
- let val = self.pstr_trail[pstr_tr - 1].clone();
-
- self.pstr_trail[i] = val;
- self.pstr_tr -= 1;
- } else {
- i += 1;
- }
- }
- }
-
pub(super) fn tidy_trail(&mut self) {
if self.b == 0 {
return;
self.trail.truncate(self.tr);
}
- #[inline]
- fn write_char_to_string(&mut self, s: &mut StringList, c: char) -> bool {
- self.pstr_trail(s.clone());
-
- let new_s = s.push_char(c);
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::String(new_s))));
- false
- }
-
- fn write_constant_to_string(&mut self, s: &mut StringList, c: Constant) -> bool {
- match c {
- Constant::EmptyList if !self.flags.double_quotes.is_atom() => !s.is_empty(),
- Constant::String(ref s2) if s.is_expandable() && s2.starts_with(s) => {
- self.pstr_trail(s.clone());
- s.append_suffix(s2);
- s.set_expandable(s2.is_expandable());
- false
- }
- Constant::String(s2) => s.borrow()[s.cursor()..] != s2.borrow()[s2.cursor()..],
- Constant::Atom(ref a, _) if a.as_str().starts_with(&s.borrow()[s.cursor()..]) => {
- if let Some(c) = a.as_str().chars().next() {
- if c.len_utf8() == a.as_str().len() {
- // detect chars masquerading as atoms.
- if s.is_empty() {
- self.write_char_to_string(s, c);
- }
-
- false
- } else {
- true
- }
- } else {
- true
- }
- }
- Constant::Char(ref c) if s.is_empty() && s.is_expandable() => {
- match self.flags.double_quotes {
- DoubleQuotes::Chars => self.write_char_to_string(s, *c),
- _ => false,
- }
- }
- Constant::Char(ref c) => match self.flags.double_quotes {
- DoubleQuotes::Chars => {
- if s.borrow().chars().next() == Some(*c) && c.len_utf8() == s.len() {
- s.set_expandable(false);
- false
- } else {
- true
- }
- }
- _ => false,
- },
- Constant::CharCode(ref c) if s.is_empty() && s.is_expandable() => {
- match self.flags.double_quotes {
- DoubleQuotes::Codes => self.write_char_to_string(s, *c as char),
- _ => false,
- }
- }
- Constant::CharCode(ref c) => match self.flags.double_quotes {
- DoubleQuotes::Codes => {
- if s.borrow().chars().next() == Some(*c as char) && 1 == s.len() {
- s.set_expandable(false);
- false
- } else {
- true
- }
- }
- _ => false,
- },
- _ => true,
- }
- }
-
pub(super) fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
match self.store(self.deref(addr)) {
- Addr::Con(Constant::String(ref mut s)) => {
- self.fail = self.write_constant_to_string(s, c)
- }
Addr::Con(c1) =>
self.fail = self.eq_test(Addr::Con(c), Addr::Con(c1)),
Addr::Lis(l) =>
};
}
- fn get_char_list(&mut self, s: &StringList) {
- let h = self.heap.h;
-
- if let Some(c) = s.head() {
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail()))));
-
- self.s = h;
- self.mode = MachineMode::Read;
- } else if s.is_expandable() {
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
-
- self.s = h;
- self.mode = MachineMode::Read;
- } else {
- self.fail = true;
- }
- }
-
- fn get_code_list(&mut self, s: &StringList) {
- let h = self.heap.h;
-
- if let Some(c) = s.head() {
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::CharCode(c as u8))));
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.tail()))));
+ fn get_char_list(&mut self, offset: usize, s: Rc<String>) {
+ if let Some(c) = s[offset ..].chars().next() {
+ let h = self.heap.h;
- self.s = h;
- self.mode = MachineMode::Read;
- } else if s.is_expandable() {
- self.heap
- .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
+ self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::Char(c))));
+ self.heap.push(HeapCellValue::Addr(Addr::Con(Constant::String(
+ offset + c.len_utf8(),
+ s,
+ ))));
self.s = h;
self.mode = MachineMode::Read;
- } else {
- self.fail = true;
}
}
let addr = self.store(self.deref(self[reg].clone()));
match addr {
- Addr::Con(Constant::String(ref s)) => match self.flags.double_quotes {
- DoubleQuotes::Chars => self.get_char_list(s),
- DoubleQuotes::Codes => self.get_code_list(s),
- _ => self.fail = true,
+ Addr::Con(Constant::String(n, s)) =>
+ match self.flags.double_quotes {
+ DoubleQuotes::Chars | DoubleQuotes::Codes
+ if s.len() > n => {
+ self.get_char_list(n, s)
+ }
+ _ => {
+ self.fail = true
+ }
},
addr @ Addr::AttrVar(_)
| addr @ Addr::StackCell(..)
let offset = match addr {
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v,
- Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
- if s.is_empty() {
- if s.is_expandable() {
- v
- } else {
+ Addr::Con(Constant::String(n, ref s)) => {
+ if !self.flags.double_quotes.is_atom() {
+ if n >= s.len() {
c
+ } else {
+ l
}
} else {
- l
+ c
}
}
Addr::Con(_) => c,
self.fail = true;
}
}
- Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() && !s.is_empty() =>
+ Addr::Con(Constant::String(o, ref s))
+ if !self.flags.double_quotes.is_atom() && !s[o ..].is_empty() =>
{
if n == 1 || n == 2 {
let a3 = self[temp_v!(3)].clone();
+ let c = s[o ..].chars().next().unwrap();
+
let h_a = if n == 1 {
- if self.flags.double_quotes.is_chars() {
- Addr::Con(Constant::Char(s.head().unwrap()))
- } else {
- Addr::Con(Constant::CharCode(s.head().unwrap() as u8))
- }
+ Addr::Con(Constant::Char(c))
} else {
- Addr::Con(Constant::String(s.tail()))
+ Addr::Con(Constant::String(o + c.len_utf8(), s.clone()))
};
self.unify(a3, h_a);
(HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) =>
continue,
(HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
- HeapCellValue::Addr(Addr::Con(Constant::String(s))))
- | (HeapCellValue::Addr(Addr::Con(Constant::String(s))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n, s))))
+ | (HeapCellValue::Addr(Addr::Con(Constant::String(n, s))),
HeapCellValue::Addr(Addr::Con(Constant::EmptyList))) =>
return match self.flags.double_quotes {
DoubleQuotes::Atom => true,
- _ => !s.is_empty()
+ _ => n < s.len()
},
(HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) =>
if a1 != a2 {
match (v1, v2) {
(
HeapCellValue::Addr(Addr::Lis(_)),
- HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
)
| (
- HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
HeapCellValue::Addr(Addr::Lis(_)),
- ) if !self.flags.double_quotes.is_atom() => {}
+ ) if !self.flags.double_quotes.is_atom() => {
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n, ref s))),
) if !self.flags.double_quotes.is_atom() => {
- if s.is_empty() {
+ if s[n ..].is_empty() {
return Ordering::Equal;
} else {
return Ordering::Greater;
}
}
(
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n, ref s))),
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
) if !self.flags.double_quotes.is_atom() => {
- if s.is_empty() {
+ if s[n ..].is_empty() {
return Ordering::Equal;
} else {
return Ordering::Less;
}
}
(HeapCellValue::Addr(Addr::HeapCell(_)), _)
- | (HeapCellValue::Addr(Addr::AttrVar(_)), _) => return Ordering::Less,
+ | (HeapCellValue::Addr(Addr::AttrVar(_)), _) => {
+ return Ordering::Less;
+ }
(
HeapCellValue::Addr(Addr::StackCell(fr1, sc1)),
HeapCellValue::Addr(Addr::StackCell(fr2, sc2)),
| (
HeapCellValue::Addr(Addr::StackCell(..)),
HeapCellValue::Addr(Addr::AttrVar(_)),
- ) => return Ordering::Greater,
- (HeapCellValue::Addr(Addr::StackCell(..)), _) => return Ordering::Less,
+ ) => {
+ return Ordering::Greater;
+ }
+ (HeapCellValue::Addr(Addr::StackCell(..)), _) => {
+ return Ordering::Less;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
HeapCellValue::Addr(Addr::HeapCell(_)),
| (
HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
HeapCellValue::Addr(Addr::AttrVar(_)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Integer(..))),
HeapCellValue::Addr(Addr::StackCell(..)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Integer(n1))),
HeapCellValue::Addr(Addr::Con(Constant::Integer(n2))),
| (
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
HeapCellValue::Addr(Addr::AttrVar(_)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Float(..))),
HeapCellValue::Addr(Addr::StackCell(..)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Float(n1))),
HeapCellValue::Addr(Addr::Con(Constant::Float(n2))),
| (
HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
HeapCellValue::Addr(Addr::AttrVar(_)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Rational(..))),
HeapCellValue::Addr(Addr::StackCell(..)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::Rational(n1))),
HeapCellValue::Addr(Addr::Con(Constant::Rational(n2))),
| (
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
HeapCellValue::Addr(Addr::AttrVar(_)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
HeapCellValue::Addr(Addr::Con(Constant::String(..))),
HeapCellValue::Addr(Addr::StackCell(..)),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
- HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
HeapCellValue::Addr(Addr::Con(Constant::Integer(_))),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
- HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
HeapCellValue::Addr(Addr::Con(Constant::Rational(_))),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
- HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
HeapCellValue::Addr(Addr::Con(Constant::Float(_))),
- ) => return Ordering::Greater,
+ ) => {
+ return Ordering::Greater;
+ }
(
- HeapCellValue::Addr(Addr::Con(Constant::String(s1))),
- HeapCellValue::Addr(Addr::Con(Constant::String(s2))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n1, s1))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n2, s2))),
) => {
- return if s1.is_expandable() {
- if s2.is_expandable() {
- s1.cmp(&s2)
- } else {
- Ordering::Greater
- }
- } else {
- if s2.is_expandable() {
- Ordering::Less
- } else {
- s1.cmp(&s2)
- }
- }
+ return s1[n1 ..].cmp(&s2[n2 ..]);
+ }
+ (HeapCellValue::Addr(Addr::Con(Constant::String(..))), _) => {
+ return Ordering::Less;
}
- (HeapCellValue::Addr(Addr::Con(Constant::String(_))), _) => return Ordering::Less,
(
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
HeapCellValue::Addr(Addr::HeapCell(_)),
) => return Ordering::Greater,
(
HeapCellValue::Addr(Addr::Con(Constant::Atom(..))),
- HeapCellValue::Addr(Addr::Con(Constant::String(_))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
) => return Ordering::Greater,
(
HeapCellValue::Addr(Addr::Con(Constant::Atom(s1, _))),
return s1.cmp(&s2);
}
}
- (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) => return Ordering::Less,
+ (HeapCellValue::Addr(Addr::Con(Constant::Atom(..))), _) => {
+ return Ordering::Less;
+ }
(HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) => {
if ar1 < ar2 {
return Ordering::Less;
return n1.cmp(&n2);
}
}
- (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue,
+ (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => {
+ continue;
+ }
(HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::NamedStr(ar, n, _))
- | (HeapCellValue::NamedStr(ar, n, _), HeapCellValue::Addr(Addr::Lis(_))) => {
+ | (HeapCellValue::NamedStr(ar, n, _), HeapCellValue::Addr(Addr::Lis(_))) => {
if ar == 2 && n.as_str() == "." {
continue;
} else if ar < 2 {
match d {
Addr::Con(Constant::Integer(_)) => self.p += 1,
Addr::Con(Constant::CharCode(_)) => self.p += 1,
+ Addr::Con(Constant::Char(_))
+ if self.flags.double_quotes.is_codes() => self.p += 1,
Addr::Con(Constant::Rational(r)) => {
if r.denom() == &1 {
self.p += 1;
let d = self.store(self.deref(self[r1].clone()));
match d {
- Addr::Con(Constant::String(_)) => self.p += 1,
+ Addr::Con(Constant::String(..)) => self.p += 1,
_ => self.fail = true,
};
}
_ => self.fail = true,
};
}
- &InlinedClauseType::IsPartialString(r1) => {
- let d = self.store(self.deref(self[r1].clone()));
-
- match d {
- Addr::Con(Constant::String(ref s)) if s.is_expandable() => self.p += 1,
- _ => self.fail = true,
- };
- }
}
}
match a1.clone() {
Addr::DBRef(_) => self.fail = true,
- Addr::Con(Constant::String(ref s))
- if !self.flags.double_quotes.is_atom() && !s.is_empty() =>
+ Addr::Con(Constant::String(n, ref s))
+ if !self.flags.double_quotes.is_atom() && !s[n ..].is_empty() =>
{
let shared_op_desc = fetch_op_spec(clause_name!("."), 2, None, &indices.op_dir);
self.try_functor_compound_case(clause_name!("."), 2, shared_op_desc)
*list = result;
}
- pub(super) fn try_string_list(&self, r: RegType) -> Result<StringList, MachineStub> {
- let a1 = self[r].clone();
- let a1 = self.store(self.deref(a1));
-
- if let Addr::Con(Constant::String(s)) = a1 {
- return Ok(s);
- } else {
- let stub = MachineError::functor_stub(clause_name!("partial_string"), 2);
-
- match self.try_from_list(r, stub.clone()) {
- Ok(addrs) => Ok(StringList::new(
- match self.try_char_list(addrs) {
- Ok(string) => string,
- Err(err) => {
- return Err(self.error_form(err, stub));
- }
- },
- false,
- )),
- Err(err) => return Err(err),
- }
- }
- }
-
- pub(super) fn try_from_list(
+ pub(super)
+ fn try_from_list(
&self,
r: RegType,
caller: MachineStub,
result.push(self.heap[hcp].as_addr(hcp));
l = hcp + 1;
}
- Addr::Con(Constant::String(ref s))
+ Addr::Con(Constant::String(n, ref s))
if !self.flags.double_quotes.is_atom() =>
{
- result.push(Addr::Con(Constant::String(s.clone())));
+ result.push(Addr::Con(Constant::String(n, s.clone())));
+ break;
+ }
+ Addr::Con(Constant::EmptyList) => {
break;
}
- Addr::Con(Constant::EmptyList) => break,
Addr::HeapCell(_) | Addr::StackCell(..) => {
return Err(
self.error_form(MachineError::instantiation_error(), caller)
Ok(result)
}
- Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
- Ok(vec![Addr::Con(Constant::String(s.clone()))])
+ Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
+ if s.len() > n {
+ Ok(Vec::from_iter(s[n ..].chars().map(|c| Addr::Con(Constant::Char(c)))))
+ } else {
+ Ok(vec![])
+ }
}
Addr::HeapCell(_) | Addr::StackCell(..) => {
Err(self.error_form(MachineError::instantiation_error(), caller))
self.unify(Addr::HeapCell(old_h), a2);
}
- fn structural_char_list_test(&self, s: &StringList, list_offset: usize) -> bool {
- if !s.is_empty() {
- if let HeapCellValue::Addr(Addr::Con(constant)) = self.heap[list_offset].clone() {
- if let Some(c) = s.head() {
- // checks equality on atoms, too.
- if constant == Constant::Char(c) {
- return true;
- }
- }
- }
- }
-
- false
- }
-
- fn structural_code_list_test(&self, s: &StringList, list_offset: usize) -> bool {
- if !s.is_empty() {
- if let HeapCellValue::Addr(Addr::Con(constant)) = self.heap[list_offset].clone() {
- if let Some(c) = s.head() {
- // checks equality on integers, too.
- if constant == Constant::CharCode(c as u8) {
- return true;
- }
- }
- }
- }
-
- false
- }
-
// returns true on failure.
pub(super) fn structural_eq_test(&self) -> bool {
let a1 = self[temp_v!(1)].clone();
for (v1, v2) in iter {
match (v1, v2) {
(
- HeapCellValue::Addr(Addr::Lis(l)),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Lis(_)),
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
)
| (
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
- HeapCellValue::Addr(Addr::Lis(l)),
- ) if !self.flags.double_quotes.is_atom() => match self.flags.double_quotes {
- DoubleQuotes::Chars => {
- if self.structural_char_list_test(s, l) {
- continue;
- }
- }
- DoubleQuotes::Codes => {
- if self.structural_code_list_test(s, l) {
- continue;
- }
- }
- DoubleQuotes::Atom => unreachable!(),
- },
- (
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s1))),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s2))),
- ) => match s1.head() {
- Some(c1) => {
- if let Some(c2) = s2.head() {
- if c1 != c2 {
- return true;
- }
- } else {
- return true;
- }
- }
- None => return !s2.is_empty(),
- },
+ HeapCellValue::Addr(Addr::Con(Constant::String(..))),
+ HeapCellValue::Addr(Addr::Lis(_)),
+ ) if !self.flags.double_quotes.is_atom() => {
+ continue;
+ }
(
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n, ref s))),
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
)
| (
HeapCellValue::Addr(Addr::Con(Constant::EmptyList)),
- HeapCellValue::Addr(Addr::Con(Constant::String(ref s))),
+ HeapCellValue::Addr(Addr::Con(Constant::String(n, ref s))),
) if !self.flags.double_quotes.is_atom() => {
- if !s.is_empty() {
+ if !s[n ..].is_empty() {
return true;
}
}
return true;
}
}
- (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => continue,
+ (HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Lis(_))) => {
+ continue;
+ }
(
HeapCellValue::Addr(v1 @ Addr::HeapCell(_)),
HeapCellValue::Addr(v2 @ Addr::AttrVar(_)),
}
let mut default_call_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
+
let call_policy = if use_default_cp {
&mut default_call_policy
} else {
or_frame.prelude.b = self.b;
or_frame.prelude.bp = self.p.local() + 1;
or_frame.prelude.tr = self.tr;
- or_frame.prelude.pstr_tr = self.pstr_tr;
or_frame.prelude.h = self.heap.h;
or_frame.prelude.b0 = self.b0;
+
or_frame.prelude.attr_var_init_queue_b =
self.attr_var_init.attr_var_queue.len();
or_frame.prelude.attr_var_init_bindings_b =
or_frame.prelude.b = self.b;
or_frame.prelude.bp = self.p.local() + offset;
or_frame.prelude.tr = self.tr;
- or_frame.prelude.pstr_tr = self.pstr_tr;
or_frame.prelude.h = self.heap.h;
or_frame.prelude.b0 = self.b0;
or_frame.prelude.attr_var_init_queue_b =
if b > b0 {
self.b = b0;
self.tidy_trail();
- self.tidy_pstr_trail();
}
self.p += 1;
self.b0 = 0;
self.s = 0;
self.tr = 0;
- self.pstr_tr = 0;
self.p = CodePtr::default();
self.cp = LocalCodePtr::default();
self.attr_var_init.reset();
self.fail = false;
self.trail.clear();
- self.pstr_trail.clear();
self.heap.clear();
self.mode = MachineMode::Write;
self.registers = vec![Addr::HeapCell(0); MAX_ARITY + 1]; // self.registers[0] is never used.
fn use_qualified_module(
&mut self,
code_repo: &mut CodeRepo,
- flags: MachineFlags,
+ _: MachineFlags,
submodule: &Module,
exports: &Vec<ModuleExport>,
) -> Result<(), SessionError> {
use_qualified_module(self, submodule, exports)?;
submodule
- .dump_expansions(code_repo, flags)
+ .dump_expansions(code_repo)
.map_err(SessionError::from)
}
fn use_module(
&mut self,
code_repo: &mut CodeRepo,
- flags: MachineFlags,
+ _: MachineFlags,
submodule: &Module,
) -> Result<(), SessionError> {
use_module(self, submodule)?;
if !submodule.inserted_expansions {
submodule
- .dump_expansions(code_repo, flags)
+ .dump_expansions(code_repo)
.map_err(SessionError::from)
} else {
Ok(())
snapshot.b0 = self.machine_st.b0;
snapshot.s = self.machine_st.s;
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.fail = self.machine_st.fail;
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.mode = self.machine_st.mode;
snapshot.stack = self.machine_st.stack.take();
self.machine_st.b0 = snapshot.b0;
self.machine_st.s = snapshot.s;
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.fail = snapshot.fail;
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.truncate(0);
pub fn dump_expansions(
&self,
code_repo: &mut CodeRepo,
- flags: MachineFlags,
) -> Result<(), ParserError> {
{
let te = code_repo
ge.1.extend(self.user_goal_expansions.1.iter().cloned());
}
- code_repo.compile_hook(CompileTimeHook::TermExpansion, flags)?;
- code_repo.compile_hook(CompileTimeHook::GoalExpansion, flags)?;
+ code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
+ code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
Ok(())
}
use prolog_parser::ast::*;
use prolog_parser::parser::*;
-use prolog_parser::string_list::*;
use prolog_parser::tabled_rc::*;
use crate::prolog::clause_types::*;
brent_st.steps,
brent_st.hare,
)),
- Addr::Con(Constant::String(ref s)) if self.flags.double_quotes.is_chars() => {
- Some(CycleSearchResult::String(brent_st.steps, s.clone()))
+ Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
+ Some(CycleSearchResult::String(brent_st.steps, n, s.clone()))
}
Addr::Lis(l) => {
brent_st.hare = l + 1;
None
}
- _ => Some(CycleSearchResult::NotList),
+ _ => {
+ Some(CycleSearchResult::NotList)
+ }
},
}
}
Addr::Lis(offset) if max_steps > 0 => offset + 1,
Addr::Lis(offset) => return CycleSearchResult::UntouchedList(offset),
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
- Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
- return CycleSearchResult::String(0, s.clone())
+ Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
+ return CycleSearchResult::String(0, n, s.clone())
}
_ => return CycleSearchResult::NotList,
};
let hare = match addr {
Addr::Lis(offset) => offset + 1,
Addr::Con(Constant::EmptyList) => return CycleSearchResult::EmptyList,
- Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => {
- return CycleSearchResult::String(0, s.clone())
+ Addr::Con(Constant::String(n, ref s)) if !self.flags.double_quotes.is_atom() => {
+ return CycleSearchResult::String(0, n, s.clone())
}
_ => return CycleSearchResult::NotList,
};
};
match search_result {
- CycleSearchResult::String(n, s) => {
+ CycleSearchResult::String(n, offset, s) => {
if max_steps == -1 {
self.finalize_skip_max_list(
- n + s.len(),
+ s[offset ..].len(),
Addr::Con(Constant::EmptyList),
)
} else {
if s.len() < i {
self.finalize_skip_max_list(
- n + s.len(),
+ s[n + offset + i..].len(),
Addr::Con(Constant::EmptyList),
)
} else {
- let s =
- StringList::new(s.char_span(i), s.is_expandable());
self.finalize_skip_max_list(
- i + n,
- Addr::Con(Constant::String(s)),
+ i + n + offset,
+ Addr::Con(Constant::String(n + i + offset, s)),
)
}
}
n: &Integer,
stub: &'static str,
arity: usize,
- ) -> Result<u8, MachineStub> {
- if let Some(c) = n.to_u8() {
+ ) -> Result<u32, MachineStub> {
+ if let Some(c) = n.to_u32() {
Ok(c)
} else {
let stub = MachineError::functor_stub(clause_name!(stub), arity);
let list_of_chars = Addr::HeapCell(self.heap.to_list(iter));
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) => {
let a2 = self[temp_v!(2)].clone();
match self.store(self.deref(a1)) {
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 a2 = self[temp_v!(2)].clone();
self.unify(a2, list_of_codes);
}
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();
- 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) => {
- let a2 = self[temp_v!(2)].clone();
let chars = vec![
- Addr::Con(Constant::CharCode('[' as u8)),
- Addr::Con(Constant::CharCode(']' as u8)),
+ Addr::Con(Constant::CharCode('[' as u32)),
+ Addr::Con(Constant::CharCode(']' as u32)),
];
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);
}
Ok(addrs) => {
let mut chars = String::new();
- for addr in addrs.iter() {
+ for addr in addrs {
match addr {
- &Addr::Con(Constant::Integer(ref n)) => {
+ Addr::Con(Constant::Integer(n)) => {
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(
ValidType::Integer,
_ => 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();
self.unify(a2, Addr::Con(Constant::Integer(len)));
let codes = string
.trim()
.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));
self.unify(codes_list, chs);
match self.try_from_list(temp_v!(1), stub.clone()) {
Err(e) => return Err(e),
- Ok(addrs) => match self.try_code_list(addrs) {
- Ok(codes) => {
- let string = codes.iter().map(|c| *c as char).collect();
- self.parse_number_from_string(string, indices, stub)?
+ Ok(addrs) => match self.try_char_list(addrs) {
+ Ok(chars) => {
+ self.parse_number_from_string(chars, indices, stub)?
}
Err(err) => return Err(self.error_form(err, stub)),
},
let c = name.as_str().chars().next().unwrap();
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)) => {
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() => {
let a2 = self[temp_v!(2)].clone();
match self.store(self.deref(a2)) {
- Addr::Con(Constant::CharCode(code)) => {
- self.unify(Addr::Con(Constant::Char(code as char)), addr.clone())
+ Addr::Con(Constant::Char(code)) => {
+ self.unify(Addr::Con(Constant::Char(code)), addr.clone())
}
Addr::Con(Constant::Integer(n)) => {
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,
};
let mut h = self.heap.h;
let mut functors = vec![];
-
+
walk_code(
&code_repo.code,
first_idx,
functors.push(Addr::HeapCell(h));
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_var = self[temp_v!(3)].clone();
self.wam
.code_repo
- .compile_hook(CompileTimeHook::TermExpansion, self.flags)?;
+ .compile_hook(CompileTimeHook::TermExpansion)?;
self.wam
.code_repo
- .compile_hook(CompileTimeHook::GoalExpansion, self.flags)?;
+ .compile_hook(CompileTimeHook::GoalExpansion)?;
Ok(ExpansionAdditionResult {
term_expansion_additions,
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);
Ok(QueryTerm::Clause(Cell::default(), ct, terms, false))
&result,
&mut indices.term_stream.wam.indices.in_situ_code_dir,
&mut indices.term_stream.wam.indices.in_situ_module_dir,
- indices.term_stream.flags,
&self.non_counted_bt_preds,
)?;
};
}
-macro_rules! is_partial_string {
- ($r:expr) => {
- call_clause!(
- ClauseType::Inlined(InlinedClauseType::IsPartialString($r)),
- 1,
- 0
- )
- };
-}
-
macro_rules! call_clause {
($ct:expr, $arity:expr, $pvs:expr) => {
Line::Control(ControlInstruction::CallClause(