make use of read_term in the repl
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -86,7 +86,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.7.10"
|
version = "0.7.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -113,7 +113,7 @@ dependencies = [
|
|||||||
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prolog_parser 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prolog_parser 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
|
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
|
||||||
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
|
||||||
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
|
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
|
||||||
"checksum prolog_parser 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "277adc8aef82e87336a642a9bbd480cac9550e5ec63c99465eed7cbc7c165808"
|
"checksum prolog_parser 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "608b6d0e85a6ea8d4fda3679fc314a8b08efdb07f896438342a9d727b04b72d7"
|
||||||
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
|
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
|
||||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
|
|||||||
downcast = "0.9.1"
|
downcast = "0.9.1"
|
||||||
num = "0.2"
|
num = "0.2"
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = "0.7.10"
|
prolog_parser = "0.7.11"
|
||||||
|
|
||||||
[dependencies.termion]
|
[dependencies.termion]
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -226,7 +226,9 @@ false.
|
|||||||
and so do conjunctive queries:
|
and so do conjunctive queries:
|
||||||
```
|
```
|
||||||
prolog> f(X) :- g(X).
|
prolog> f(X) :- g(X).
|
||||||
prolog> g(x). g(y). g(z).
|
prolog> :{
|
||||||
|
g(x). g(y). g(z).
|
||||||
|
}:
|
||||||
prolog> h(call(f, X)).
|
prolog> h(call(f, X)).
|
||||||
prolog> ?- h(X), X.
|
prolog> ?- h(X), X.
|
||||||
true .
|
true .
|
||||||
|
|||||||
36
src/main.rs
36
src/main.rs
@@ -7,8 +7,11 @@ use prolog::instructions::*;
|
|||||||
mod prolog;
|
mod prolog;
|
||||||
|
|
||||||
use prolog::compile::*;
|
use prolog::compile::*;
|
||||||
use prolog::io::*;
|
|
||||||
use prolog::machine::*;
|
use prolog::machine::*;
|
||||||
|
use prolog::read::*;
|
||||||
|
use prolog::write::*;
|
||||||
|
|
||||||
|
use std::io::{Write, stdout};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
@@ -20,7 +23,7 @@ fn parse_and_compile_line(wam: &mut Machine, buffer: &str)
|
|||||||
let result = compile_packet(wam, packet);
|
let result = compile_packet(wam, packet);
|
||||||
print(wam, result);
|
print(wam, result);
|
||||||
},
|
},
|
||||||
Err(s) => println!("{:?}", s)
|
Err(e) => print(wam, EvalSession::from(e))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,19 +32,28 @@ fn prolog_repl() {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
print!("prolog> ");
|
print!("prolog> ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
match read() {
|
|
||||||
Input::Line(line) => parse_and_compile_line(&mut wam, line.as_str()),
|
match read_toplevel(&mut wam) {
|
||||||
Input::Batch(batch) =>
|
Ok(Input::Term(term)) =>
|
||||||
match compile_user_module(&mut wam, batch.as_str()) {
|
match compile_term(&mut wam, term) {
|
||||||
EvalSession::Error(e) => println!("{}", e),
|
Ok(packet) => {
|
||||||
_ => {}
|
let result = compile_packet(&mut wam, packet);
|
||||||
|
print(&mut wam, result);
|
||||||
|
},
|
||||||
|
Err(e) => print(&mut wam, EvalSession::from(e))
|
||||||
},
|
},
|
||||||
Input::Quit => break,
|
Ok(Input::Line(line)) => parse_and_compile_line(&mut wam, line.as_str()),
|
||||||
Input::Clear => {
|
Ok(Input::Batch(batch)) => {
|
||||||
|
let result = compile_user_module(&mut wam, batch.as_bytes());
|
||||||
|
print(&mut wam, result);
|
||||||
|
},
|
||||||
|
Ok(Input::Quit) => break,
|
||||||
|
Ok(Input::Clear) => {
|
||||||
wam.clear();
|
wam.clear();
|
||||||
continue;
|
continue;
|
||||||
}
|
},
|
||||||
|
Err(e) => print(&mut wam, EvalSession::from(e))
|
||||||
};
|
};
|
||||||
|
|
||||||
wam.reset();
|
wam.reset();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use prolog::machine::*;
|
|||||||
use prolog::toplevel::*;
|
use prolog::toplevel::*;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
|
use std::io::Read;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -48,6 +49,11 @@ pub fn parse_code(wam: &mut Machine, buffer: &str) -> Result<TopLevelPacket, Par
|
|||||||
worker.parse_code()
|
worker.parse_code()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compile_term(wam: &mut Machine, term: Term) -> Result<TopLevelPacket, ParserError> {
|
||||||
|
let indices = machine_code_indices!(&mut wam.code_dir, &mut wam.op_dir, &mut HashMap::new());
|
||||||
|
parse_term(term, indices)
|
||||||
|
}
|
||||||
|
|
||||||
// throw errors if declaration or query found.
|
// throw errors if declaration or query found.
|
||||||
fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags) -> Result<Code, ParserError>
|
fn compile_relation(tl: &TopLevel, non_counted_bt: bool, flags: MachineFlags) -> Result<Code, ParserError>
|
||||||
{
|
{
|
||||||
@@ -137,7 +143,7 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
|
|||||||
try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
|
try_eval_session!(compile_appendix(&mut code, queue, false, wam.machine_flags()));
|
||||||
|
|
||||||
if !code.is_empty() {
|
if !code.is_empty() {
|
||||||
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().ok().unwrap())
|
wam.add_user_code(name, tl.arity(), code)
|
||||||
} else {
|
} else {
|
||||||
EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
|
EvalSession::from(SessionError::ImpermissibleEntry(String::from("no code generated.")))
|
||||||
}
|
}
|
||||||
@@ -177,8 +183,8 @@ impl<'a> ListingCompiler<'a> {
|
|||||||
.unwrap_or(ClauseName::BuiltIn("user"))
|
.unwrap_or(ClauseName::BuiltIn("user"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_code(&mut self, decls: Vec<(Predicate, VecDeque<TopLevel>)>, code_dir: &mut CodeDir)
|
fn generate_code(&mut self, decls: Vec<(Predicate, VecDeque<TopLevel>)>, code_dir: &mut CodeDir)
|
||||||
-> Result<Code, SessionError>
|
-> Result<Code, SessionError>
|
||||||
{
|
{
|
||||||
let mut code = vec![];
|
let mut code = vec![];
|
||||||
|
|
||||||
@@ -246,9 +252,9 @@ fn use_qualified_module(module: &mut Option<Module>, submodule: &Module, exports
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub
|
pub
|
||||||
fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeIndices) -> EvalSession
|
fn compile_listing<R: Read>(wam: &mut Machine, src: R, mut indices: MachineCodeIndices) -> EvalSession
|
||||||
{
|
{
|
||||||
let mut worker = TopLevelBatchWorker::new(src_str.as_bytes(), wam.atom_tbl(), wam.machine_flags());
|
let mut worker = TopLevelBatchWorker::new(src, wam.atom_tbl(), wam.machine_flags());
|
||||||
let mut compiler = ListingCompiler::new(wam);
|
let mut compiler = ListingCompiler::new(wam);
|
||||||
|
|
||||||
while let Some(decl) = try_eval_session!(worker.consume(&mut indices)) {
|
while let Some(decl) = try_eval_session!(worker.consume(&mut indices)) {
|
||||||
@@ -279,13 +285,13 @@ fn compile_listing(wam: &mut Machine, src_str: &str, mut indices: MachineCodeInd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let code = try_eval_session!(compiler.gen_code(worker.results, &mut indices.code_dir));
|
let code = try_eval_session!(compiler.generate_code(worker.results, &mut indices.code_dir));
|
||||||
compiler.add_code(code, indices);
|
compiler.add_code(code, indices);
|
||||||
|
|
||||||
EvalSession::EntrySuccess
|
EvalSession::EntrySuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
|
pub fn compile_user_module<R: Read>(wam: &mut Machine, src: R) -> EvalSession {
|
||||||
let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
|
let mut indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
|
||||||
&mut HashMap::new());
|
&mut HashMap::new());
|
||||||
|
|
||||||
@@ -295,5 +301,5 @@ pub fn compile_user_module(wam: &mut Machine, src_str: &str) -> EvalSession {
|
|||||||
return EvalSession::from(SessionError::ModuleNotFound);
|
return EvalSession::from(SessionError::ModuleNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_listing(wam, src_str, indices)
|
compile_listing(wam, src, indices)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ impl InlinedClauseType {
|
|||||||
&InlinedClauseType::IsAtom(..) => "atom",
|
&InlinedClauseType::IsAtom(..) => "atom",
|
||||||
&InlinedClauseType::IsAtomic(..) => "atomic",
|
&InlinedClauseType::IsAtomic(..) => "atomic",
|
||||||
&InlinedClauseType::IsCompound(..) => "compound",
|
&InlinedClauseType::IsCompound(..) => "compound",
|
||||||
&InlinedClauseType::IsInteger (..) => "integer",
|
&InlinedClauseType::IsInteger (..) => "integer",
|
||||||
&InlinedClauseType::IsRational(..) => "rational",
|
&InlinedClauseType::IsRational(..) => "rational",
|
||||||
&InlinedClauseType::IsString(..) => "string",
|
&InlinedClauseType::IsString(..) => "string",
|
||||||
&InlinedClauseType::IsFloat (..) => "float",
|
&InlinedClauseType::IsFloat (..) => "float",
|
||||||
@@ -195,7 +195,7 @@ pub type ModuleCodeDir = HashMap<PredicateKey, ModuleCodeIndex>;
|
|||||||
|
|
||||||
pub type CodeDir = HashMap<PredicateKey, CodeIndex>;
|
pub type CodeDir = HashMap<PredicateKey, CodeIndex>;
|
||||||
|
|
||||||
pub type TermDir = HashMap<PredicateKey, Predicate>;
|
//pub type TermDir = HashMap<PredicateKey, Predicate>;
|
||||||
|
|
||||||
pub type ModuleDir = HashMap<ClauseName, Module>;
|
pub type ModuleDir = HashMap<ClauseName, Module>;
|
||||||
|
|
||||||
@@ -781,6 +781,7 @@ pub enum IndexPtr {
|
|||||||
pub struct CodeIndex(pub Rc<RefCell<(IndexPtr, ClauseName)>>);
|
pub struct CodeIndex(pub Rc<RefCell<(IndexPtr, ClauseName)>>);
|
||||||
|
|
||||||
impl CodeIndex {
|
impl CodeIndex {
|
||||||
|
#[inline]
|
||||||
pub fn is_undefined(&self) -> bool {
|
pub fn is_undefined(&self) -> bool {
|
||||||
let index_ptr = &self.0.borrow().0;
|
let index_ptr = &self.0.borrow().0;
|
||||||
|
|
||||||
@@ -1140,15 +1141,6 @@ impl TopLevel {
|
|||||||
&TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
|
&TopLevel::Rule(Rule { ref head, .. }) => head.1.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_predicate(self) -> Result<Predicate, TopLevel> {
|
|
||||||
match self {
|
|
||||||
TopLevel::Fact(term) => Ok(Predicate(vec![PredicateClause::Fact(term)])),
|
|
||||||
TopLevel::Rule(rule) => Ok(Predicate(vec![PredicateClause::Rule(rule)])),
|
|
||||||
TopLevel::Predicate(pred) => Ok(pred),
|
|
||||||
_ => Err(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -1239,7 +1231,7 @@ pub enum SessionError {
|
|||||||
OpIsInfixAndPostFix,
|
OpIsInfixAndPostFix,
|
||||||
ParserError(ParserError),
|
ParserError(ParserError),
|
||||||
QueryFailure,
|
QueryFailure,
|
||||||
QueryFailureWithException(String)
|
QueryFailureWithException(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum EvalSession {
|
pub enum EvalSession {
|
||||||
|
|||||||
@@ -61,48 +61,7 @@ impl MachineError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn syntax_error(h: usize, err: ParserError) -> Self {
|
pub(super) fn syntax_error(h: usize, err: ParserError) -> Self {
|
||||||
let err = match err {
|
let err = vec![heap_atom!(err.as_str())];
|
||||||
ParserError::Arithmetic(_) =>
|
|
||||||
vec![heap_atom!("arithmetic_error")],
|
|
||||||
ParserError::BackQuotedString =>
|
|
||||||
vec![heap_atom!("back_quoted_string")],
|
|
||||||
ParserError::UnexpectedChar(c) =>
|
|
||||||
functor!("unexpected_char", 1, [heap_char!(c)]),
|
|
||||||
ParserError::UnexpectedEOF =>
|
|
||||||
vec![heap_atom!("unexpected_end_of_file")],
|
|
||||||
ParserError::ExpectedRel =>
|
|
||||||
vec![heap_atom!("expected_relation")],
|
|
||||||
ParserError::InadmissibleFact =>
|
|
||||||
vec![heap_atom!("inadmissible_fact")],
|
|
||||||
ParserError::InadmissibleQueryTerm =>
|
|
||||||
vec![heap_atom!("inadmissible_query_term")],
|
|
||||||
ParserError::IncompleteReduction =>
|
|
||||||
vec![heap_atom!("incomplete_reduction")],
|
|
||||||
ParserError::InconsistentEntry =>
|
|
||||||
vec![heap_atom!("inconsistent_entry")],
|
|
||||||
ParserError::InvalidModuleDecl =>
|
|
||||||
vec![heap_atom!("invalid_module_declaration")],
|
|
||||||
ParserError::InvalidModuleExport =>
|
|
||||||
vec![heap_atom!("invalid_module_export")],
|
|
||||||
ParserError::InvalidModuleResolution =>
|
|
||||||
vec![heap_atom!("invalid_module_resolution")],
|
|
||||||
ParserError::InvalidRuleHead =>
|
|
||||||
vec![heap_atom!("invalid_head_of_rule")],
|
|
||||||
ParserError::InvalidUseModuleDecl =>
|
|
||||||
vec![heap_atom!("invalid_use_module_declaration")],
|
|
||||||
ParserError::IO(_) =>
|
|
||||||
vec![heap_atom!("input_output_error")],
|
|
||||||
ParserError::MissingQuote =>
|
|
||||||
vec![heap_atom!("missing_quote")],
|
|
||||||
ParserError::NonPrologChar =>
|
|
||||||
vec![heap_atom!("non_prolog_character")],
|
|
||||||
ParserError::ParseBigInt =>
|
|
||||||
vec![heap_atom!("cannot_parse_big_int")],
|
|
||||||
ParserError::ParseFloat =>
|
|
||||||
vec![heap_atom!("cannot_parse_float")],
|
|
||||||
ParserError::Utf8Conversion(_) =>
|
|
||||||
vec![heap_atom!("utf8_conversion_error")]
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut stub = if err.len() == 1 {
|
let mut stub = if err.len() == 1 {
|
||||||
functor!("syntax_error", 1)
|
functor!("syntax_error", 1)
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ use prolog::machine::MachineCodeIndices;
|
|||||||
use prolog::machine::machine_errors::*;
|
use prolog::machine::machine_errors::*;
|
||||||
use prolog::num::{BigInt, BigUint, Zero, One};
|
use prolog::num::{BigInt, BigUint, Zero, One};
|
||||||
use prolog::or_stack::*;
|
use prolog::or_stack::*;
|
||||||
use prolog::read::*;
|
|
||||||
|
|
||||||
use downcast::Any;
|
use downcast::Any;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::io::stdin;
|
||||||
use std::mem::swap;
|
use std::mem::swap;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -297,7 +297,7 @@ pub struct MachineState {
|
|||||||
pub(super) ball: Ball,
|
pub(super) ball: Ball,
|
||||||
pub(super) interms: Vec<Number>, // intermediate numbers.
|
pub(super) interms: Vec<Number>, // intermediate numbers.
|
||||||
pub(super) last_call: bool,
|
pub(super) last_call: bool,
|
||||||
pub(super) flags: MachineFlags
|
pub(crate) flags: MachineFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_at_index(machine_st: &mut MachineState, module_name: ClauseName, arity: usize, idx: usize)
|
fn call_at_index(machine_st: &mut MachineState, module_name: ClauseName, arity: usize, idx: usize)
|
||||||
@@ -570,25 +570,23 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
machine_st.fail = !machine_st.is_cyclic_term(addr);
|
machine_st.fail = !machine_st.is_cyclic_term(addr);
|
||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
},
|
},
|
||||||
&BuiltInClauseType::Read => {
|
&BuiltInClauseType::Read => {
|
||||||
let mut reader = Reader::new(machine_st);
|
match machine_st.read(stdin(), &indices.op_dir) {
|
||||||
|
|
||||||
match reader.read_stdin(&indices.op_dir) {
|
|
||||||
Ok(offset) => {
|
Ok(offset) => {
|
||||||
let addr = reader.machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)].clone();
|
||||||
reader.machine_st.unify(addr, Addr::HeapCell(offset));
|
machine_st.unify(addr, Addr::HeapCell(offset));
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let h = reader.machine_st.heap.h;
|
let h = machine_st.heap.h;
|
||||||
let stub = MachineError::functor_stub(clause_name!("read"), 1);
|
let stub = MachineError::functor_stub(clause_name!("read"), 1);
|
||||||
let err = MachineError::syntax_error(h, e);
|
let err = MachineError::syntax_error(h, e);
|
||||||
let err = reader.machine_st.error_form(err, stub);
|
let err = machine_st.error_form(err, stub);
|
||||||
|
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return_from_clause!(reader.machine_st.last_call, reader.machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
},
|
},
|
||||||
&BuiltInClauseType::Writeq => {
|
&BuiltInClauseType::Writeq => {
|
||||||
let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
|
let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ pub struct Machine {
|
|||||||
code: Code,
|
code: Code,
|
||||||
pub(super) code_dir: CodeDir,
|
pub(super) code_dir: CodeDir,
|
||||||
pub(super) op_dir: OpDir,
|
pub(super) op_dir: OpDir,
|
||||||
term_dir: TermDir,
|
// term_dir: TermDir,
|
||||||
pub(super) modules: ModuleDir,
|
pub(super) modules: ModuleDir,
|
||||||
cached_query: Option<Code>
|
cached_query: Option<Code>
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ impl Machine {
|
|||||||
code: Code::new(),
|
code: Code::new(),
|
||||||
code_dir: CodeDir::new(),
|
code_dir: CodeDir::new(),
|
||||||
op_dir: default_op_dir(),
|
op_dir: default_op_dir(),
|
||||||
term_dir: TermDir::new(),
|
// term_dir: TermDir::new(),
|
||||||
modules: HashMap::new(),
|
modules: HashMap::new(),
|
||||||
cached_query: None
|
cached_query: None
|
||||||
};
|
};
|
||||||
@@ -124,11 +124,11 @@ impl Machine {
|
|||||||
let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
|
let indices = machine_code_indices!(&mut CodeDir::new(), &mut default_op_dir(),
|
||||||
&mut HashMap::new());
|
&mut HashMap::new());
|
||||||
|
|
||||||
compile_listing(&mut wam, BUILTINS, indices);
|
compile_listing(&mut wam, BUILTINS.as_bytes(), indices);
|
||||||
|
|
||||||
compile_user_module(&mut wam, LISTS);
|
compile_user_module(&mut wam, LISTS.as_bytes());
|
||||||
compile_user_module(&mut wam, CONTROL);
|
compile_user_module(&mut wam, CONTROL.as_bytes());
|
||||||
compile_user_module(&mut wam, QUEUES);
|
compile_user_module(&mut wam, QUEUES.as_bytes());
|
||||||
|
|
||||||
wam.use_module_in_toplevel(clause_name!("builtins"));
|
wam.use_module_in_toplevel(clause_name!("builtins"));
|
||||||
|
|
||||||
@@ -252,8 +252,7 @@ impl Machine {
|
|||||||
self.code.extend(code.into_iter());
|
self.code.extend(code.into_iter());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_user_code(&mut self, name: ClauseName, arity: usize, code: Code, pred: Predicate)
|
pub fn add_user_code(&mut self, name: ClauseName, arity: usize, code: Code) -> EvalSession
|
||||||
-> EvalSession
|
|
||||||
{
|
{
|
||||||
match self.code_dir.get(&(name.clone(), arity)) {
|
match self.code_dir.get(&(name.clone(), arity)) {
|
||||||
Some(&CodeIndex (ref idx)) if idx.borrow().1 != clause_name!("user") =>
|
Some(&CodeIndex (ref idx)) if idx.borrow().1 != clause_name!("user") =>
|
||||||
@@ -268,7 +267,7 @@ impl Machine {
|
|||||||
let offset = self.code.len();
|
let offset = self.code.len();
|
||||||
|
|
||||||
self.code.extend(code.into_iter());
|
self.code.extend(code.into_iter());
|
||||||
self.term_dir.insert((name.clone(), arity), pred);
|
//self.term_dir.insert((name.clone(), arity), pred);
|
||||||
|
|
||||||
let idx = self.code_dir.entry((name, arity))
|
let idx = self.code_dir.entry((name, arity))
|
||||||
.or_insert(CodeIndex::from((offset, clause_name!("user"))));
|
.or_insert(CodeIndex::from((offset, clause_name!("user"))));
|
||||||
|
|||||||
@@ -22,12 +22,6 @@ macro_rules! heap_integer {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! heap_char {
|
|
||||||
($c:expr) => (
|
|
||||||
HeapCellValue::Addr(Addr::Con(Constant::Char($c)))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! heap_atom {
|
macro_rules! heap_atom {
|
||||||
($name:expr) => (
|
($name:expr) => (
|
||||||
HeapCellValue::Addr(Addr::Con(atom!($name)))
|
HeapCellValue::Addr(Addr::Con(atom!($name)))
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ mod debray_allocator;
|
|||||||
mod fixtures;
|
mod fixtures;
|
||||||
mod heap_iter;
|
mod heap_iter;
|
||||||
mod indexing;
|
mod indexing;
|
||||||
pub mod io;
|
pub mod write;
|
||||||
mod iterators;
|
mod iterators;
|
||||||
mod or_stack;
|
mod or_stack;
|
||||||
pub mod heap_print;
|
pub mod heap_print;
|
||||||
mod targets;
|
mod targets;
|
||||||
mod read;
|
pub mod read;
|
||||||
|
|||||||
@@ -3,14 +3,11 @@ use prolog_parser::parser::*;
|
|||||||
|
|
||||||
use prolog::instructions::*;
|
use prolog::instructions::*;
|
||||||
use prolog::iterators::*;
|
use prolog::iterators::*;
|
||||||
use prolog::machine::machine_state::*;
|
use prolog::machine::*;
|
||||||
|
use prolog::machine::machine_state::MachineState;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io::stdin;
|
use std::io::{Read, stdin};
|
||||||
|
|
||||||
pub struct Reader<'a> {
|
|
||||||
pub machine_st: &'a mut MachineState,
|
|
||||||
}
|
|
||||||
|
|
||||||
type SubtermDeque = VecDeque<(usize, usize)>;
|
type SubtermDeque = VecDeque<(usize, usize)>;
|
||||||
|
|
||||||
@@ -25,133 +22,137 @@ impl<'a> TermRef<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Reader<'a> {
|
pub enum Input {
|
||||||
pub fn new(machine_st: &'a mut MachineState) -> Self {
|
Quit,
|
||||||
Reader { machine_st }
|
Clear,
|
||||||
|
Line(String),
|
||||||
|
Batch(String),
|
||||||
|
Term(Term)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_lines(buffer: &mut String, end_delim: &str) -> String {
|
||||||
|
let mut result = String::new();
|
||||||
|
let stdin = stdin();
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
stdin.read_line(buffer).unwrap();
|
||||||
|
|
||||||
|
while &*buffer.trim() != end_delim {
|
||||||
|
result += buffer.as_str();
|
||||||
|
buffer.clear();
|
||||||
|
stdin.read_line(buffer).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_term(&self, buffer: &String, op_dir: &'a OpDir) -> Result<Term, ParserError> {
|
result
|
||||||
let mut parser = Parser::new(buffer.as_bytes(), self.machine_st.atom_tbl.clone(),
|
}
|
||||||
self.machine_st.machine_flags());
|
|
||||||
|
|
||||||
parser.read_term(op_dir)
|
pub fn read_toplevel(wam: &Machine) -> Result<Input, ParserError> {
|
||||||
}
|
let mut buffer = String::new();
|
||||||
|
|
||||||
fn read_term_loop(&mut self, buffer: &mut String, op_dir: &'a OpDir) -> Result<Term, ParserError> {
|
let stdin = stdin();
|
||||||
let stdin = stdin();
|
stdin.read_line(&mut buffer).unwrap();
|
||||||
|
|
||||||
loop {
|
match &*buffer.trim() {
|
||||||
match self.read_term(&buffer, op_dir) {
|
":{" => Ok(Input::Line(read_lines(&mut buffer, "}:"))),
|
||||||
Err(ParserError::UnexpectedEOF) => {},
|
":{{" => Ok(Input::Batch(read_lines(&mut buffer, "}}:"))),
|
||||||
result => return result
|
"quit" => Ok(Input::Quit),
|
||||||
};
|
"clear" => Ok(Input::Clear),
|
||||||
|
_ => {
|
||||||
let mut append_buf = String::new();
|
let mut parser = Parser::new(stdin.lock(), wam.atom_tbl(), wam.machine_flags());
|
||||||
stdin.read_line(&mut append_buf).unwrap();
|
|
||||||
*buffer += append_buf.as_str();
|
parser.add_to_top(buffer.as_str());
|
||||||
|
Ok(Input::Term(parser.read_term(&wam.op_dir)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
}
|
||||||
pub fn repl_read(&mut self, op_dir: &'a OpDir) -> Result<Vec<Term>, ParserError> {
|
|
||||||
let mut buffer = String::new();
|
impl MachineState {
|
||||||
|
pub fn read<R: Read>(&mut self, inner: R, op_dir: &OpDir) -> Result<usize, ParserError>
|
||||||
stdin().read_line(&mut buffer);
|
{
|
||||||
|
let mut parser = Parser::new(inner, self.atom_tbl.clone(), self.flags);
|
||||||
if buffer.as_str() == "[user]" {
|
let term = parser.read_term(op_dir)?;
|
||||||
let locked = stdin().lock();
|
|
||||||
let mut parser = Parser::new(locked, self.machine_st.atom_tbl.clone(),
|
Ok(write_term_to_heap(term, self))
|
||||||
self.machine_st.flags());
|
}
|
||||||
|
}
|
||||||
parser.read(op_dir)
|
|
||||||
} else {
|
fn push_stub_addr(machine_st: &mut MachineState) {
|
||||||
Ok(vec![self.read_term_loop(buffer, op_dir)?])
|
let h = machine_st.heap.h;
|
||||||
}
|
machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
pub fn read_stdin(&mut self, op_dir: &'a OpDir) -> Result<usize, ParserError>
|
fn modify_head_of_queue(machine_st: &mut MachineState, queue: &mut SubtermDeque, term: TermRef, h: usize)
|
||||||
{
|
{
|
||||||
let term = self.read_term_loop(&mut String::new(), op_dir)?;
|
if let Some((arity, site_h)) = queue.pop_front() {
|
||||||
Ok(self.write_term_to_heap(term))
|
machine_st.heap[site_h] = HeapCellValue::Addr(term.as_addr(h));
|
||||||
}
|
|
||||||
|
if arity > 1 {
|
||||||
fn push_stub_addr(&mut self) {
|
queue.push_front((arity - 1, site_h + 1));
|
||||||
let h = self.machine_st.heap.h;
|
}
|
||||||
self.machine_st.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_head_of_queue(&mut self, queue: &mut SubtermDeque, term: TermRef, h: usize) {
|
fn write_term_to_heap(term: Term, machine_st: &mut MachineState) -> usize {
|
||||||
if let Some((arity, site_h)) = queue.pop_front() {
|
let h = machine_st.heap.h;
|
||||||
self.machine_st.heap[site_h] = HeapCellValue::Addr(term.as_addr(h));
|
|
||||||
|
let mut queue = SubtermDeque::new();
|
||||||
if arity > 1 {
|
let mut var_dict = HeapVarDict::new();
|
||||||
queue.push_front((arity - 1, site_h + 1));
|
|
||||||
}
|
for term in breadth_first_iter(&term, true) {
|
||||||
}
|
let h = machine_st.heap.h;
|
||||||
}
|
|
||||||
|
match &term {
|
||||||
fn write_term_to_heap(&mut self, term: Term) -> usize {
|
&TermRef::Cons(lvl, ..) => {
|
||||||
let h = self.machine_st.heap.h;
|
queue.push_back((2, h+1));
|
||||||
|
machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
|
||||||
let mut queue = SubtermDeque::new();
|
|
||||||
let mut var_dict = HeapVarDict::new();
|
push_stub_addr(machine_st);
|
||||||
|
push_stub_addr(machine_st);
|
||||||
for term in breadth_first_iter(&term, true) {
|
|
||||||
let h = self.machine_st.heap.h;
|
if let Level::Root = lvl {
|
||||||
|
continue;
|
||||||
match &term {
|
}
|
||||||
&TermRef::Cons(lvl, ..) => {
|
},
|
||||||
queue.push_back((2, h+1));
|
&TermRef::Clause(lvl, _, ref ct, subterms) => {
|
||||||
self.machine_st.heap.push(HeapCellValue::Addr(Addr::Lis(h+1)));
|
queue.push_back((subterms.len(), h+1));
|
||||||
|
let named = HeapCellValue::NamedStr(subterms.len(), ct.name(), ct.fixity());
|
||||||
self.push_stub_addr();
|
|
||||||
self.push_stub_addr();
|
machine_st.heap.push(named);
|
||||||
|
|
||||||
if let Level::Root = lvl {
|
for _ in 0 .. subterms.len() {
|
||||||
continue;
|
push_stub_addr(machine_st);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
&TermRef::Clause(lvl, _, ref ct, subterms) => {
|
if let Level::Root = lvl {
|
||||||
queue.push_back((subterms.len(), h+1));
|
continue;
|
||||||
let named = HeapCellValue::NamedStr(subterms.len(), ct.name(),
|
}
|
||||||
ct.fixity());
|
},
|
||||||
|
&TermRef::AnonVar(Level::Root)
|
||||||
self.machine_st.heap.push(named);
|
| &TermRef::Var(Level::Root, ..)
|
||||||
|
| &TermRef::Constant(Level::Root, ..) =>
|
||||||
for _ in 0 .. subterms.len() {
|
machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))),
|
||||||
self.push_stub_addr();
|
&TermRef::AnonVar(_) =>
|
||||||
}
|
continue,
|
||||||
|
&TermRef::Var(_, _, ref var) => {
|
||||||
if let Level::Root = lvl {
|
if let Some((arity, site_h)) = queue.pop_front() {
|
||||||
continue;
|
if let Some(addr) = var_dict.get(var).cloned() {
|
||||||
}
|
machine_st.heap[site_h] = HeapCellValue::Addr(addr);
|
||||||
},
|
} else {
|
||||||
&TermRef::AnonVar(Level::Root)
|
var_dict.insert(var.clone(), Addr::HeapCell(site_h));
|
||||||
| &TermRef::Var(Level::Root, ..)
|
}
|
||||||
| &TermRef::Constant(Level::Root, ..) =>
|
|
||||||
self.machine_st.heap.push(HeapCellValue::Addr(term.as_addr(h))),
|
if arity > 1 {
|
||||||
&TermRef::AnonVar(_) =>
|
queue.push_front((arity - 1, site_h + 1));
|
||||||
continue,
|
}
|
||||||
&TermRef::Var(_, _, ref var) => {
|
}
|
||||||
if let Some((arity, site_h)) = queue.pop_front() {
|
|
||||||
if let Some(addr) = var_dict.get(var).cloned() {
|
continue;
|
||||||
self.machine_st.heap[site_h] = HeapCellValue::Addr(addr);
|
},
|
||||||
} else {
|
_ => {}
|
||||||
var_dict.insert(var.clone(), Addr::HeapCell(site_h));
|
};
|
||||||
}
|
|
||||||
|
modify_head_of_queue(machine_st, &mut queue, term, h);
|
||||||
if arity > 1 {
|
}
|
||||||
queue.push_front((arity - 1, site_h + 1));
|
|
||||||
}
|
h
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.modify_head_of_queue(&mut queue, term, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
h
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -645,6 +645,16 @@ impl<'a, R: Read> TopLevelWorker<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_term(term: Term, mut indices: MachineCodeIndices) -> Result<TopLevelPacket, ParserError>
|
||||||
|
{
|
||||||
|
let mut rel_worker = RelationWorker::new();
|
||||||
|
|
||||||
|
let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
|
||||||
|
let results = rel_worker.parse_queue(&mut indices)?;
|
||||||
|
|
||||||
|
Ok(deque_to_packet(tl, results))
|
||||||
|
}
|
||||||
|
|
||||||
pub struct TopLevelBatchWorker<R: Read> {
|
pub struct TopLevelBatchWorker<R: Read> {
|
||||||
parser: Parser<R>,
|
parser: Parser<R>,
|
||||||
rel_worker: RelationWorker,
|
rel_worker: RelationWorker,
|
||||||
@@ -666,7 +676,7 @@ impl<R: Read> TopLevelBatchWorker<R> {
|
|||||||
{
|
{
|
||||||
let mut preds = vec![];
|
let mut preds = vec![];
|
||||||
|
|
||||||
while !self.parser.eof() {
|
while !self.parser.eof()? {
|
||||||
self.parser.reset(); // empty the parser stack of token descriptions.
|
self.parser.reset(); // empty the parser stack of token descriptions.
|
||||||
|
|
||||||
let mut new_rel_worker = RelationWorker::new();
|
let mut new_rel_worker = RelationWorker::new();
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ impl fmt::Display for ControlInstruction {
|
|||||||
&ControlInstruction::CallClause(ref ct, arity, pvs, true, false) =>
|
&ControlInstruction::CallClause(ref ct, arity, pvs, true, false) =>
|
||||||
write!(f, "execute {}/{}, {}", ct, arity, pvs),
|
write!(f, "execute {}/{}, {}", ct, arity, pvs),
|
||||||
&ControlInstruction::CallClause(ref ct, arity, pvs, false, false) =>
|
&ControlInstruction::CallClause(ref ct, arity, pvs, false, false) =>
|
||||||
write!(f, "call {}/{}, {}", ct, arity, pvs),
|
write!(f, "call {}/{}, {}", ct, arity, pvs),
|
||||||
&ControlInstruction::Deallocate =>
|
&ControlInstruction::Deallocate =>
|
||||||
write!(f, "deallocate"),
|
write!(f, "deallocate"),
|
||||||
&ControlInstruction::JmpBy(arity, offset, pvs, false) =>
|
&ControlInstruction::JmpBy(arity, offset, pvs, false) =>
|
||||||
@@ -162,7 +162,7 @@ impl fmt::Display for IndexedChoiceInstruction {
|
|||||||
|
|
||||||
impl fmt::Display for ChoiceInstruction {
|
impl fmt::Display for ChoiceInstruction {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
&ChoiceInstruction::TryMeElse(offset) =>
|
&ChoiceInstruction::TryMeElse(offset) =>
|
||||||
write!(f, "try_me_else {}", offset),
|
write!(f, "try_me_else {}", offset),
|
||||||
&ChoiceInstruction::DefaultRetryMeElse(offset) =>
|
&ChoiceInstruction::DefaultRetryMeElse(offset) =>
|
||||||
@@ -201,7 +201,7 @@ impl fmt::Display for SessionError {
|
|||||||
&SessionError::OpIsInfixAndPostFix =>
|
&SessionError::OpIsInfixAndPostFix =>
|
||||||
write!(f, "cannot define an op to be both postfix and infix."),
|
write!(f, "cannot define an op to be both postfix and infix."),
|
||||||
&SessionError::NamelessEntry => write!(f, "the predicate head is not an atom or clause."),
|
&SessionError::NamelessEntry => write!(f, "the predicate head is not an atom or clause."),
|
||||||
&SessionError::ParserError(ref e) => write!(f, "{:?}", e)
|
&SessionError::ParserError(ref e) => write!(f, "syntax_error({})", e.as_str()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,59 +281,17 @@ impl fmt::Display for Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Input {
|
|
||||||
Quit,
|
|
||||||
Clear,
|
|
||||||
Line(String),
|
|
||||||
Batch(String)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_lines(buffer: &mut String, end_delim: &str) -> String {
|
|
||||||
let mut result = String::new();
|
|
||||||
let stdin = stdin();
|
|
||||||
|
|
||||||
buffer.clear();
|
|
||||||
stdin.read_line(buffer).unwrap();
|
|
||||||
|
|
||||||
while &*buffer.trim() != end_delim {
|
|
||||||
result += buffer.as_str();
|
|
||||||
buffer.clear();
|
|
||||||
stdin.read_line(buffer).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read() -> Input {
|
|
||||||
let _ = stdout().flush();
|
|
||||||
let mut buffer = String::new();
|
|
||||||
|
|
||||||
let stdin = stdin();
|
|
||||||
stdin.read_line(&mut buffer).unwrap();
|
|
||||||
|
|
||||||
match &*buffer.trim() {
|
|
||||||
":{" => Input::Line(read_lines(&mut buffer, "}:")),
|
|
||||||
":{{" => Input::Batch(read_lines(&mut buffer, "}}:")),
|
|
||||||
"quit" => Input::Quit,
|
|
||||||
"clear" => Input::Clear,
|
|
||||||
_ => Input::Line(buffer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print(wam: &mut Machine, result: EvalSession) {
|
pub fn print(wam: &mut Machine, result: EvalSession) {
|
||||||
match result {
|
match result {
|
||||||
EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
|
EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
|
||||||
print!("true");
|
|
||||||
|
|
||||||
if !wam.or_stack_is_empty() {
|
|
||||||
print!(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
println!(".");
|
|
||||||
|
|
||||||
if heap_locs.is_empty() {
|
if heap_locs.is_empty() {
|
||||||
|
println!("true.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !wam.or_stack_is_empty() {
|
||||||
|
println!("true .");
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut result = EvalSession::from(SessionError::QueryFailure);
|
let mut result = EvalSession::from(SessionError::QueryFailure);
|
||||||
12
src/tests.rs
12
src/tests.rs
@@ -129,7 +129,7 @@ pub fn submit(wam: &mut Machine, buffer: &str) -> bool
|
|||||||
true,
|
true,
|
||||||
_ => false
|
_ => false
|
||||||
},
|
},
|
||||||
Err(e) => panic!("parse error: {:?}", e)
|
Err(e) => panic!("syntax_error({})", e.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ pub fn submit_query(wam: &mut Machine, buffer: &str, result: Vec<HashSet<String>
|
|||||||
EvalSession::EntrySuccess => true,
|
EvalSession::EntrySuccess => true,
|
||||||
_ => false
|
_ => false
|
||||||
},
|
},
|
||||||
Err(e) => panic!("parse error: {:?}", e)
|
Err(e) => panic!("syntax_error({})", e.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ pub fn submit_query_with_limit(wam: &mut Machine, buffer: &str,
|
|||||||
EvalSession::EntrySuccess => true,
|
EvalSession::EntrySuccess => true,
|
||||||
_ => false
|
_ => false
|
||||||
},
|
},
|
||||||
Err(e) => panic!("parse error: {:?}", e)
|
Err(e) => panic!("syntax_error({})", e.as_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1351,7 +1351,7 @@ fn test_queries_on_modules()
|
|||||||
local_member(X, Xs) :- member(X, Xs).
|
local_member(X, Xs) :- member(X, Xs).
|
||||||
|
|
||||||
reverse(Xs, Ys) :- lists:reverse(Xs, Ys).
|
reverse(Xs, Ys) :- lists:reverse(Xs, Ys).
|
||||||
");
|
".as_bytes());
|
||||||
|
|
||||||
assert_prolog_success!(&mut wam, "?- my_lists:local_member(1, [1,2,3]).");
|
assert_prolog_success!(&mut wam, "?- my_lists:local_member(1, [1,2,3]).");
|
||||||
assert_prolog_success!(&mut wam, "?- my_lists:reverse([a,b,c], [c,b,a]).");
|
assert_prolog_success!(&mut wam, "?- my_lists:reverse([a,b,c], [c,b,a]).");
|
||||||
@@ -1359,13 +1359,11 @@ reverse(Xs, Ys) :- lists:reverse(Xs, Ys).
|
|||||||
compile_user_module(&mut wam, "
|
compile_user_module(&mut wam, "
|
||||||
:- use_module(library(my_lists), [local_member/2]).
|
:- use_module(library(my_lists), [local_member/2]).
|
||||||
:- module(my_lists_2, [local_member/2]).
|
:- module(my_lists_2, [local_member/2]).
|
||||||
");
|
".as_bytes());
|
||||||
|
|
||||||
assert_prolog_success!(&mut wam, "?- my_lists_2:local_member(1, [1,2,3]).");
|
assert_prolog_success!(&mut wam, "?- my_lists_2:local_member(1, [1,2,3]).");
|
||||||
assert_prolog_success!(&mut wam, "?- catch(local_member(X, Xs), error(E, _), true).",
|
assert_prolog_success!(&mut wam, "?- catch(local_member(X, Xs), error(E, _), true).",
|
||||||
[["X = _1", "E = existence_error(procedure, local_member/2)", "Xs = _2"]]);
|
[["X = _1", "E = existence_error(procedure, local_member/2)", "Xs = _2"]]);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user