]> Repositorios git - scryer-prolog.git/commitdiff
remove partial strings, but represent strings as lists when warranted by double_quotes
authorMark Thom <[email protected]>
Thu, 13 Feb 2020 05:12:42 +0000 (22:12 -0700)
committerMark Thom <[email protected]>
Thu, 13 Feb 2020 05:12:42 +0000 (22:12 -0700)
19 files changed:
Cargo.lock
Cargo.toml
src/prolog/clause_types.rs
src/prolog/codegen.rs
src/prolog/heap_iter.rs
src/prolog/heap_print.rs
src/prolog/indexing.rs
src/prolog/lib/builtins.pl
src/prolog/machine/code_repo.rs
src/prolog/machine/compile.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/modules.rs
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/machine/toplevel.rs
src/prolog/macros.rs

index 535177e5f765f9647929a23420583ddd90b8222e..2e982c05fac9a3cc5f8e3cac472af3704e5ae621 100644 (file)
@@ -316,8 +316,7 @@ dependencies = [
 
 [[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)",
@@ -453,7 +452,7 @@ dependencies = [
  "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)",
@@ -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 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"
index 0b70510cf09ae5e897fecd2860b8e59b948131e1..d044eec8cac82ae72eada2f836bb5df7de9c209c 100644 (file)
@@ -24,7 +24,7 @@ libc = "0.2.62"
 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"
index 78670b655c37253d8d4ecbac2ab1f65102ef42a8..7d61cab7bfbbade245926f906e3a7b48cef0faa2 100644 (file)
@@ -78,7 +78,6 @@ pub enum InlinedClauseType {
     IsString(RegType),
     IsFloat(RegType),
     IsNonVar(RegType),
-    IsPartialString(RegType),
     IsVar(RegType),
 }
 
@@ -109,7 +108,6 @@ ref_thread_local! {
         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));
@@ -127,7 +125,6 @@ ref_thread_local! {
         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));
 
@@ -147,7 +144,6 @@ impl InlinedClauseType {
             &InlinedClauseType::IsString(..) => "string",
             &InlinedClauseType::IsFloat(..) => "float",
             &InlinedClauseType::IsNonVar(..) => "nonvar",
-            &InlinedClauseType::IsPartialString(..) => "is_partial_string",
             &InlinedClauseType::IsVar(..) => "var",
         }
     }
@@ -545,7 +541,6 @@ pub enum BuiltInClauseType {
     KeySort,
     Nl,
     NotEq,
-    PartialString,
     Read,
     Sort,
 }
@@ -577,7 +572,6 @@ impl BuiltInClauseType {
             &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"),
         }
@@ -598,7 +592,6 @@ impl BuiltInClauseType {
             &BuiltInClauseType::KeySort => 2,
             &BuiltInClauseType::NotEq => 2,
             &BuiltInClauseType::Nl => 0,
-            &BuiltInClauseType::PartialString => 1,
             &BuiltInClauseType::Read => 1,
             &BuiltInClauseType::Sort => 2,
         }
index 0b5d6f63cc31a4ddbe1b18f2cc3a111610278bc6..eadbdded24341e208bef86893c8e7947481dafea 100644 (file)
@@ -18,7 +18,6 @@ use std::rc::Rc;
 use std::vec::Vec;
 
 pub struct CodeGenerator<TermMarker> {
-    flags: MachineFlags,
     marker: TermMarker,
     pub var_count: IndexMap<Rc<Var>, usize>,
     non_counted_bt: bool,
@@ -107,12 +106,11 @@ impl<'a> ConjunctInfo<'a> {
 }
 
 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,
         }
     }
 
@@ -435,7 +433,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
                 }
             },
             &InlinedClauseType::IsString(..) => match terms[0].as_ref() {
-                &Term::Constant(_, Constant::String(_)) => {
+                &Term::Constant(_, Constant::String(..)) => {
                     code.push(succeed!());
                 }
                 &Term::Var(ref vr, ref name) => {
@@ -459,8 +457,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
                 }
             },
             &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) => {
@@ -483,13 +480,6 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
                     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(())
@@ -867,7 +857,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker> {
         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();
 
index 85afd015679b2650089d81524ad882a2ec254934..13f2b3557e7b9557162f2af9ac7e257387dba1fe 100644 (file)
@@ -46,39 +46,42 @@ impl<'a> HCPreOrderIterator<'a> {
         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.
+            }
         }
     }
 }
@@ -88,11 +91,15 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
 
     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)
+            }
         })
     }
 }
index aa3c97097b97de20c3fcf63a736774aeac98a8a3..a89bbd4a4c37a3a9641589ebe47d4311465d9966 100644 (file)
@@ -1,5 +1,4 @@
 use prolog_parser::ast::*;
