update to handle strings as lists.
This commit is contained in:
@@ -877,7 +877,7 @@ impl<'a> From<&'a TabledRc<Atom>> for ClauseName {
|
||||
}
|
||||
}
|
||||
|
||||
impl ClauseName {
|
||||
impl ClauseName {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
&ClauseName::BuiltIn(s) => s,
|
||||
|
||||
@@ -4,6 +4,7 @@ use prolog::ast::*;
|
||||
use prolog::fixtures::*;
|
||||
use prolog::indexing::*;
|
||||
use prolog::iterators::*;
|
||||
use prolog::machine::machine_state::MachineFlags;
|
||||
use prolog::targets::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
@@ -12,6 +13,7 @@ use std::rc::Rc;
|
||||
use std::vec::Vec;
|
||||
|
||||
pub struct CodeGenerator<TermMarker> {
|
||||
flags: MachineFlags,
|
||||
marker: TermMarker,
|
||||
var_count: HashMap<Rc<Var>, usize>,
|
||||
non_counted_bt: bool
|
||||
@@ -44,10 +46,11 @@ impl<'a> ConjunctInfo<'a>
|
||||
|
||||
impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
||||
{
|
||||
pub fn new(non_counted_bt: bool) -> Self {
|
||||
pub fn new(non_counted_bt: bool, flags: MachineFlags) -> Self {
|
||||
CodeGenerator { marker: Allocator::new(),
|
||||
var_count: HashMap::new(),
|
||||
non_counted_bt }
|
||||
non_counted_bt,
|
||||
flags }
|
||||
}
|
||||
|
||||
pub fn take_vars(self) -> AllocVarDict {
|
||||
@@ -705,7 +708,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
|
||||
-> Result<Code, ParserError>
|
||||
{
|
||||
let mut code_body = Vec::new();
|
||||
let mut code_offsets = CodeOffsets::new();
|
||||
let mut code_offsets = CodeOffsets::new(self.flags);
|
||||
|
||||
let num_clauses = clauses.len();
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ use prolog::ast::*;
|
||||
use prolog::debray_allocator::*;
|
||||
use prolog::codegen::*;
|
||||
use prolog::machine::*;
|
||||
use prolog::machine::machine_state::MachineFlags;
|
||||
use prolog::toplevel::*;
|
||||
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
@@ -39,20 +40,22 @@ pub fn parse_code(wam: &mut Machine, buffer: &str) -> Result<TopLevelPacket, Par
|
||||
{
|
||||
let atom_tbl = wam.atom_tbl();
|
||||
let string_tbl = wam.string_tbl();
|
||||
let flags = wam.machine_flags();
|
||||
|
||||
let index = MachineCodeIndices {
|
||||
code_dir: &mut wam.code_dir,
|
||||
op_dir: &mut wam.op_dir,
|
||||
};
|
||||
|
||||
let mut worker = TopLevelWorker::new(buffer.as_bytes(), atom_tbl, string_tbl, index);
|
||||
|
||||
let mut worker = TopLevelWorker::new(buffer.as_bytes(), atom_tbl, string_tbl,
|
||||
flags, index);
|
||||
worker.parse_code()
|
||||
}
|
||||
|
||||
// throw errors if declaration or query found.
|
||||
fn compile_relation(tl: &TopLevel, non_counted_bt: bool) -> Result<Code, ParserError>
|
||||
fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags) -> Result<Code, ParserError>
|
||||
{
|
||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt);
|
||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(non_counted_bt, flags);
|
||||
|
||||
match tl {
|
||||
&TopLevel::Declaration(_) | &TopLevel::Query(_) =>
|
||||
@@ -84,22 +87,25 @@ fn set_first_index(code: &mut Code)
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_appendix(code: &mut Code, queue: Vec<TopLevel>, non_counted_bt: bool) -> Result<(), ParserError>
|
||||
fn compile_appendix(code: &mut Code, queue: Vec<TopLevel>, non_counted_bt: bool, flags: MachineFlags)
|
||||
-> Result<(), ParserError>
|
||||
{
|
||||
for tl in queue.iter() {
|
||||
set_first_index(code);
|
||||
code.append(&mut compile_relation(tl, non_counted_bt)?);
|
||||
code.append(&mut compile_relation(tl, non_counted_bt, flags)?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>) -> Result<(Code, AllocVarDict), ParserError>
|
||||
fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, flags: MachineFlags)
|
||||
-> Result<(Code, AllocVarDict), ParserError>
|
||||
{
|
||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false); // count backtracking inferences.
|
||||
// count backtracking inferences.
|
||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(false, flags);
|
||||
let mut code = try!(cg.compile_query(&terms));
|
||||
|
||||
compile_appendix(&mut code, queue, false)?;
|
||||
compile_appendix(&mut code, queue, false, flags)?;
|
||||
|
||||
Ok((code, cg.take_vars()))
|
||||
}
|
||||
@@ -124,8 +130,8 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
|
||||
Err(SessionError::NamelessEntry)
|
||||
});
|
||||
|
||||
let mut code = try_eval_session!(compile_relation(&tl, false));
|
||||
try_eval_session!(compile_appendix(&mut code, queue, false));
|
||||
let mut code = try_eval_session!(compile_relation(&tl, false, wam.machine_flags()));
|
||||
try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
|
||||
|
||||
if !code.is_empty() {
|
||||
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
|
||||
@@ -140,7 +146,7 @@ pub fn compile_packet(wam: &mut Machine, tl: TopLevelPacket) -> EvalSession
|
||||
{
|
||||
match tl {
|
||||
TopLevelPacket::Query(terms, queue) =>
|
||||
match compile_query(terms, queue) {
|
||||
match compile_query(terms, queue, wam.machine_flags()) {
|
||||
Ok((mut code, vars)) => wam.submit_query(code, vars),
|
||||
Err(e) => EvalSession::from(e)
|
||||
},
|
||||
@@ -182,17 +188,15 @@ impl<'a> ListingCompiler<'a> {
|
||||
let non_counted_bt = self.non_counted_bt_preds.contains(&(name.clone(), arity));
|
||||
|
||||
let p = code.len() + self.wam.code_size();
|
||||
let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt)?;
|
||||
let mut decl_code = compile_relation(&TopLevel::Predicate(decl), non_counted_bt,
|
||||
self.wam.machine_flags())?;
|
||||
|
||||
compile_appendix(&mut decl_code, Vec::from(queue), non_counted_bt)?;
|
||||
|
||||
// println!("\n{}/{}:\n", name.as_str(), arity);
|
||||
compile_appendix(&mut decl_code, Vec::from(queue), non_counted_bt,
|
||||
self.wam.machine_flags())?;
|
||||
|
||||
let idx = code_dir.entry((name, arity)).or_insert(CodeIndex::default());
|
||||
set_code_index!(idx, IndexPtr::Index(p), self.get_module_name());
|
||||
|
||||
// print_code(&decl_code);
|
||||
|
||||
code.extend(decl_code.into_iter());
|
||||
}
|
||||
|
||||
@@ -241,7 +245,8 @@ fn use_qualified_module(module: &mut Option<Module>, submodule: &Module, exports
|
||||
pub
|
||||
fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeIndices) -> EvalSession
|
||||
{
|
||||
let mut worker = TopLevelBatchWorker::new(src_str.as_bytes(), wam.atom_tbl(), wam.string_tbl());
|
||||
let mut worker = TopLevelBatchWorker::new(src_str.as_bytes(), wam.atom_tbl(), wam.string_tbl(),
|
||||
wam.machine_flags());
|
||||
let mut compiler = ListingCompiler::new(wam);
|
||||
|
||||
while let Some(decl) = try_eval_session!(worker.consume(&mut indices)) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use prolog::ast::*;
|
||||
use prolog::num::*;
|
||||
use prolog::heap_iter::*;
|
||||
use prolog::machine::machine_state::MachineState;
|
||||
use prolog::machine::machine_state::{DoubleQuotes, MachineState};
|
||||
use prolog::ordered_float::OrderedFloat;
|
||||
use prolog::string_list::*;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
@@ -11,6 +12,7 @@ use std::rc::Rc;
|
||||
#[derive(Clone)]
|
||||
pub enum TokenOrRedirect {
|
||||
Atom(ClauseName),
|
||||
Char(char),
|
||||
NumberedVar(String),
|
||||
Redirect,
|
||||
Open,
|
||||
@@ -19,7 +21,6 @@ pub enum TokenOrRedirect {
|
||||
OpenList(Rc<Cell<bool>>),
|
||||
CloseList(Rc<Cell<bool>>),
|
||||
HeadTailSeparator,
|
||||
// Space
|
||||
}
|
||||
|
||||
pub trait HCValueFormatter {
|
||||
@@ -201,6 +202,10 @@ fn reverse_heap_locs<'a>(machine_st: &'a MachineState, heap_locs: &'a HeapVarDic
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn non_quoted_token(c: char) -> bool {
|
||||
graphic_token_char!(c) || alpha_numeric_char!(c)
|
||||
}
|
||||
|
||||
impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
||||
HCPrinter<'a, Formatter, Outputter>
|
||||
{
|
||||
@@ -275,19 +280,45 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
||||
}
|
||||
|
||||
fn print_atom(&mut self, atom: &ClauseName) {
|
||||
let non_quoted_token = |c| {
|
||||
graphic_token_char!(c) || alpha_numeric_char!(c)
|
||||
};
|
||||
|
||||
match atom.as_str() {
|
||||
";" | "!" => self.outputter.append(atom.as_str()),
|
||||
s => if s.chars().all(non_quoted_token) {
|
||||
self.outputter.append(atom.as_str());
|
||||
} else {
|
||||
self.outputter.append(&("'".to_owned() + atom.as_str() + "'"));
|
||||
self.outputter.push_char('\'');
|
||||
self.outputter.append(atom.as_str());
|
||||
self.outputter.push_char('\'');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_char_list(&mut self, s: StringList) {
|
||||
let cell = Rc::new(Cell::new(true));
|
||||
let cursor = s.cursor();
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::CloseList(cell.clone()));
|
||||
|
||||
if !s.is_empty() {
|
||||
for c in s.borrow()[cursor ..].chars().rev() {
|
||||
self.state_stack.push(TokenOrRedirect::Char(c));
|
||||
self.state_stack.push(TokenOrRedirect::Comma);
|
||||
}
|
||||
|
||||
self.state_stack.pop();
|
||||
}
|
||||
|
||||
self.state_stack.push(TokenOrRedirect::OpenList(cell));
|
||||
}
|
||||
|
||||
fn print_char(&mut self, c: char) {
|
||||
if non_quoted_token(c) {
|
||||
self.outputter.push_char(c);
|
||||
} else {
|
||||
self.outputter.push_char('\'');
|
||||
self.outputter.push_char(c);
|
||||
self.outputter.push_char('\'');
|
||||
}
|
||||
}
|
||||
|
||||
fn print_constant(&mut self, c: Constant) {
|
||||
match c {
|
||||
@@ -307,11 +338,8 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
||||
// self.outputter.append("\a"),
|
||||
// Constant::Char(c) if c == '\\v' =>
|
||||
// self.outputter.append("\\v"),
|
||||
Constant::Char(c) => {
|
||||
self.outputter.append("'");
|
||||
self.outputter.push_char(c);
|
||||
self.outputter.append("'");
|
||||
},
|
||||
Constant::Char(c) =>
|
||||
self.print_char(c),
|
||||
Constant::EmptyList =>
|
||||
self.outputter.append("[]"),
|
||||
Constant::Number(Number::Float(fl)) =>
|
||||
@@ -322,11 +350,14 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
||||
},
|
||||
Constant::Number(n) =>
|
||||
self.outputter.append(&format!("{}", n)),
|
||||
Constant::String(s) => {
|
||||
self.outputter.append("\"");
|
||||
self.outputter.append(s.borrow().as_str());
|
||||
self.outputter.append("\"");
|
||||
},
|
||||
Constant::String(s) =>
|
||||
if let DoubleQuotes::Chars = self.machine_st.machine_flags().double_quotes {
|
||||
self.expand_char_list(s);
|
||||
} else { // for now, == DoubleQuotes::Atom
|
||||
self.outputter.append("\"");
|
||||
self.outputter.append(s.borrow().as_str());
|
||||
self.outputter.append("\"");
|
||||
},
|
||||
Constant::Usize(i) =>
|
||||
self.outputter.append(&format!("u{}", i))
|
||||
}
|
||||
@@ -384,10 +415,10 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
|
||||
loop {
|
||||
if let Some(loc_data) = self.state_stack.pop() {
|
||||
match loc_data {
|
||||
// TokenOrRedirect::Space =>
|
||||
// self.outputter.append(" "),
|
||||
TokenOrRedirect::Atom(atom) =>
|
||||
self.outputter.append(atom.as_str()),
|
||||
TokenOrRedirect::Char(c) =>
|
||||
self.print_char(c),
|
||||
TokenOrRedirect::NumberedVar(num_var) =>
|
||||
self.outputter.append(num_var.as_str()),
|
||||
TokenOrRedirect::Redirect =>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use prolog::ast::*;
|
||||
use prolog::machine::machine_state::MachineFlags;
|
||||
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::hash::Hash;
|
||||
@@ -10,14 +11,16 @@ enum IntIndex {
|
||||
}
|
||||
|
||||
pub struct CodeOffsets {
|
||||
flags: MachineFlags,
|
||||
pub constants: HashMap<Constant, ThirdLevelIndex>,
|
||||
pub lists: ThirdLevelIndex,
|
||||
pub structures: HashMap<(ClauseName, usize), ThirdLevelIndex>
|
||||
}
|
||||
|
||||
impl CodeOffsets {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(flags: MachineFlags) -> Self {
|
||||
CodeOffsets {
|
||||
flags,
|
||||
constants: HashMap::new(),
|
||||
lists: Vec::new(),
|
||||
structures: HashMap::new()
|
||||
@@ -56,6 +59,11 @@ impl CodeOffsets {
|
||||
let is_initial_index = self.lists.is_empty();
|
||||
self.lists.push(Self::add_index(is_initial_index, index));
|
||||
},
|
||||
&Term::Constant(_, Constant::String(_))
|
||||
if self.flags.double_quotes.is_chars() => { // 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(_, ref constant) => {
|
||||
let code = self.constants.entry(constant.clone())
|
||||
.or_insert(Vec::new());
|
||||
|
||||
@@ -266,10 +266,20 @@ pub(super) enum MachineMode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) enum DoubleQuotes {
|
||||
pub enum DoubleQuotes {
|
||||
Atom, Chars, // Codes
|
||||
}
|
||||
|
||||
impl DoubleQuotes {
|
||||
pub fn is_chars(self) -> bool {
|
||||
if let DoubleQuotes::Chars = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DoubleQuotes {
|
||||
fn default() -> Self {
|
||||
DoubleQuotes::Chars
|
||||
@@ -277,8 +287,8 @@ impl Default for DoubleQuotes {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) struct MachineFlags {
|
||||
pub(super) double_quotes: DoubleQuotes
|
||||
pub struct MachineFlags {
|
||||
pub double_quotes: DoubleQuotes
|
||||
}
|
||||
|
||||
impl Default for MachineFlags {
|
||||
|
||||
@@ -56,6 +56,11 @@ impl MachineState {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn machine_flags(&self) -> MachineFlags {
|
||||
self.flags
|
||||
}
|
||||
|
||||
fn next_global_index(&self) -> usize {
|
||||
max(if self.and_stack.len() > 0 { self.and_stack[self.e].global_index } else { 0 },
|
||||
if self.b > 0 { self.or_stack[self.b - 1].global_index } else { 0 }) + 1
|
||||
@@ -185,6 +190,30 @@ impl MachineState {
|
||||
|
||||
self.fail = true;
|
||||
},
|
||||
(Addr::Con(Constant::Char(c)), Addr::Con(Constant::Atom(atom)))
|
||||
| (Addr::Con(Constant::Atom(atom)), Addr::Con(Constant::Char(c))) => {
|
||||
let s = atom.as_str();
|
||||
if c.len_utf8() != s.len() || Some(c) != s.chars().next() {
|
||||
self.fail = true;
|
||||
}
|
||||
},
|
||||
(Addr::Lis(a1), Addr::Con(Constant::String(ref s)))
|
||||
| (Addr::Con(Constant::String(ref s)), Addr::Lis(a1))
|
||||
if self.flags.double_quotes.is_chars() =>
|
||||
if let Some(c) = s.head() {
|
||||
pdl.push(Addr::Con(Constant::String(s.tail())));
|
||||
pdl.push(Addr::HeapCell(a1 + 1));
|
||||
|
||||
pdl.push(Addr::Con(Constant::Char(c)));
|
||||
pdl.push(Addr::HeapCell(a1));
|
||||
} else {
|
||||
self.fail = true;
|
||||
},
|
||||
(Addr::Con(Constant::EmptyList), Addr::Con(Constant::String(ref s)))
|
||||
| (Addr::Con(Constant::String(ref s)), Addr::Con(Constant::EmptyList))
|
||||
if self.flags.double_quotes.is_chars() => {
|
||||
self.fail = !s.is_empty();
|
||||
},
|
||||
(Addr::Lis(a1), Addr::Lis(a2)) => {
|
||||
pdl.push(Addr::HeapCell(a1));
|
||||
pdl.push(Addr::HeapCell(a2));
|
||||
@@ -750,6 +779,20 @@ impl MachineState {
|
||||
let addr = self.store(self.deref(self[reg].clone()));
|
||||
|
||||
match addr {
|
||||
Addr::Con(Constant::String(ref s))
|
||||
if self.flags.double_quotes.is_chars() => {
|
||||
if let Some(c) = s.head() {
|
||||
let h = self.heap.h;
|
||||
|
||||
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 {
|
||||
self.fail = true;
|
||||
}
|
||||
},
|
||||
Addr::HeapCell(hc) => {
|
||||
let h = self.heap.h;
|
||||
|
||||
@@ -907,6 +950,7 @@ impl MachineState {
|
||||
|
||||
let offset = match addr {
|
||||
Addr::HeapCell(_) | Addr::StackCell(_, _) => v,
|
||||
Addr::Con(Constant::String(_)) if self.flags.double_quotes.is_chars() => l,
|
||||
Addr::Con(_) => c,
|
||||
Addr::Lis(_) => l,
|
||||
Addr::Str(_) => s
|
||||
@@ -1400,7 +1444,7 @@ impl MachineState {
|
||||
let d = self.store(self.deref(self[r1].clone()));
|
||||
|
||||
match d {
|
||||
Addr::Con(Constant::Atom(_)) => self.p += 1,
|
||||
Addr::Con(Constant::Atom(_)) | Addr::Con(Constant::Char(_)) => self.p += 1,
|
||||
_ => self.fail = true
|
||||
};
|
||||
},
|
||||
|
||||
@@ -122,6 +122,11 @@ impl Machine {
|
||||
wam
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn machine_flags(&self) -> MachineFlags {
|
||||
self.ms.flags
|
||||
}
|
||||
|
||||
fn remove_module(&mut self, module_name: ClauseName) {
|
||||
let iter = if let Some(submodule) = self.modules.get(&module_name) {
|
||||
submodule.module_decl.exports.iter().cloned()
|
||||
|
||||
Submodule src/prolog/parser updated: 6d995645d5...b5eafac512
@@ -35,8 +35,9 @@ impl<'a> Reader<'a> {
|
||||
|
||||
let atom_tbl = self.machine_st.atom_tbl.clone();
|
||||
let string_tbl = self.machine_st.string_tbl.clone();
|
||||
let flags = self.machine_st.machine_flags();
|
||||
|
||||
let mut parser = Parser::new(buffer.as_bytes(), atom_tbl, string_tbl);
|
||||
let mut parser = Parser::new(buffer.as_bytes(), atom_tbl, string_tbl, flags);
|
||||
Ok(self.write_term_to_heap(parser.read_term(op_dir)?))
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ impl Hash for StringListWrapper {
|
||||
pub struct StringList {
|
||||
body: TabledRc<StringListWrapper>,
|
||||
cursor: usize, // use this to generate a chars() iterator on the fly,
|
||||
// and skip over the first cursor chars.
|
||||
// and skip over the first cursor chars.
|
||||
expandable: bool
|
||||
}
|
||||
|
||||
@@ -63,17 +63,32 @@ impl StringList {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cursor(&self) -> usize {
|
||||
self.cursor
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn head(&self) -> Option<char> {
|
||||
self.borrow()[self.cursor ..].chars().next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tail(&self) -> Self {
|
||||
let mut new_string_list = self.clone();
|
||||
|
||||
if let Some(c) = self.borrow()[self.cursor ..].chars().next() {
|
||||
|
||||
if let Some(c) = self.head() {
|
||||
new_string_list.cursor += c.len_utf8();
|
||||
}
|
||||
|
||||
|
||||
new_string_list
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.borrow().len() == self.cursor
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn borrow(&self) -> Ref<String> {
|
||||
self.body.0.borrow()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use prolog::ast::*;
|
||||
use prolog::machine::*;
|
||||
use prolog::machine::machine_state::MachineFlags;
|
||||
use prolog::num::*;
|
||||
use prolog::parser::parser::*;
|
||||
use prolog::string_list::*;
|
||||
@@ -608,10 +609,10 @@ pub struct TopLevelWorker<'a, R: Read> {
|
||||
|
||||
impl<'a, R: Read> TopLevelWorker<'a, R> {
|
||||
pub fn new(inner: R, atom_tbl: TabledData<Atom>, string_tbl: TabledData<StringListWrapper>,
|
||||
indices: MachineCodeIndices<'a>)
|
||||
flags: MachineFlags, indices: MachineCodeIndices<'a>)
|
||||
-> Self
|
||||
{
|
||||
TopLevelWorker { parser: Parser::new(inner, atom_tbl, string_tbl), indices }
|
||||
TopLevelWorker { parser: Parser::new(inner, atom_tbl, string_tbl, flags), indices }
|
||||
}
|
||||
|
||||
pub fn parse_code(&mut self) -> Result<TopLevelPacket, ParserError>
|
||||
@@ -640,10 +641,11 @@ pub struct TopLevelBatchWorker<R: Read> {
|
||||
}
|
||||
|
||||
impl<R: Read> TopLevelBatchWorker<R> {
|
||||
pub fn new(inner: R, atom_tbl: TabledData<Atom>, string_tbl: TabledData<StringListWrapper>)
|
||||
pub fn new(inner: R, atom_tbl: TabledData<Atom>, string_tbl: TabledData<StringListWrapper>,
|
||||
flags: MachineFlags)
|
||||
-> Self
|
||||
{
|
||||
TopLevelBatchWorker { parser: Parser::new(inner, atom_tbl, string_tbl),
|
||||
TopLevelBatchWorker { parser: Parser::new(inner, atom_tbl, string_tbl, flags),
|
||||
rel_worker: RelationWorker::new(),
|
||||
source_mod: clause_name!("user"),
|
||||
results: vec![] }
|
||||
|
||||
@@ -1357,7 +1357,7 @@ fn test_queries_on_builtins()
|
||||
assert_prolog_success!(&mut wam, "?- functor(Func, f, 4).", [["Func = f(_2, _3, _4, _5)"]]);
|
||||
|
||||
assert_prolog_success!(&mut wam, "?- catch(functor(F, \"sdf\", 3), error(E, _), true).",
|
||||
[["E = type_error(atom, \"sdf\")", "F = _1"]]);
|
||||
[["E = type_error(atom, [s, d, f])", "F = _1"]]);
|
||||
assert_prolog_success!(&mut wam, "?- catch(functor(Func, F, 3), error(E, _), true).",
|
||||
[["E = instantiation_error", "Func = _1", "F = _2"]]);
|
||||
assert_prolog_success!(&mut wam, "?- catch(functor(Func, f, N), error(E, _), true).",
|
||||
@@ -1370,7 +1370,7 @@ fn test_queries_on_builtins()
|
||||
assert_prolog_success!(&mut wam, "?- X is 3 + 3.5, \\+ integer(X).");
|
||||
|
||||
assert_prolog_success!(&mut wam, "?- Func =.. [atom].", [["Func = atom"]]);
|
||||
assert_prolog_success!(&mut wam, "?- Func =.. [\"sdf\"].", [["Func = \"sdf\""]]);
|
||||
assert_prolog_success!(&mut wam, "?- Func =.. [\"sdf\"].", [["Func = [s, d, f]"]]);
|
||||
assert_prolog_success!(&mut wam, "?- Func =.. [1].", [["Func = 1"]]);
|
||||
assert_prolog_success!(&mut wam, "?- catch(Func =.. [1,2], error(type_error(atom, 1), _), true).");
|
||||
assert_prolog_success!(&mut wam, "?- f(1,2,3) =.. List.", [["List = [f, 1, 2, 3]"]]);
|
||||
|
||||
Reference in New Issue
Block a user