add streams.rs, consume them in place of the old PrologStream
This commit is contained in:
@@ -170,6 +170,7 @@ pub enum SystemClauseType {
|
|||||||
CheckCutPoint,
|
CheckCutPoint,
|
||||||
CopyToLiftedHeap,
|
CopyToLiftedHeap,
|
||||||
CreatePartialString,
|
CreatePartialString,
|
||||||
|
CurrentInput,
|
||||||
DeleteAttribute,
|
DeleteAttribute,
|
||||||
DeleteHeadAttribute,
|
DeleteHeadAttribute,
|
||||||
DynamicModuleResolution(usize),
|
DynamicModuleResolution(usize),
|
||||||
@@ -283,6 +284,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
|
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
|
||||||
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
|
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
|
||||||
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
|
||||||
|
&SystemClauseType::CurrentInput => clause_name!("$current_input"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
|
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
|
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
|
||||||
@@ -433,6 +435,7 @@ impl SystemClauseType {
|
|||||||
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
|
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
|
||||||
("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
|
("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
|
||||||
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
|
||||||
|
("$current_input", 1) => Some(SystemClauseType::CurrentInput),
|
||||||
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
|
("$del_attr_non_head", 1) => Some(SystemClauseType::DeleteAttribute),
|
||||||
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
("$del_attr_head", 1) => Some(SystemClauseType::DeleteHeadAttribute),
|
||||||
("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
|
("$get_next_db_ref", 2) => Some(SystemClauseType::GetNextDBRef),
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ impl<'a> HCPreOrderIterator<'a> {
|
|||||||
|
|
||||||
Addr::Con(Constant::String(n, s))
|
Addr::Con(Constant::String(n, s))
|
||||||
}
|
}
|
||||||
Addr::Con(_) | Addr::DBRef(_) => {
|
Addr::Con(_) | Addr::DBRef(_) | Addr::Stream(_) => {
|
||||||
da
|
da
|
||||||
}
|
}
|
||||||
Addr::Lis(a) => {
|
Addr::Lis(a) => {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :-
|
|||||||
abolish/1, asserta/1, assertz/1, atom_chars/2,
|
abolish/1, asserta/1, assertz/1, atom_chars/2,
|
||||||
atom_codes/2, atom_concat/3, atom_length/2,
|
atom_codes/2, atom_concat/3, atom_length/2,
|
||||||
bagof/3, catch/3, char_code/2, clause/2,
|
bagof/3, catch/3, char_code/2, clause/2,
|
||||||
current_op/3, current_predicate/1,
|
current_input/1, current_op/3, current_predicate/1,
|
||||||
current_prolog_flag/2, expand_goal/2,
|
current_prolog_flag/2, expand_goal/2,
|
||||||
expand_term/2, fail/0, false/0, findall/3,
|
expand_term/2, fail/0, false/0, findall/3,
|
||||||
findall/4, get_char/1, halt/0, max_arity/1,
|
findall/4, get_char/1, halt/0, max_arity/1,
|
||||||
@@ -1012,3 +1012,5 @@ subsumes_term(General, Specific) :-
|
|||||||
).
|
).
|
||||||
|
|
||||||
unify_with_occurs_check(X, Y) :- '$unify_with_occurs_check'(X, Y).
|
unify_with_occurs_check(X, Y) :- '$unify_with_occurs_check'(X, Y).
|
||||||
|
|
||||||
|
current_input(S) :- '$current_input'(S).
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ use ref_thread_local::RefThreadLocal;
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
@@ -60,9 +59,9 @@ fn fix_filename(
|
|||||||
Ok(path)
|
Ok(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_module<R: Read>(
|
fn load_module(
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
stream: ParsingStream<R>,
|
stream: Stream,
|
||||||
suppress_warnings: bool,
|
suppress_warnings: bool,
|
||||||
listing_src: &ListingSource,
|
listing_src: &ListingSource,
|
||||||
) -> Result<ClauseName, SessionError> {
|
) -> Result<ClauseName, SessionError> {
|
||||||
@@ -78,7 +77,11 @@ fn load_module<R: Read>(
|
|||||||
listing_src.clone(),
|
listing_src.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let results = compiler.gather_items(wam, stream, &mut indices);
|
let results = compiler.gather_items(
|
||||||
|
wam,
|
||||||
|
&mut parsing_stream(stream),
|
||||||
|
&mut indices,
|
||||||
|
);
|
||||||
|
|
||||||
let module_name = if let Some(ref module) = &compiler.module {
|
let module_name = if let Some(ref module) = &compiler.module {
|
||||||
module.module_decl.name.clone()
|
module.module_decl.name.clone()
|
||||||
@@ -114,14 +117,14 @@ fn load_module_from_file(
|
|||||||
let mut path_buf = fix_filename(wam.indices.atom_tbl.clone(), path_buf)?;
|
let mut path_buf = fix_filename(wam.indices.atom_tbl.clone(), path_buf)?;
|
||||||
let filename = clause_name!(path_buf.to_string_lossy().to_string(), wam.indices.atom_tbl);
|
let filename = clause_name!(path_buf.to_string_lossy().to_string(), wam.indices.atom_tbl);
|
||||||
|
|
||||||
let file_handle = File::open(&path_buf).or_else(|_| {
|
let file_handle = Stream::from(File::open(&path_buf).or_else(|_| {
|
||||||
Err(SessionError::InvalidFileName(filename.clone()))
|
Err(SessionError::InvalidFileName(filename.clone()))
|
||||||
})?;
|
})?);
|
||||||
|
|
||||||
path_buf.pop();
|
path_buf.pop();
|
||||||
|
|
||||||
let listing_src = ListingSource::from_file_and_path(filename, path_buf);
|
let listing_src = ListingSource::from_file_and_path(filename, path_buf);
|
||||||
load_module(wam, parsing_stream(file_handle), suppress_warnings, &listing_src)
|
load_module(wam, file_handle, suppress_warnings, &listing_src)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
|
pub type PredicateCompileQueue = (Predicate, VecDeque<TopLevel>);
|
||||||
@@ -320,10 +323,11 @@ fn setup_module_expansions(wam: &mut Machine, module: &Module) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn compile_into_module<R: Read>(
|
pub(super)
|
||||||
|
fn compile_into_module(
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
module_name: ClauseName,
|
module_name: ClauseName,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
) -> EvalSession {
|
) -> EvalSession {
|
||||||
let mut indices = default_index_store!(wam.atom_tbl_of(&name));
|
let mut indices = default_index_store!(wam.atom_tbl_of(&name));
|
||||||
@@ -333,7 +337,11 @@ pub(super) fn compile_into_module<R: Read>(
|
|||||||
indices.op_dir = module.op_dir.clone();
|
indices.op_dir = module.op_dir.clone();
|
||||||
indices.atom_tbl = module.atom_tbl.clone();
|
indices.atom_tbl = module.atom_tbl.clone();
|
||||||
|
|
||||||
let mut compiler = ListingCompiler::new(&wam.code_repo, true, module.listing_src.clone());
|
let mut compiler = ListingCompiler::new(
|
||||||
|
&wam.code_repo,
|
||||||
|
true,
|
||||||
|
module.listing_src.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
match compile_into_module_impl(wam, &mut compiler, module, src, indices) {
|
match compile_into_module_impl(wam, &mut compiler, module, src, indices) {
|
||||||
Ok(()) => EvalSession::EntrySuccess,
|
Ok(()) => EvalSession::EntrySuccess,
|
||||||
@@ -348,11 +356,11 @@ pub(super) fn compile_into_module<R: Read>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_into_module_impl<R: Read>(
|
fn compile_into_module_impl(
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
compiler: &mut ListingCompiler,
|
compiler: &mut ListingCompiler,
|
||||||
module: Module,
|
module: Module,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
mut indices: IndexStore,
|
mut indices: IndexStore,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
setup_module_expansions(wam, &module);
|
setup_module_expansions(wam, &module);
|
||||||
@@ -363,7 +371,11 @@ fn compile_into_module_impl<R: Read>(
|
|||||||
wam.code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
|
wam.code_repo.compile_hook(CompileTimeHook::TermExpansion)?;
|
||||||
wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
|
wam.code_repo.compile_hook(CompileTimeHook::GoalExpansion)?;
|
||||||
|
|
||||||
let mut results = compiler.gather_items(wam, src, &mut indices)?;
|
let mut results = compiler.gather_items(
|
||||||
|
wam,
|
||||||
|
&mut parsing_stream(src),
|
||||||
|
&mut indices,
|
||||||
|
)?;
|
||||||
|
|
||||||
compiler.adapt_in_situ_code(
|
compiler.adapt_in_situ_code(
|
||||||
results.worker_results,
|
results.worker_results,
|
||||||
@@ -392,7 +404,6 @@ fn compile_into_module_impl<R: Read>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
wam.code_repo.code.extend(results.in_situ_code.into_iter());
|
wam.code_repo.code.extend(results.in_situ_code.into_iter());
|
||||||
|
|
||||||
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
|
clause_code_generator.add_clause_code(wam, results.dynamic_clause_map);
|
||||||
|
|
||||||
Ok(compiler.drop_expansions(&mut wam.code_repo))
|
Ok(compiler.drop_expansions(&mut wam.code_repo))
|
||||||
@@ -591,7 +602,7 @@ fn load_library(
|
|||||||
|
|
||||||
load_module(
|
load_module(
|
||||||
wam,
|
wam,
|
||||||
parsing_stream(code.as_bytes()),
|
Stream::from(*code),
|
||||||
suppress_warnings,
|
suppress_warnings,
|
||||||
&listing_src,
|
&listing_src,
|
||||||
)
|
)
|
||||||
@@ -1022,10 +1033,10 @@ impl ListingCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_multifile_decl<R: Read>(
|
fn setup_multifile_decl(
|
||||||
&self,
|
&self,
|
||||||
indicator: MultiFileIndicator,
|
indicator: MultiFileIndicator,
|
||||||
worker: &mut TopLevelBatchWorker<R>,
|
worker: &mut TopLevelBatchWorker,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
match indicator {
|
match indicator {
|
||||||
MultiFileIndicator::LocalScoped(name, arity) => {
|
MultiFileIndicator::LocalScoped(name, arity) => {
|
||||||
@@ -1055,10 +1066,10 @@ impl ListingCompiler {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_and_commit_decl<R: Read>(
|
fn process_and_commit_decl(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: Declaration,
|
decl: Declaration,
|
||||||
worker: &mut TopLevelBatchWorker<R>,
|
worker: &mut TopLevelBatchWorker,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
@@ -1105,15 +1116,15 @@ impl ListingCompiler {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn gather_items<R: Read>(
|
pub(crate) fn gather_items(
|
||||||
&mut self,
|
&mut self,
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
mut src: ParsingStream<R>,
|
src: &mut ParsingStream<Stream>,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
) -> Result<GatherResult, SessionError> {
|
) -> Result<GatherResult, SessionError> {
|
||||||
let flags = wam.machine_flags();
|
let flags = wam.machine_flags();
|
||||||
let atom_tbl = indices.atom_tbl.clone();
|
let atom_tbl = indices.atom_tbl.clone();
|
||||||
let mut worker = TopLevelBatchWorker::new(&mut src, atom_tbl.clone(), flags, wam);
|
let mut worker = TopLevelBatchWorker::new(src, atom_tbl.clone(), flags, wam);
|
||||||
|
|
||||||
let mut toplevel_results = vec![];
|
let mut toplevel_results = vec![];
|
||||||
let mut toplevel_indices = default_index_store!(atom_tbl.clone());
|
let mut toplevel_indices = default_index_store!(atom_tbl.clone());
|
||||||
@@ -1306,28 +1317,32 @@ fn compile_work_impl(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_work<R: Read>(
|
fn compile_work(
|
||||||
compiler: &mut ListingCompiler,
|
compiler: &mut ListingCompiler,
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
mut indices: IndexStore,
|
mut indices: IndexStore,
|
||||||
) -> EvalSession {
|
) -> EvalSession {
|
||||||
|
let src = &mut parsing_stream(src);
|
||||||
let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
|
let results = try_eval_session!(compiler.gather_items(wam, src, &mut indices));
|
||||||
|
|
||||||
try_eval_session!(compile_work_impl(compiler, wam, indices, results));
|
try_eval_session!(compile_work_impl(compiler, wam, indices, results));
|
||||||
|
|
||||||
EvalSession::EntrySuccess
|
EvalSession::EntrySuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a truncated version of compile_user_module, used for
|
/* This is a truncated version of compile_user_module, used for
|
||||||
compiling code composing special forms, ie. the code that calls
|
compiling code composing special forms, ie. the code that calls
|
||||||
M:verify_attributes on attributed variables. */
|
M:verify_attributes on attributed variables. */
|
||||||
pub fn compile_special_form<R: Read>(
|
pub fn compile_special_form(
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
listing_src: ListingSource,
|
listing_src: ListingSource,
|
||||||
) -> Result<usize, SessionError> {
|
) -> Result<usize, SessionError> {
|
||||||
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
|
let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
|
||||||
setup_indices(wam, clause_name!("builtins"), &mut indices)?;
|
setup_indices(wam, clause_name!("builtins"), &mut indices)?;
|
||||||
|
|
||||||
|
let src = &mut parsing_stream(src);
|
||||||
let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src);
|
let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src);
|
||||||
let mut results = compiler.gather_items(wam, src, &mut indices)?;
|
let mut results = compiler.gather_items(wam, src, &mut indices)?;
|
||||||
|
|
||||||
@@ -1352,9 +1367,9 @@ pub fn compile_special_form<R: Read>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn compile_listing<R: Read>(
|
pub fn compile_listing(
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
indices: IndexStore,
|
indices: IndexStore,
|
||||||
suppress_warnings: bool,
|
suppress_warnings: bool,
|
||||||
listing_src: ListingSource,
|
listing_src: ListingSource,
|
||||||
@@ -1388,9 +1403,9 @@ pub(super) fn setup_indices(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_user_module<R: Read>(
|
pub fn compile_user_module(
|
||||||
wam: &mut Machine,
|
wam: &mut Machine,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
suppress_warnings: bool,
|
suppress_warnings: bool,
|
||||||
listing_src: ListingSource,
|
listing_src: ListingSource,
|
||||||
) -> EvalSession {
|
) -> EvalSession {
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
Addr::PStrLocation(addr, n) => {
|
Addr::PStrLocation(addr, n) => {
|
||||||
self.copy_partial_string_from(addr, n);
|
self.copy_partial_string_from(addr, n);
|
||||||
}
|
}
|
||||||
Addr::Con(_) | Addr::DBRef(_) => {
|
Addr::Con(_) | Addr::DBRef(_) | Addr::Stream(_) => {
|
||||||
self.scan += 1;
|
self.scan += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
use prolog_parser::ast::*;
|
use prolog_parser::ast::*;
|
||||||
|
|
||||||
use crate::prolog::heap_print::*;
|
use crate::prolog::heap_print::*;
|
||||||
|
use crate::prolog::machine::*;
|
||||||
use crate::prolog::machine::compile::*;
|
use crate::prolog::machine::compile::*;
|
||||||
use crate::prolog::machine::machine_errors::*;
|
use crate::prolog::machine::machine_errors::*;
|
||||||
use crate::prolog::machine::*;
|
use crate::prolog::machine::streams::*;
|
||||||
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
pub(super) fn atom_tbl_of(&self, name: &ClauseName) -> TabledData<Atom> {
|
pub(super) fn atom_tbl_of(&self, name: &ClauseName) -> TabledData<Atom> {
|
||||||
@@ -15,9 +14,9 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_into_machine<R: Read>(
|
fn compile_into_machine(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: ParsingStream<R>,
|
src: Stream,
|
||||||
name: ClauseName,
|
name: ClauseName,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
) -> EvalSession {
|
) -> EvalSession {
|
||||||
@@ -130,7 +129,12 @@ impl Machine {
|
|||||||
) {
|
) {
|
||||||
let machine_st = mem::replace(&mut self.machine_st, MachineState::new());
|
let machine_st = mem::replace(&mut self.machine_st, MachineState::new());
|
||||||
|
|
||||||
let result = self.compile_into_machine(parsing_stream(pred_str.as_bytes()), name, arity);
|
let result = self.compile_into_machine(
|
||||||
|
Stream::from(pred_str),
|
||||||
|
name,
|
||||||
|
arity,
|
||||||
|
);
|
||||||
|
|
||||||
self.machine_st = machine_st;
|
self.machine_st = machine_st;
|
||||||
|
|
||||||
if let EvalSession::Error(err) = result {
|
if let EvalSession::Error(err) = result {
|
||||||
|
|||||||
@@ -333,12 +333,14 @@ impl ValidType {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum DomainError {
|
pub enum DomainError {
|
||||||
NotLessThanZero,
|
NotLessThanZero,
|
||||||
|
Stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DomainError {
|
impl DomainError {
|
||||||
pub fn as_str(self) -> &'static str {
|
pub fn as_str(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
DomainError::NotLessThanZero => "not_less_than_zero",
|
DomainError::NotLessThanZero => "not_less_than_zero",
|
||||||
|
DomainError::Stream => "stream",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::prolog::machine::Ball;
|
|||||||
use crate::prolog::machine::heap::*;
|
use crate::prolog::machine::heap::*;
|
||||||
use crate::prolog::machine::partial_string::*;
|
use crate::prolog::machine::partial_string::*;
|
||||||
use crate::prolog::machine::raw_block::RawBlockTraits;
|
use crate::prolog::machine::raw_block::RawBlockTraits;
|
||||||
|
use crate::prolog::machine::streams::Stream;
|
||||||
use crate::prolog::instructions::*;
|
use crate::prolog::instructions::*;
|
||||||
use crate::prolog::rug::Integer;
|
use crate::prolog::rug::Integer;
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ pub enum Addr {
|
|||||||
Str(usize),
|
Str(usize),
|
||||||
PStrLocation(usize, usize), // location of pstr in heap, offset into string in bytes.
|
PStrLocation(usize, usize), // location of pstr in heap, offset into string in bytes.
|
||||||
PStrTail(usize, usize), // location of pstr in heap, offset into string in bytes.
|
PStrTail(usize, usize), // location of pstr in heap, offset into string in bytes.
|
||||||
|
Stream(Stream),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Hash, Eq, PartialEq)]
|
#[derive(Clone, Copy, Hash, Eq, PartialEq)]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::prolog::machine::machine_errors::*;
|
|||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::modules::*;
|
use crate::prolog::machine::modules::*;
|
||||||
use crate::prolog::machine::stack::*;
|
use crate::prolog::machine::stack::*;
|
||||||
use crate::prolog::read::PrologStream;
|
use crate::prolog::machine::streams::*;
|
||||||
use crate::prolog::rug::Integer;
|
use crate::prolog::rug::Integer;
|
||||||
|
|
||||||
use downcast::Any;
|
use downcast::Any;
|
||||||
@@ -721,7 +721,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
machine_st: &mut MachineState,
|
machine_st: &mut MachineState,
|
||||||
ct: &BuiltInClauseType,
|
ct: &BuiltInClauseType,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
parsing_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
match ct {
|
match ct {
|
||||||
&BuiltInClauseType::AcyclicTerm => {
|
&BuiltInClauseType::AcyclicTerm => {
|
||||||
@@ -768,7 +768,11 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
return_from_clause!(machine_st.last_call, machine_st)
|
return_from_clause!(machine_st.last_call, machine_st)
|
||||||
}
|
}
|
||||||
&BuiltInClauseType::Read => {
|
&BuiltInClauseType::Read => {
|
||||||
match machine_st.read(parsing_stream, indices.atom_tbl.clone(), &indices.op_dir) {
|
match machine_st.read(
|
||||||
|
&mut parsing_stream(current_input_stream.clone()),
|
||||||
|
indices.atom_tbl.clone(),
|
||||||
|
&indices.op_dir,
|
||||||
|
) {
|
||||||
Ok(offset) => {
|
Ok(offset) => {
|
||||||
let addr = machine_st[temp_v!(1)].clone();
|
let addr = machine_st[temp_v!(1)].clone();
|
||||||
machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
|
machine_st.unify(addr, Addr::HeapCell(offset.heap_loc));
|
||||||
@@ -891,13 +895,13 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
machine_st: &mut MachineState,
|
machine_st: &mut MachineState,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
parsing_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
if let Some((name, arity)) = machine_st.setup_call_n(arity) {
|
||||||
match ClauseType::from(name.clone(), arity, None) {
|
match ClauseType::from(name.clone(), arity, None) {
|
||||||
ClauseType::BuiltIn(built_in) => {
|
ClauseType::BuiltIn(built_in) => {
|
||||||
machine_st.setup_built_in_call(built_in.clone());
|
machine_st.setup_built_in_call(built_in.clone());
|
||||||
self.call_builtin(machine_st, &built_in, indices, parsing_stream)?;
|
self.call_builtin(machine_st, &built_in, indices, current_input_stream)?;
|
||||||
}
|
}
|
||||||
ClauseType::CallN => {
|
ClauseType::CallN => {
|
||||||
machine_st.handle_internal_call_n(arity);
|
machine_st.handle_internal_call_n(arity);
|
||||||
@@ -977,10 +981,10 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
machine_st: &mut MachineState,
|
machine_st: &mut MachineState,
|
||||||
ct: &BuiltInClauseType,
|
ct: &BuiltInClauseType,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
parsing_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
self.prev_policy
|
self.prev_policy
|
||||||
.call_builtin(machine_st, ct, indices, parsing_stream)?;
|
.call_builtin(machine_st, ct, indices, current_input_stream)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -989,10 +993,10 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
machine_st: &mut MachineState,
|
machine_st: &mut MachineState,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
parsing_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
self.prev_policy
|
self.prev_policy
|
||||||
.call_n(machine_st, arity, indices, parsing_stream)?;
|
.call_n(machine_st, arity, indices, current_input_stream)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ use crate::prolog::machine::machine_errors::*;
|
|||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::machine_state::*;
|
use crate::prolog::machine::machine_state::*;
|
||||||
use crate::prolog::machine::stack::*;
|
use crate::prolog::machine::stack::*;
|
||||||
|
use crate::prolog::machine::streams::*;
|
||||||
use crate::prolog::ordered_float::*;
|
use crate::prolog::ordered_float::*;
|
||||||
use crate::prolog::read::PrologStream;
|
|
||||||
use crate::prolog::rug::{Integer, Rational};
|
use crate::prolog::rug::{Integer, Rational};
|
||||||
|
|
||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
@@ -1768,7 +1768,8 @@ impl MachineState {
|
|||||||
|
|
||||||
let offset = match addr {
|
let offset = match addr {
|
||||||
Addr::HeapCell(_) | Addr::StackCell(..)
|
Addr::HeapCell(_) | Addr::StackCell(..)
|
||||||
| Addr::AttrVar(..) | Addr::PStrTail(..) => {
|
| Addr::AttrVar(..) | Addr::PStrTail(..)
|
||||||
|
| Addr::Stream(_) => {
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
Addr::Con(Constant::String(n, ref s)) => {
|
Addr::Con(Constant::String(n, ref s)) => {
|
||||||
@@ -1790,7 +1791,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
Addr::Str(_) => {
|
Addr::Str(_) => {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
Addr::DBRef(_) => {
|
Addr::DBRef(_) => {
|
||||||
self.fail = true;
|
self.fail = true;
|
||||||
return;
|
return;
|
||||||
@@ -2788,7 +2789,7 @@ impl MachineState {
|
|||||||
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
|
||||||
match a1.clone() {
|
match a1.clone() {
|
||||||
Addr::DBRef(_) => self.fail = true,
|
Addr::Stream(_) | Addr::DBRef(_) => self.fail = true,
|
||||||
Addr::Con(Constant::String(n, ref s))
|
Addr::Con(Constant::String(n, ref s))
|
||||||
if !self.flags.double_quotes.is_atom() && !s[n ..].is_empty() =>
|
if !self.flags.double_quotes.is_atom() && !s[n ..].is_empty() =>
|
||||||
{
|
{
|
||||||
@@ -3217,7 +3218,7 @@ impl MachineState {
|
|||||||
code_repo: &CodeRepo,
|
code_repo: &CodeRepo,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
cut_policy: &mut Box<dyn CutPolicy>,
|
cut_policy: &mut Box<dyn CutPolicy>,
|
||||||
parsing_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
ct: &ClauseType,
|
ct: &ClauseType,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
lco: bool,
|
lco: bool,
|
||||||
@@ -3244,11 +3245,11 @@ impl MachineState {
|
|||||||
match ct {
|
match ct {
|
||||||
&ClauseType::BuiltIn(ref ct) => try_or_fail!(
|
&ClauseType::BuiltIn(ref ct) => try_or_fail!(
|
||||||
self,
|
self,
|
||||||
call_policy.call_builtin(self, ct, indices, parsing_stream)
|
call_policy.call_builtin(self, ct, indices, current_input_stream)
|
||||||
),
|
),
|
||||||
&ClauseType::CallN => try_or_fail!(
|
&ClauseType::CallN => try_or_fail!(
|
||||||
self,
|
self,
|
||||||
call_policy.call_n(self, arity, indices, parsing_stream)
|
call_policy.call_n(self, arity, indices, current_input_stream)
|
||||||
),
|
),
|
||||||
&ClauseType::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)),
|
&ClauseType::Hook(ref hook) => try_or_fail!(self, call_policy.compile_hook(self, hook)),
|
||||||
&ClauseType::Inlined(ref ct) => {
|
&ClauseType::Inlined(ref ct) => {
|
||||||
@@ -3272,7 +3273,7 @@ impl MachineState {
|
|||||||
indices,
|
indices,
|
||||||
call_policy,
|
call_policy,
|
||||||
cut_policy,
|
cut_policy,
|
||||||
parsing_stream
|
current_input_stream,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@@ -3286,18 +3287,20 @@ impl MachineState {
|
|||||||
code_repo: &CodeRepo,
|
code_repo: &CodeRepo,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
cut_policy: &mut Box<dyn CutPolicy>,
|
cut_policy: &mut Box<dyn CutPolicy>,
|
||||||
parsing_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
instr: &ControlInstruction,
|
instr: &ControlInstruction,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&ControlInstruction::Allocate(num_cells) => self.allocate(num_cells),
|
&ControlInstruction::Allocate(num_cells) => {
|
||||||
|
self.allocate(num_cells);
|
||||||
|
}
|
||||||
&ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) => self
|
&ControlInstruction::CallClause(ref ct, arity, _, lco, use_default_cp) => self
|
||||||
.handle_call_clause(
|
.handle_call_clause(
|
||||||
indices,
|
indices,
|
||||||
code_repo,
|
code_repo,
|
||||||
call_policy,
|
call_policy,
|
||||||
cut_policy,
|
cut_policy,
|
||||||
parsing_stream,
|
current_input_stream,
|
||||||
ct,
|
ct,
|
||||||
arity,
|
arity,
|
||||||
lco,
|
lco,
|
||||||
@@ -3313,7 +3316,9 @@ impl MachineState {
|
|||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p += offset;
|
self.p += offset;
|
||||||
}
|
}
|
||||||
&ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone())
|
&ControlInstruction::Proceed => {
|
||||||
|
self.p = CodePtr::Local(self.cp.clone());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ pub mod modules;
|
|||||||
mod partial_string;
|
mod partial_string;
|
||||||
mod raw_block;
|
mod raw_block;
|
||||||
mod stack;
|
mod stack;
|
||||||
|
pub(super) mod streams;
|
||||||
pub(super) mod term_expansion;
|
pub(super) mod term_expansion;
|
||||||
pub mod toplevel;
|
pub mod toplevel;
|
||||||
|
|
||||||
@@ -36,14 +37,13 @@ use crate::prolog::machine::machine_errors::*;
|
|||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::machine_state::*;
|
use crate::prolog::machine::machine_state::*;
|
||||||
use crate::prolog::machine::modules::*;
|
use crate::prolog::machine::modules::*;
|
||||||
|
use crate::prolog::machine::streams::*;
|
||||||
use crate::prolog::machine::toplevel::*;
|
use crate::prolog::machine::toplevel::*;
|
||||||
use crate::prolog::read::PrologStream;
|
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -76,7 +76,7 @@ pub struct Machine {
|
|||||||
pub(super) indices: IndexStore,
|
pub(super) indices: IndexStore,
|
||||||
pub(super) code_repo: CodeRepo,
|
pub(super) code_repo: CodeRepo,
|
||||||
pub(super) toplevel_idx: usize,
|
pub(super) toplevel_idx: usize,
|
||||||
pub(super) prolog_stream: ParsingStream<Box<dyn Read>>,
|
pub(super) current_input_stream: Stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<LocalCodePtr> for CodeRepo {
|
impl Index<LocalCodePtr> for CodeRepo {
|
||||||
@@ -216,7 +216,11 @@ impl Machine {
|
|||||||
current_dir.clone(),
|
current_dir.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes()), verify_attrs_src)
|
match compile_special_form(
|
||||||
|
self,
|
||||||
|
Stream::from(VERIFY_ATTRS),
|
||||||
|
verify_attrs_src,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
self.machine_st.attr_var_init.verify_attrs_loc = p;
|
self.machine_st.attr_var_init.verify_attrs_loc = p;
|
||||||
@@ -230,7 +234,11 @@ impl Machine {
|
|||||||
current_dir,
|
current_dir,
|
||||||
);
|
);
|
||||||
|
|
||||||
match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes()), project_attrs_src)
|
match compile_special_form(
|
||||||
|
self,
|
||||||
|
Stream::from(PROJECT_ATTRS),
|
||||||
|
project_attrs_src,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
self.machine_st.attr_var_init.project_attrs_loc = p;
|
self.machine_st.attr_var_init.project_attrs_loc = p;
|
||||||
@@ -254,7 +262,7 @@ impl Machine {
|
|||||||
|
|
||||||
compile_user_module(
|
compile_user_module(
|
||||||
self,
|
self,
|
||||||
parsing_stream(TOPLEVEL.as_bytes()),
|
Stream::from(TOPLEVEL),
|
||||||
true,
|
true,
|
||||||
top_lvl_src,
|
top_lvl_src,
|
||||||
);
|
);
|
||||||
@@ -282,7 +290,7 @@ impl Machine {
|
|||||||
|
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
let file_src = match File::open(&path) {
|
let file_src = match File::open(&path) {
|
||||||
Ok(file_handle) => parsing_stream(file_handle),
|
Ok(file_handle) => Stream::from(file_handle),
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -297,7 +305,7 @@ impl Machine {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.prolog_stream = readline::input_stream();
|
self.current_input_stream = readline::input_stream();
|
||||||
self.policies.cut_policy = Box::new(DefaultCutPolicy {});
|
self.policies.cut_policy = Box::new(DefaultCutPolicy {});
|
||||||
self.machine_st.reset();
|
self.machine_st.reset();
|
||||||
}
|
}
|
||||||
@@ -336,7 +344,7 @@ impl Machine {
|
|||||||
self.run_query();
|
self.run_query();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(prolog_stream: PrologStream) -> Self
|
pub fn new(current_input_stream: Stream) -> Self
|
||||||
{
|
{
|
||||||
let mut wam = Machine {
|
let mut wam = Machine {
|
||||||
machine_st: MachineState::new(),
|
machine_st: MachineState::new(),
|
||||||
@@ -345,7 +353,7 @@ impl Machine {
|
|||||||
indices: IndexStore::new(),
|
indices: IndexStore::new(),
|
||||||
code_repo: CodeRepo::new(),
|
code_repo: CodeRepo::new(),
|
||||||
toplevel_idx: 0,
|
toplevel_idx: 0,
|
||||||
prolog_stream,
|
current_input_stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
let atom_tbl = wam.indices.atom_tbl.clone();
|
let atom_tbl = wam.indices.atom_tbl.clone();
|
||||||
@@ -358,7 +366,7 @@ impl Machine {
|
|||||||
|
|
||||||
compile_listing(
|
compile_listing(
|
||||||
&mut wam,
|
&mut wam,
|
||||||
parsing_stream(BUILTINS.as_bytes()),
|
Stream::from(BUILTINS),
|
||||||
default_index_store!(atom_tbl.clone()),
|
default_index_store!(atom_tbl.clone()),
|
||||||
true,
|
true,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(
|
||||||
@@ -369,25 +377,36 @@ impl Machine {
|
|||||||
|
|
||||||
wam.compile_special_forms();
|
wam.compile_special_forms();
|
||||||
|
|
||||||
compile_user_module(&mut wam, parsing_stream(ERROR.as_bytes()), true,
|
compile_user_module(&mut wam,
|
||||||
|
Stream::from(ERROR),
|
||||||
|
true,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(
|
||||||
clause_name!("error"),
|
clause_name!("error"),
|
||||||
lib_path.clone(),
|
lib_path.clone(),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
compile_user_module(&mut wam, parsing_stream(LISTS.as_bytes()), true,
|
|
||||||
|
compile_user_module(&mut wam,
|
||||||
|
Stream::from(LISTS),
|
||||||
|
true,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(
|
||||||
clause_name!("lists"),
|
clause_name!("lists"),
|
||||||
lib_path.clone(),
|
lib_path.clone(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
compile_user_module(&mut wam, parsing_stream(ISO_EXT.as_bytes()), true,
|
|
||||||
|
compile_user_module(&mut wam,
|
||||||
|
Stream::from(ISO_EXT),
|
||||||
|
true,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(
|
||||||
clause_name!("iso_ext"),
|
clause_name!("iso_ext"),
|
||||||
lib_path.clone(),
|
lib_path.clone(),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
compile_user_module(&mut wam, parsing_stream(SI.as_bytes()), true,
|
|
||||||
|
compile_user_module(&mut wam,
|
||||||
|
Stream::from(SI),
|
||||||
|
true,
|
||||||
ListingSource::from_file_and_path(
|
ListingSource::from_file_and_path(
|
||||||
clause_name!("si"),
|
clause_name!("si"),
|
||||||
lib_path.clone(),
|
lib_path.clone(),
|
||||||
@@ -755,12 +774,15 @@ impl Machine {
|
|||||||
&mut self.indices,
|
&mut self.indices,
|
||||||
&mut self.policies,
|
&mut self.policies,
|
||||||
&mut self.code_repo,
|
&mut self.code_repo,
|
||||||
&mut self.prolog_stream,
|
&mut self.current_input_stream,
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.machine_st.p {
|
match self.machine_st.p {
|
||||||
CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {}
|
CodePtr::Local(LocalCodePtr::TopLevel(_, p)) if p > 0 => {
|
||||||
CodePtr::REPL(code_ptr, p) => self.handle_toplevel_command(code_ptr, p),
|
}
|
||||||
|
CodePtr::REPL(code_ptr, p) => {
|
||||||
|
self.handle_toplevel_command(code_ptr, p)
|
||||||
|
}
|
||||||
CodePtr::DynamicTransaction(trans_type, p) => {
|
CodePtr::DynamicTransaction(trans_type, p) => {
|
||||||
// self.code_repo.cached_query is about to be overwritten by the term expander,
|
// self.code_repo.cached_query is about to be overwritten by the term expander,
|
||||||
// so hold onto it locally and restore it after the compiler has finished.
|
// so hold onto it locally and restore it after the compiler has finished.
|
||||||
@@ -788,7 +810,7 @@ impl MachineState {
|
|||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &CodeRepo,
|
code_repo: &CodeRepo,
|
||||||
prolog_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||||
@@ -803,7 +825,7 @@ impl MachineState {
|
|||||||
code_repo,
|
code_repo,
|
||||||
&mut policies.call_policy,
|
&mut policies.call_policy,
|
||||||
&mut policies.cut_policy,
|
&mut policies.cut_policy,
|
||||||
prolog_stream,
|
current_input_stream,
|
||||||
control_instr,
|
control_instr,
|
||||||
),
|
),
|
||||||
&Line::Fact(ref fact_instr) => {
|
&Line::Fact(ref fact_instr) => {
|
||||||
@@ -826,14 +848,20 @@ impl MachineState {
|
|||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &CodeRepo,
|
code_repo: &CodeRepo,
|
||||||
prolog_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) {
|
) {
|
||||||
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
||||||
Some(instr) => instr,
|
Some(instr) => instr,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream);
|
self.dispatch_instr(
|
||||||
|
instr.as_ref(),
|
||||||
|
indices,
|
||||||
|
policies,
|
||||||
|
code_repo,
|
||||||
|
current_input_stream,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn backtrack(&mut self) {
|
fn backtrack(&mut self) {
|
||||||
@@ -884,7 +912,7 @@ impl MachineState {
|
|||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
prolog_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
loop {
|
loop {
|
||||||
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
let instr = match code_repo.lookup_instr(self.last_call, &self.p) {
|
||||||
@@ -900,7 +928,13 @@ impl MachineState {
|
|||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.dispatch_instr(instr.as_ref(), indices, policies, code_repo, prolog_stream);
|
self.dispatch_instr(
|
||||||
|
instr.as_ref(),
|
||||||
|
indices,
|
||||||
|
policies,
|
||||||
|
code_repo,
|
||||||
|
current_input_stream
|
||||||
|
);
|
||||||
|
|
||||||
if self.fail {
|
if self.fail {
|
||||||
self.backtrack();
|
self.backtrack();
|
||||||
@@ -924,10 +958,10 @@ impl MachineState {
|
|||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
policies: &mut MachinePolicies,
|
policies: &mut MachinePolicies,
|
||||||
code_repo: &mut CodeRepo,
|
code_repo: &mut CodeRepo,
|
||||||
prolog_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) {
|
) {
|
||||||
loop {
|
loop {
|
||||||
self.execute_instr(indices, policies, code_repo, prolog_stream);
|
self.execute_instr(indices, policies, code_repo, current_input_stream);
|
||||||
|
|
||||||
if self.fail {
|
if self.fail {
|
||||||
self.backtrack();
|
self.backtrack();
|
||||||
@@ -943,7 +977,7 @@ impl MachineState {
|
|||||||
if !instigating_instr.as_ref().is_head_instr() {
|
if !instigating_instr.as_ref().is_head_instr() {
|
||||||
let cp = self.p.local();
|
let cp = self.p.local();
|
||||||
self.run_verify_attr_interrupt(cp);
|
self.run_verify_attr_interrupt(cp);
|
||||||
} else if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) {
|
} else if !self.verify_attr_stepper(indices, policies, code_repo, current_input_stream) {
|
||||||
if self.fail {
|
if self.fail {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
245
src/prolog/machine/streams.rs
Normal file
245
src/prolog/machine/streams.rs
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
use crate::prolog_parser::ast::*;
|
||||||
|
|
||||||
|
use crate::prolog::read::readline::*;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Cursor, ErrorKind, Read, Write};
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::net::TcpStream;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum StreamType {
|
||||||
|
Binary,
|
||||||
|
Text,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub enum EOFAction {
|
||||||
|
EOFCode,
|
||||||
|
Error,
|
||||||
|
Reset,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all these streams are closed automatically when the instance is
|
||||||
|
* dropped. */
|
||||||
|
pub enum StreamInstance {
|
||||||
|
Bytes(Cursor<Vec<u8>>),
|
||||||
|
DynReadSource(Box<dyn Read>),
|
||||||
|
File(File),
|
||||||
|
ReadlineStream(ReadlineStream),
|
||||||
|
TcpStream(TcpStream),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct WrappedStreamInstance(Rc<RefCell<StreamInstance>>);
|
||||||
|
|
||||||
|
impl WrappedStreamInstance {
|
||||||
|
#[inline]
|
||||||
|
fn new(stream_inst: StreamInstance) -> Self {
|
||||||
|
WrappedStreamInstance(Rc::new(RefCell::new(stream_inst)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for WrappedStreamInstance {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
Rc::ptr_eq(&self.0, &other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for WrappedStreamInstance {}
|
||||||
|
|
||||||
|
impl Hash for WrappedStreamInstance {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
let rc = &self.0;
|
||||||
|
let ptr = Rc::into_raw(rc.clone());
|
||||||
|
|
||||||
|
state.write_usize(ptr as usize);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// necessary to avoid memory leak.
|
||||||
|
let _ = Rc::from_raw(ptr);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum StreamError {
|
||||||
|
ReadFromOutputStream,
|
||||||
|
WriteToInputStream,
|
||||||
|
FlushToInputStream,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for StreamError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
StreamError::ReadFromOutputStream => {
|
||||||
|
write!(f, "attempted to read from a write-only stream")
|
||||||
|
}
|
||||||
|
StreamError::WriteToInputStream => {
|
||||||
|
write!(f, "attempted to write to a read-only stream")
|
||||||
|
}
|
||||||
|
StreamError::FlushToInputStream => {
|
||||||
|
write!(f, "attempted to flush a read-only stream")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for StreamError {}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct StreamOptions {
|
||||||
|
pub stream_type: StreamType,
|
||||||
|
pub reposition: bool,
|
||||||
|
pub alias: Option<ClauseName>,
|
||||||
|
pub eof_action: EOFAction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for StreamOptions {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> Self {
|
||||||
|
StreamOptions {
|
||||||
|
stream_type: StreamType::Text,
|
||||||
|
reposition: false,
|
||||||
|
alias: None,
|
||||||
|
eof_action: EOFAction::EOFCode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Stream {
|
||||||
|
pub options: StreamOptions,
|
||||||
|
stream_inst: WrappedStreamInstance,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for Stream {
|
||||||
|
fn from(string: String) -> Self {
|
||||||
|
Stream {
|
||||||
|
options: StreamOptions::default(),
|
||||||
|
stream_inst: WrappedStreamInstance::new(
|
||||||
|
StreamInstance::Bytes(Cursor::new(string.into_bytes()))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ReadlineStream> for Stream {
|
||||||
|
fn from(rl_stream: ReadlineStream) -> Self {
|
||||||
|
Stream {
|
||||||
|
options: StreamOptions::default(),
|
||||||
|
stream_inst: WrappedStreamInstance::new(
|
||||||
|
StreamInstance::ReadlineStream(rl_stream)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&'static str> for Stream {
|
||||||
|
fn from(src: &'static str) -> Stream {
|
||||||
|
Stream {
|
||||||
|
options: StreamOptions::default(),
|
||||||
|
stream_inst: WrappedStreamInstance::new(
|
||||||
|
StreamInstance::DynReadSource(Box::new(src.as_bytes()))
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<File> for Stream {
|
||||||
|
fn from(file: File) -> Stream {
|
||||||
|
Stream {
|
||||||
|
options: StreamOptions::default(),
|
||||||
|
stream_inst: WrappedStreamInstance::new(
|
||||||
|
StreamInstance::File(file)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stream {
|
||||||
|
#[inline]
|
||||||
|
pub(crate)
|
||||||
|
fn as_ptr(&self) -> *const RefCell<StreamInstance> {
|
||||||
|
let rc = self.stream_inst.0.clone();
|
||||||
|
let ptr = Rc::into_raw(rc);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// must be done to avoid memory leak.
|
||||||
|
let _ = Rc::from_raw(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Read for Stream {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
match *self.stream_inst.0.borrow_mut() {
|
||||||
|
StreamInstance::File(ref mut file) => {
|
||||||
|
file.read(buf)
|
||||||
|
}
|
||||||
|
StreamInstance::TcpStream(ref mut tcp_stream) => {
|
||||||
|
tcp_stream.read(buf)
|
||||||
|
}
|
||||||
|
StreamInstance::ReadlineStream(ref mut rl_stream) => {
|
||||||
|
rl_stream.read(buf)
|
||||||
|
}
|
||||||
|
StreamInstance::DynReadSource(ref mut src) => {
|
||||||
|
src.read(buf)
|
||||||
|
}
|
||||||
|
StreamInstance::Bytes(ref mut cursor) => {
|
||||||
|
cursor.read(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for Stream {
|
||||||
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
|
match *self.stream_inst.0.borrow_mut() {
|
||||||
|
StreamInstance::File(ref mut file) => {
|
||||||
|
file.write(buf)
|
||||||
|
}
|
||||||
|
StreamInstance::TcpStream(ref mut tcp_stream) => {
|
||||||
|
tcp_stream.write(buf)
|
||||||
|
}
|
||||||
|
StreamInstance::Bytes(ref mut cursor) => {
|
||||||
|
cursor.write(buf)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
ErrorKind::PermissionDenied,
|
||||||
|
StreamError::WriteToInputStream,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
|
match *self.stream_inst.0.borrow_mut() {
|
||||||
|
StreamInstance::File(ref mut file) => {
|
||||||
|
file.flush()
|
||||||
|
}
|
||||||
|
StreamInstance::TcpStream(ref mut tcp_stream) => {
|
||||||
|
tcp_stream.flush()
|
||||||
|
}
|
||||||
|
StreamInstance::Bytes(ref mut cursor) => {
|
||||||
|
cursor.flush()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
ErrorKind::PermissionDenied,
|
||||||
|
StreamError::FlushToInputStream,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: write a Seek instance.
|
||||||
@@ -12,9 +12,10 @@ use crate::prolog::machine::code_walker::*;
|
|||||||
use crate::prolog::machine::machine_errors::*;
|
use crate::prolog::machine::machine_errors::*;
|
||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::machine_state::*;
|
use crate::prolog::machine::machine_state::*;
|
||||||
|
use crate::prolog::machine::streams::*;
|
||||||
use crate::prolog::machine::toplevel::to_op_decl;
|
use crate::prolog::machine::toplevel::to_op_decl;
|
||||||
use crate::prolog::ordered_float::OrderedFloat;
|
use crate::prolog::ordered_float::OrderedFloat;
|
||||||
use crate::prolog::read::{readline, PrologStream};
|
use crate::prolog::read::readline;
|
||||||
use crate::prolog::rug::Integer;
|
use crate::prolog::rug::Integer;
|
||||||
|
|
||||||
use crate::ref_thread_local::RefThreadLocal;
|
use crate::ref_thread_local::RefThreadLocal;
|
||||||
@@ -354,12 +355,12 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_term(&mut self,
|
fn read_term(&mut self,
|
||||||
current_input_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
indices: &mut IndexStore)
|
indices: &mut IndexStore)
|
||||||
-> CallResult
|
-> CallResult
|
||||||
{
|
{
|
||||||
match self.read(
|
match self.read(
|
||||||
current_input_stream,
|
&mut parsing_stream(current_input_stream.clone()),
|
||||||
indices.atom_tbl.clone(),
|
indices.atom_tbl.clone(),
|
||||||
&indices.op_dir,
|
&indices.op_dir,
|
||||||
) {
|
) {
|
||||||
@@ -671,7 +672,7 @@ impl MachineState {
|
|||||||
indices: &mut IndexStore,
|
indices: &mut IndexStore,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
cut_policy: &mut Box<dyn CutPolicy>,
|
cut_policy: &mut Box<dyn CutPolicy>,
|
||||||
current_input_stream: &mut PrologStream,
|
current_input_stream: &mut Stream,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
match ct {
|
match ct {
|
||||||
&SystemClauseType::AbolishClause => {
|
&SystemClauseType::AbolishClause => {
|
||||||
@@ -721,6 +722,32 @@ impl MachineState {
|
|||||||
self.p = CodePtr::DynamicTransaction(trans_type, p);
|
self.p = CodePtr::DynamicTransaction(trans_type, p);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::CurrentInput => {
|
||||||
|
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
|
||||||
|
let stream = current_input_stream.clone();
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
addr if addr.is_ref() => {
|
||||||
|
self.unify(Addr::Stream(stream), addr);
|
||||||
|
}
|
||||||
|
Addr::Stream(other_stream) => {
|
||||||
|
self.fail = stream != other_stream;
|
||||||
|
}
|
||||||
|
addr => {
|
||||||
|
let stub = MachineError::functor_stub(
|
||||||
|
clause_name!("current_input"),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
let err = MachineError::domain_error(
|
||||||
|
DomainError::Stream,
|
||||||
|
addr,
|
||||||
|
);
|
||||||
|
|
||||||
|
return Err(self.error_form(err, stub));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
&SystemClauseType::AtEndOfExpansion => {
|
&SystemClauseType::AtEndOfExpansion => {
|
||||||
if self.cp == LocalCodePtr::TopLevel(0, 0) {
|
if self.cp == LocalCodePtr::TopLevel(0, 0) {
|
||||||
self.at_end_of_expansion = true;
|
self.at_end_of_expansion = true;
|
||||||
@@ -1177,7 +1204,9 @@ impl MachineState {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
&SystemClauseType::GetChar => {
|
&SystemClauseType::GetChar => {
|
||||||
let result = current_input_stream.next();
|
let mut iter = parsing_stream(current_input_stream.clone());
|
||||||
|
let result = iter.next();
|
||||||
|
|
||||||
let a1 = self[temp_v!(1)].clone();
|
let a1 = self[temp_v!(1)].clone();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
@@ -2315,7 +2344,7 @@ impl MachineState {
|
|||||||
// get the call site so that the number of active permanent variables can be read
|
// get the call site so that the number of active permanent variables can be read
|
||||||
// from it later.
|
// from it later.
|
||||||
let cp = (self.stack.index_and_frame(e).prelude.cp - 1).unwrap();
|
let cp = (self.stack.index_and_frame(e).prelude.cp - 1).unwrap();
|
||||||
|
|
||||||
let p = cp.as_functor(&mut self.heap);
|
let p = cp.as_functor(&mut self.heap);
|
||||||
let e = self.stack.index_and_frame(e).prelude.e;
|
let e = self.stack.index_and_frame(e).prelude.e;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use crate::prolog::rug::Integer;
|
|||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io::Read;
|
|
||||||
use std::iter::Rev;
|
use std::iter::Rev;
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
@@ -28,7 +27,11 @@ where
|
|||||||
term
|
term
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_from_list(head: Box<Term>, tail: Box<Term>) -> Result<Rev<IntoIter<Term>>, ParserError> {
|
fn extract_from_list(
|
||||||
|
head: Box<Term>,
|
||||||
|
tail: Box<Term>,
|
||||||
|
) -> Result<Rev<IntoIter<Term>>, ParserError>
|
||||||
|
{
|
||||||
let mut terms = vec![*head];
|
let mut terms = vec![*head];
|
||||||
let mut tail = *tail;
|
let mut tail = *tail;
|
||||||
|
|
||||||
@@ -44,10 +47,10 @@ fn extract_from_list(head: Box<Term>, tail: Box<Term>) -> Result<Rev<IntoIter<Te
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TermStream<'a, R: Read> {
|
pub struct TermStream<'a> {
|
||||||
stack: Vec<Term>,
|
stack: Vec<Term>,
|
||||||
pub(crate) wam: &'a mut Machine,
|
pub(crate) wam: &'a mut Machine,
|
||||||
parser: Parser<'a, R>,
|
parser: Parser<'a, Stream>,
|
||||||
pub(crate) flags: MachineFlags,
|
pub(crate) flags: MachineFlags,
|
||||||
term_expansion_lens: (usize, usize),
|
term_expansion_lens: (usize, usize),
|
||||||
goal_expansion_lens: (usize, usize),
|
goal_expansion_lens: (usize, usize),
|
||||||
@@ -75,7 +78,7 @@ impl ExpansionAdditionResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: Read> Drop for TermStream<'a, R> {
|
impl<'a> Drop for TermStream<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.wam.indices.in_situ_code_dir.clear();
|
self.wam.indices.in_situ_code_dir.clear();
|
||||||
self.wam.indices.in_situ_module_dir.clear();
|
self.wam.indices.in_situ_module_dir.clear();
|
||||||
@@ -85,9 +88,9 @@ impl<'a, R: Read> Drop for TermStream<'a, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: Read> TermStream<'a, R> {
|
impl<'a> TermStream<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
src: &'a mut ParsingStream<R>,
|
src: &'a mut ParsingStream<Stream>,
|
||||||
atom_tbl: TabledData<Atom>,
|
atom_tbl: TabledData<Atom>,
|
||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
wam: &'a mut Machine,
|
wam: &'a mut Machine,
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use indexmap::{IndexMap, IndexSet};
|
|||||||
use std::borrow::BorrowMut;
|
use std::borrow::BorrowMut;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io::Read;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -30,15 +29,15 @@ fn op_dir<'a, 'b: 'a>(from: &'b IndexSource<'a, IndexStore>) -> RefOrOwned<'a, O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CompositeIndices<'a, 'b, 'c, R: Read> {
|
struct CompositeIndices<'a, 'b, 'c> {
|
||||||
term_stream: &'b mut TermStream<'a, R>,
|
term_stream: &'b mut TermStream<'a>,
|
||||||
index_src: IndexSource<'c, IndexStore>,
|
index_src: IndexSource<'c, IndexStore>,
|
||||||
static_code_dir: Option<IndexSource<'c, CodeDir>>
|
static_code_dir: Option<IndexSource<'c, CodeDir>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> {
|
impl<'a, 'b, 'c> CompositeIndices<'a, 'b, 'c> {
|
||||||
fn new(
|
fn new(
|
||||||
term_stream: &'b mut TermStream<'a, R>,
|
term_stream: &'b mut TermStream<'a>,
|
||||||
index_src: IndexSource<'c, IndexStore>,
|
index_src: IndexSource<'c, IndexStore>,
|
||||||
static_code_dir: Option<IndexSource<'c, CodeDir>>,
|
static_code_dir: Option<IndexSource<'c, CodeDir>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -577,8 +576,8 @@ fn draw_from_term_dir_impl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_from_term_dir<R: Read>(
|
fn draw_from_term_dir(
|
||||||
indices: &CompositeIndices<R>,
|
indices: &CompositeIndices,
|
||||||
intra_module_term_dirs: &mut IndexMap<ClauseName, TermDirQuantum>,
|
intra_module_term_dirs: &mut IndexMap<ClauseName, TermDirQuantum>,
|
||||||
top_level_term_dirs: &mut TermDirQuantum,
|
top_level_term_dirs: &mut TermDirQuantum,
|
||||||
key: &PredicateKey,
|
key: &PredicateKey,
|
||||||
@@ -615,8 +614,8 @@ fn draw_from_term_dir<R: Read>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_declaration<'a, 'b, 'c, R: Read>(
|
fn setup_declaration<'a, 'b, 'c>(
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
mut terms: Vec<Box<Term>>,
|
mut terms: Vec<Box<Term>>,
|
||||||
line_num: usize,
|
line_num: usize,
|
||||||
@@ -796,9 +795,9 @@ impl RelationWorker {
|
|||||||
self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
|
self.fabricate_rule(fold_by_str(prec_seq.into_iter(), body_term, comma_sym))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_query_term<'a, 'b, 'c, R: Read>(
|
fn to_query_term<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
term: Term,
|
term: Term,
|
||||||
) -> Result<QueryTerm, ParserError> {
|
) -> Result<QueryTerm, ParserError> {
|
||||||
match term {
|
match term {
|
||||||
@@ -872,9 +871,9 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_query_term<'a, 'b, 'c, R: Read>(
|
fn pre_query_term<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
term: Term,
|
term: Term,
|
||||||
) -> Result<QueryTerm, ParserError> {
|
) -> Result<QueryTerm, ParserError> {
|
||||||
match term {
|
match term {
|
||||||
@@ -893,9 +892,9 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_query<'a, 'b, 'c, R: Read>(
|
fn setup_query<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
terms: Vec<Box<Term>>,
|
terms: Vec<Box<Term>>,
|
||||||
blocks_cuts: bool,
|
blocks_cuts: bool,
|
||||||
) -> Result<Vec<QueryTerm>, ParserError> {
|
) -> Result<Vec<QueryTerm>, ParserError> {
|
||||||
@@ -946,10 +945,10 @@ impl RelationWorker {
|
|||||||
Ok(query_terms)
|
Ok(query_terms)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_hook<'a, 'b, 'c, R: Read>(
|
fn setup_hook<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
hook: CompileTimeHook,
|
hook: CompileTimeHook,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
term: Term,
|
term: Term,
|
||||||
) -> Result<CompileTimeHookCompileInfo, ParserError> {
|
) -> Result<CompileTimeHookCompileInfo, ParserError> {
|
||||||
match flatten_hook(term) {
|
match flatten_hook(term) {
|
||||||
@@ -970,9 +969,9 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_rule<'a, 'b, 'c, R: Read>(
|
fn setup_rule<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
mut terms: Vec<Box<Term>>,
|
mut terms: Vec<Box<Term>>,
|
||||||
blocks_cuts: bool,
|
blocks_cuts: bool,
|
||||||
assume_dyn: bool,
|
assume_dyn: bool,
|
||||||
@@ -1003,9 +1002,9 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_term_to_query<'a, 'b, 'c, R: Read>(
|
fn try_term_to_query<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
terms: Vec<Box<Term>>,
|
terms: Vec<Box<Term>>,
|
||||||
blocks_cuts: bool,
|
blocks_cuts: bool,
|
||||||
) -> Result<TopLevel, ParserError> {
|
) -> Result<TopLevel, ParserError> {
|
||||||
@@ -1016,10 +1015,10 @@ impl RelationWorker {
|
|||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compact_module_scoped_head<'a, 'b, 'c, R: Read>(
|
fn compact_module_scoped_head<'a, 'b, 'c>(
|
||||||
&self,
|
&self,
|
||||||
term: &mut Term,
|
term: &mut Term,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
) {
|
) {
|
||||||
let inner_term = match term {
|
let inner_term = match term {
|
||||||
Term::Clause(_, ref name, ref mut inner_terms, _)
|
Term::Clause(_, ref name, ref mut inner_terms, _)
|
||||||
@@ -1044,9 +1043,9 @@ impl RelationWorker {
|
|||||||
*term = inner_term;
|
*term = inner_term;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_term_to_tl<'a, 'b, 'c, R: Read>(
|
fn try_term_to_tl<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
term: Term,
|
term: Term,
|
||||||
blocks_cuts: bool,
|
blocks_cuts: bool,
|
||||||
) -> Result<TopLevel, ParserError> {
|
) -> Result<TopLevel, ParserError> {
|
||||||
@@ -1085,14 +1084,14 @@ impl RelationWorker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_terms_to_tls<'a, 'b, 'c, I, R>(
|
fn try_terms_to_tls<'a, 'b, 'c, I>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
terms: I,
|
terms: I,
|
||||||
blocks_cuts: bool,
|
blocks_cuts: bool,
|
||||||
) -> Result<VecDeque<TopLevel>, ParserError>
|
) -> Result<VecDeque<TopLevel>, ParserError>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Term>, R: Read
|
I: IntoIterator<Item = Term>
|
||||||
{
|
{
|
||||||
let mut results = VecDeque::new();
|
let mut results = VecDeque::new();
|
||||||
|
|
||||||
@@ -1103,9 +1102,9 @@ impl RelationWorker {
|
|||||||
Ok(results)
|
Ok(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_queue<'a, 'b, 'c, R: Read>(
|
fn parse_queue<'a, 'b, 'c>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indices: &mut CompositeIndices<'a, 'b, 'c, R>,
|
indices: &mut CompositeIndices<'a, 'b, 'c>,
|
||||||
) -> Result<VecDeque<TopLevel>, ParserError> {
|
) -> Result<VecDeque<TopLevel>, ParserError> {
|
||||||
let mut queue = VecDeque::new();
|
let mut queue = VecDeque::new();
|
||||||
|
|
||||||
@@ -1128,8 +1127,8 @@ pub type DynamicClause = Vec<(Term, Term)>;
|
|||||||
|
|
||||||
pub type DynamicClauseMap = IndexMap<(ClauseName, usize), DynamicClause>;
|
pub type DynamicClauseMap = IndexMap<(ClauseName, usize), DynamicClause>;
|
||||||
|
|
||||||
pub struct TopLevelBatchWorker<'a, R: Read> {
|
pub struct TopLevelBatchWorker<'a> {
|
||||||
pub(crate) term_stream: TermStream<'a, R>,
|
pub(crate) term_stream: TermStream<'a>,
|
||||||
rel_worker: RelationWorker,
|
rel_worker: RelationWorker,
|
||||||
pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
|
pub(crate) results: Vec<(Predicate, VecDeque<TopLevel>)>,
|
||||||
pub(crate) dynamic_clause_map: DynamicClauseMap,
|
pub(crate) dynamic_clause_map: DynamicClauseMap,
|
||||||
@@ -1139,14 +1138,14 @@ pub struct TopLevelBatchWorker<'a, R: Read> {
|
|||||||
pub(crate) non_counted_bt_preds: IndexSet<PredicateKey>,
|
pub(crate) non_counted_bt_preds: IndexSet<PredicateKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: Read> TopLevelBatchWorker<'a, R> {
|
impl<'a> TopLevelBatchWorker<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
inner: &'a mut ParsingStream<R>,
|
stream: &'a mut ParsingStream<Stream>,
|
||||||
atom_tbl: TabledData<Atom>,
|
atom_tbl: TabledData<Atom>,
|
||||||
flags: MachineFlags,
|
flags: MachineFlags,
|
||||||
wam: &'a mut Machine,
|
wam: &'a mut Machine,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let term_stream = TermStream::new(inner, atom_tbl, flags, wam);
|
let term_stream = TermStream::new(stream, atom_tbl, flags, wam);
|
||||||
|
|
||||||
let line_num = term_stream.line_num();
|
let line_num = term_stream.line_num();
|
||||||
let col_num = term_stream.col_num();
|
let col_num = term_stream.col_num();
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use crate::prolog::forms::*;
|
|||||||
use crate::prolog::iterators::*;
|
use crate::prolog::iterators::*;
|
||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::machine_state::MachineState;
|
use crate::prolog::machine::machine_state::MachineState;
|
||||||
|
use crate::prolog::machine::streams::Stream;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
type SubtermDeque = VecDeque<(usize, usize)>;
|
type SubtermDeque = VecDeque<(usize, usize)>;
|
||||||
|
|
||||||
@@ -23,10 +23,10 @@ impl<'a> TermRef<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type PrologStream = ParsingStream<Box<dyn Read>>;
|
pub type PrologStream = ParsingStream<Stream>;
|
||||||
|
|
||||||
pub mod readline {
|
pub mod readline {
|
||||||
use prolog_parser::ast::*;
|
use crate::prolog::machine::streams::Stream;
|
||||||
use crate::prolog::rustyline::error::ReadlineError;
|
use crate::prolog::rustyline::error::ReadlineError;
|
||||||
use crate::prolog::rustyline::{Cmd, Editor, KeyPress};
|
use crate::prolog::rustyline::{Cmd, Editor, KeyPress};
|
||||||
use std::io::{Cursor, Read};
|
use std::io::{Cursor, Read};
|
||||||
@@ -52,10 +52,10 @@ pub mod readline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ReadlineStream {
|
impl ReadlineStream {
|
||||||
fn input_stream(pending_input: String) -> Self {
|
pub fn input_stream(pending_input: String) -> Stream {
|
||||||
let mut rl = Editor::<()>::new();
|
let mut rl = Editor::<()>::new();
|
||||||
rl.bind_sequence(KeyPress::Tab, Cmd::Insert(1, "\t".to_string()));
|
rl.bind_sequence(KeyPress::Tab, Cmd::Insert(1, "\t".to_string()));
|
||||||
ReadlineStream { rl, pending_input: Cursor::new(pending_input) }
|
Stream::from(ReadlineStream { rl, pending_input: Cursor::new(pending_input) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_readline(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
fn call_readline(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
@@ -99,9 +99,9 @@ pub mod readline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn input_stream() -> crate::PrologStream {
|
pub fn input_stream() -> Stream {
|
||||||
let reader: Box<dyn Read> = Box::new(ReadlineStream::input_stream(String::from("")));
|
let input_stream = ReadlineStream::input_stream(String::from(""));
|
||||||
parsing_stream(reader)
|
Stream::from(input_stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ impl fmt::Display for Addr {
|
|||||||
&Addr::Str(s) => write!(f, "Addr::Str({})", s),
|
&Addr::Str(s) => write!(f, "Addr::Str({})", s),
|
||||||
&Addr::PStrLocation(h, n) => write!(f, "Addr::PStrLocation({}, {})", h, n),
|
&Addr::PStrLocation(h, n) => write!(f, "Addr::PStrLocation({}, {})", h, n),
|
||||||
&Addr::PStrTail(h, n) => write!(f, "Addr::PStrTail({}, {})", h, n),
|
&Addr::PStrTail(h, n) => write!(f, "Addr::PStrTail({}, {})", h, n),
|
||||||
|
&Addr::Stream(ref stream) => write!(f, "Addr::Stream({})", stream.as_ptr() as usize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user