-use prolog_parser::string_list::*;
 
 use crate::prolog::clause_types::*;
 use crate::prolog::forms::*;
@@ -12,7 +11,7 @@ use crate::prolog::rug::Integer;
 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;
 
@@ -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)) => {
                 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();
@@ -806,51 +808,38 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
                 } 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('"');        
         }
     }
 
index dddd7ef7cf0d8b3b44fc2bad1e957403eb0c1972..032087338553bf23688faa75b0b44c53f3e4c9ab 100644 (file)
@@ -15,16 +15,14 @@ enum IntIndex {
 }
 
 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(),
@@ -65,18 +63,15 @@ impl CodeOffsets {
                 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());
@@ -260,8 +255,8 @@ impl CodeOffsets {
         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
                 }
                 _ => {}
index 38a5fe39959fa23566f286085ea68b647eedf620..5092d4c5603d1787e79e66566e33fae729eb943f 100644 (file)
@@ -928,8 +928,12 @@ must_be_number(N, PI) :-
     ;  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) :-
@@ -943,8 +947,12 @@ 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) :-
index ac780f38866cbb540e6e3bf397527f68292ed384..ac672d5a21bedba8d4d46a8ebd1c974ef9e03e71 100644 (file)
@@ -1,5 +1,3 @@
-use prolog_parser::ast::MachineFlags;
-
 use crate::prolog::clause_types::*;
 use crate::prolog::codegen::*;
 use crate::prolog::debray_allocator::*;
@@ -67,7 +65,6 @@ impl CodeRepo {
         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;
@@ -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)?;
 
-        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()))
     }
index efb62cda764deee06c5f34984149bd908041e944..ffa6d5171b3c5837511a9222d6a9e633cf695ea2 100644 (file)
@@ -196,11 +196,10 @@ pub fn compile_appendix(
     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());
     }
@@ -230,7 +229,6 @@ impl CodeRepo {
     pub fn compile_hook(
         &mut self,
         hook: CompileTimeHook,
-        flags: MachineFlags,
     ) -> Result<(), ParserError> {
         let key = (hook.name(), hook.arity());
 
@@ -238,10 +236,10 @@ impl CodeRepo {
             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();
 
@@ -260,7 +258,7 @@ impl CodeRepo {
                         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)?;
                     }
                 }
@@ -269,7 +267,7 @@ impl CodeRepo {
                         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)?;
                     }
                 }
@@ -281,13 +279,12 @@ impl CodeRepo {
 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()))
 }
 
@@ -345,7 +342,7 @@ pub(super) fn compile_into_module<R: Read>(
                 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)
         }
     }
@@ -363,10 +360,8 @@ fn compile_into_module_impl<R: Read>(
     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)?;
 
@@ -400,7 +395,7 @@ fn compile_into_module_impl<R: Read>(
 
     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 {
@@ -462,14 +457,14 @@ impl ClauseCodeGenerator {
             );
 
             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());
@@ -735,12 +730,11 @@ impl ListingCompiler {
 
     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)
     }
@@ -766,13 +760,12 @@ impl ListingCompiler {
                 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();
 
@@ -934,7 +927,7 @@ impl ListingCompiler {
 
                 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);
@@ -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 (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) {
@@ -1244,10 +1237,8 @@ fn compile_work_impl(
         }
     }
 
-    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 {
@@ -1280,7 +1271,7 @@ fn compile_work_impl(
 
         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(
@@ -1292,9 +1283,7 @@ fn compile_work_impl(
         )?;
     }
 
-    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) {
@@ -1370,7 +1359,7 @@ pub fn compile_listing<R: Read>(
 
     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)
index 8670f9bf64d9bfce329cd7f7c206f6908715d763..5596d71b6f7a394399b1f042e347901f61836433 100644 (file)
@@ -1,11 +1,12 @@
 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)]
@@ -392,7 +393,7 @@ pub(super) enum CycleSearchResult {
     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).
 }
 
index 3aaeeb7496be1860d68e6cce20b6268296b11c62..ab7c9b04ccb29944e3d75cc897ae6f89bfc64a88 100644 (file)
@@ -1,5 +1,4 @@
 use prolog_parser::ast::*;
-use prolog_parser::string_list::*;
 
 use crate::prolog::clause_types::*;
 use crate::prolog::forms::*;
@@ -250,8 +249,6 @@ pub struct MachineState {
     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.
@@ -265,72 +262,58 @@ pub struct 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 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,
@@ -379,7 +362,7 @@ impl MachineState {
                         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.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,
@@ -506,18 +482,12 @@ pub(crate) trait CallPolicy: Any {
         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);
 
@@ -546,18 +516,12 @@ pub(crate) trait CallPolicy: Any {
         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,
@@ -591,20 +555,12 @@ pub(crate) trait CallPolicy: Any {
         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,
@@ -802,15 +758,6 @@ pub(crate) trait CallPolicy: Any {
 
                 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()?;
 
@@ -1087,7 +1034,6 @@ fn cut_body(machine_st: &mut MachineState, addr: Addr) -> bool {
             if b > b0 {
                 machine_st.b = b0;
                 machine_st.tidy_trail();
-                machine_st.tidy_pstr_trail();
             }
         }
         _ => {
@@ -1174,7 +1120,6 @@ impl CutPolicy for SCCCutPolicy {
                 if b > b0 {
                     machine_st.b = b0;
                     machine_st.tidy_trail();
-                    machine_st.tidy_pstr_trail();
                 }
             }
             _ => {
index 57aeab5dcf3eb373f4dc3e995a07dfd8b570ef78..a305ab7249a8f60bc51dc1b9cbf3b7c12479618a 100644 (file)
@@ -1,5 +1,4 @@
 use prolog_parser::ast::*;
-use prolog_parser::string_list::StringList;
 use prolog_parser::tabled_rc::*;
 
 use crate::prolog::arithmetic::*;
@@ -24,7 +23,9 @@ use indexmap::{IndexMap, IndexSet};
 
 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) => {{
@@ -64,8 +65,6 @@ impl MachineState {
             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,
@@ -95,8 +94,6 @@ impl MachineState {
             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,
@@ -190,138 +187,22 @@ impl MachineState {
         }
     }
 
-    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;
             }
         }
 
@@ -346,7 +227,8 @@ impl MachineState {
         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();
 
@@ -391,29 +273,23 @@ impl MachineState {
 
                         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));
@@ -422,13 +298,6 @@ impl MachineState {
                         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;
@@ -459,7 +328,8 @@ impl MachineState {
         }
     }
 
-    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();
 
@@ -481,12 +351,20 @@ impl MachineState {
 
                 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 {
@@ -502,29 +380,23 @@ impl MachineState {
 
                         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));
@@ -533,13 +405,6 @@ impl MachineState {
                         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;
@@ -570,19 +435,6 @@ impl MachineState {
         }
     }
 
-    #[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)) => {
@@ -643,36 +495,6 @@ impl MachineState {
         }
     }
 
-    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;
@@ -708,85 +530,8 @@ impl MachineState {
         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) =>
@@ -1630,47 +1375,18 @@ impl MachineState {
         };
     }
 
-    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;
         }
     }
 
@@ -1684,10 +1400,15 @@ impl MachineState {
                 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(..)
@@ -1838,15 +1559,15 @@ impl MachineState {
 
                 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,
@@ -2155,19 +1876,17 @@ impl MachineState {
                             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);
@@ -2243,12 +1962,12 @@ impl MachineState {
                 (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 {
@@ -2269,17 +1988,18 @@ impl MachineState {
             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;
@@ -2306,10 +2026,10 @@ impl MachineState {
                     }
                 }
                 (
-                    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;
@@ -2336,7 +2056,9 @@ impl MachineState {
                     }
                 }
                 (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)),
@@ -2356,8 +2078,12 @@ impl MachineState {
                 | (
                     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(_)),
@@ -2365,11 +2091,15 @@ impl MachineState {
                 | (
                     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))),
@@ -2386,11 +2116,15 @@ impl MachineState {
                 | (
                     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))),
@@ -2407,11 +2141,15 @@ impl MachineState {
                 | (
                     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))),
@@ -2430,42 +2168,42 @@ impl MachineState {
                 | (
                     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(_)),
@@ -2492,7 +2230,7 @@ impl MachineState {
                 ) => 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, _))),
@@ -2502,7 +2240,9 @@ impl MachineState {
                         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;
@@ -2512,9 +2252,11 @@ impl MachineState {
                         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 {
@@ -2572,6 +2314,8 @@ impl MachineState {
                 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;
@@ -2610,7 +2354,7 @@ impl MachineState {
                 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,
                 };
             }
@@ -2630,14 +2374,6 @@ impl MachineState {
                     _ => 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,
-                };
-            }
         }
     }
 
@@ -2697,8 +2433,8 @@ impl MachineState {
 
         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)
@@ -2806,31 +2542,8 @@ impl MachineState {
         *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,
@@ -2851,13 +2564,15 @@ impl MachineState {
                                 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)
@@ -2879,8 +2594,12 @@ impl MachineState {
 
                 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))
@@ -2921,36 +2640,6 @@ impl MachineState {
         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();
@@ -2963,49 +2652,24 @@ impl MachineState {
         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;
                     }
                 }
@@ -3014,7 +2678,9 @@ impl MachineState {
                         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(_)),
@@ -3136,6 +2802,7 @@ impl MachineState {
        }
 
         let mut default_call_policy: Box<dyn CallPolicy> = Box::new(DefaultCallPolicy {});
+
         let call_policy = if use_default_cp {
             &mut default_call_policy
         } else {
@@ -3237,9 +2904,9 @@ impl MachineState {
                 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 =
@@ -3276,7 +2943,6 @@ impl MachineState {
                 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 =
@@ -3321,7 +2987,6 @@ impl MachineState {
                 if b > b0 {
                     self.b = b0;
                     self.tidy_trail();
-                    self.tidy_pstr_trail();
                 }
 
                 self.p += 1;
@@ -3356,7 +3021,6 @@ impl MachineState {
         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();
@@ -3364,7 +3028,6 @@ impl MachineState {
 
         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.
index ede50593ffb1cd82324e48e63125d4633be234e7..88e8eb63e1c8306fba2de6d36212f944c5adb8c9 100644 (file)
@@ -161,27 +161,27 @@ impl SubModuleUser for IndexStore {
     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(())
@@ -699,12 +699,10 @@ impl Machine {
         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();
@@ -724,12 +722,10 @@ impl Machine {
         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);
index 00bb0bc141cb295013029bbaf35e9d24905671ad..00a258bee0a9cf3b713ff0a50c60773c0cbdd3c9 100644 (file)
@@ -38,7 +38,6 @@ impl Module {
     pub fn dump_expansions(
         &self,
         code_repo: &mut CodeRepo,
-        flags: MachineFlags,
     ) -> Result<(), ParserError> {
         {
             let te = code_repo
@@ -64,8 +63,8 @@ impl Module {
             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(())
     }
index d88dad91dfb37305f413637775d39bbcb642d9cf..0fc09b97b063688dff499993d1997d641cd6dfdc 100644 (file)
@@ -1,6 +1,5 @@
 use prolog_parser::ast::*;
 use prolog_parser::parser::*;
-use prolog_parser::string_list::*;
 use prolog_parser::tabled_rc::*;
 
 use crate::prolog::clause_types::*;
@@ -88,8 +87,8 @@ impl MachineState {
                     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;
@@ -104,7 +103,9 @@ impl MachineState {
 
                     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) => 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,
         };
@@ -139,8 +140,8 @@ impl MachineState {
         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,
         };
@@ -198,10 +199,10 @@ impl MachineState {
                                 };
 
                             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 {
@@ -209,15 +210,13 @@ impl MachineState {
 
                                         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)),
                                             )
                                         }
                                     }
@@ -436,8 +435,8 @@ impl MachineState {
         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);
@@ -644,7 +643,16 @@ impl MachineState {
                         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();
@@ -682,31 +690,50 @@ impl MachineState {
 
                 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);
                     }
@@ -718,14 +745,15 @@ impl MachineState {
                             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,
@@ -754,7 +782,7 @@ impl MachineState {
                     _ => 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)));
@@ -831,7 +859,7 @@ impl MachineState {
                 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);
@@ -841,10 +869,9 @@ impl MachineState {
 
                 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)),
                     },
@@ -878,22 +905,24 @@ impl MachineState {
                         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,
                         };
@@ -2325,7 +2354,7 @@ impl MachineState {
 
                 let mut h = self.heap.h;
                 let mut functors = vec![];
-                
+
                 walk_code(
                     &code_repo.code,
                     first_idx,
@@ -2334,10 +2363,10 @@ impl MachineState {
                         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();
 
index 9af68c6730f685f732124be90a0ae60037dabbfc..9c91e55554e7ee4ed5645b19d61770ddd77a4893 100644 (file)
@@ -209,10 +209,10 @@ impl<'a, R: Read> TermStream<'a, R> {
 
         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,
index 0530222545b27ae74d4a9d7d4c4aa2ee0c8f5bb9..3078beca2d6864b2b5213f0fb2733a67d9c43ead 100644 (file)
@@ -828,10 +828,6 @@ impl RelationWorker {
                         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))
@@ -1190,7 +1186,6 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
             &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,
         )?;
 
index 667986834d7df8f639132853d2868acf51c45349..89f971e71f966222720e6dce3029bffb1e51eacd 100644 (file)
@@ -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 {
     ($ct:expr, $arity:expr, $pvs:expr) => {
         Line::Control(ControlInstruction::CallClause(