Merge branch 'sockets-develop'
This commit is contained in:
@@ -119,7 +119,7 @@ fn load_module_from_file(
|
||||
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 file_handle = Stream::from(File::open(&path_buf).or_else(|_| {
|
||||
let file_handle = Stream::from_file_as_input(filename.clone(), File::open(&path_buf).or_else(|_| {
|
||||
Err(SessionError::InvalidFileName(filename.clone()))
|
||||
})?);
|
||||
|
||||
@@ -614,7 +614,7 @@ fn load_library(
|
||||
)
|
||||
}
|
||||
None => {
|
||||
let err = ExistenceError::SourceSink(ModuleSource::Library(
|
||||
let err = ExistenceError::ModuleSource(ModuleSource::Library(
|
||||
name.clone()
|
||||
));
|
||||
|
||||
@@ -705,7 +705,7 @@ impl ListingCompiler {
|
||||
|
||||
Ok(wam_indices.insert_module(submodule))
|
||||
} else {
|
||||
let err = ExistenceError::SourceSink(ModuleSource::File(
|
||||
let err = ExistenceError::ModuleSource(ModuleSource::File(
|
||||
module_name,
|
||||
));
|
||||
|
||||
@@ -743,7 +743,7 @@ impl ListingCompiler {
|
||||
|
||||
Ok(wam_indices.insert_module(submodule))
|
||||
} else {
|
||||
let err = ExistenceError::SourceSink(ModuleSource::File(
|
||||
let err = ExistenceError::ModuleSource(ModuleSource::File(
|
||||
module_name
|
||||
));
|
||||
|
||||
@@ -1077,7 +1077,7 @@ impl ListingCompiler {
|
||||
insert_or_refresh_term_dir_quantum(term_dir, key, term_dirs);
|
||||
}
|
||||
None => {
|
||||
let err = ExistenceError::SourceSink(ModuleSource::File(
|
||||
let err = ExistenceError::ModuleSource(ModuleSource::File(
|
||||
module_name,
|
||||
));
|
||||
|
||||
@@ -1436,7 +1436,7 @@ pub(super) fn setup_indices(
|
||||
wam.indices.insert_module(module);
|
||||
result
|
||||
} else {
|
||||
let err = ExistenceError::SourceSink(ModuleSource::Library(
|
||||
let err = ExistenceError::ModuleSource(ModuleSource::Library(
|
||||
module
|
||||
));
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::stack::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::IndexMut;
|
||||
@@ -215,24 +214,6 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_stream(&mut self, addr: usize) {
|
||||
let threshold = self.target.threshold();
|
||||
|
||||
let trail_item = mem::replace(
|
||||
&mut self.target[addr],
|
||||
HeapCellValue::Addr(Addr::Stream(threshold)),
|
||||
);
|
||||
|
||||
self.trail.push((
|
||||
Ref::HeapCell(addr),
|
||||
trail_item,
|
||||
));
|
||||
|
||||
self.target.push(HeapCellValue::Stream(Stream::null_stream()));
|
||||
|
||||
self.scan += 1;
|
||||
}
|
||||
|
||||
fn copy_structure(&mut self, addr: usize) {
|
||||
match self.target[addr].context_free_clone() {
|
||||
HeapCellValue::NamedStr(arity, name, fixity) => {
|
||||
@@ -285,11 +266,12 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
*self.value_at_scan() = HeapCellValue::Addr(addr);
|
||||
}
|
||||
}
|
||||
Addr::Lis(h) if h >= self.old_h => {
|
||||
self.scan += 1;
|
||||
}
|
||||
Addr::Lis(h) => {
|
||||
self.copy_list(h);
|
||||
if h >= self.old_h {
|
||||
self.scan += 1;
|
||||
} else {
|
||||
self.copy_list(h);
|
||||
}
|
||||
}
|
||||
addr @ Addr::AttrVar(_) |
|
||||
addr @ Addr::HeapCell(_) |
|
||||
@@ -303,7 +285,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
||||
self.copy_partial_string(addr, n);
|
||||
}
|
||||
Addr::Stream(h) => {
|
||||
self.copy_stream(h);
|
||||
*self.value_at_scan() = self.target[h].context_free_clone();
|
||||
}
|
||||
_ => {
|
||||
self.scan += 1;
|
||||
|
||||
@@ -171,15 +171,18 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
&HeapCellValue::NamedStr(arity, ref name, ref op) => {
|
||||
HeapCellValue::NamedStr(arity, name.clone(), op.clone())
|
||||
}
|
||||
&HeapCellValue::Rational(ref r) => {
|
||||
HeapCellValue::Rational(r.clone())
|
||||
}
|
||||
&HeapCellValue::PartialString(..) => {
|
||||
HeapCellValue::Addr(Addr::PStrLocation(h, 0))
|
||||
}
|
||||
&HeapCellValue::Rational(ref r) => {
|
||||
HeapCellValue::Rational(r.clone())
|
||||
}
|
||||
&HeapCellValue::Stream(_) => {
|
||||
HeapCellValue::Addr(Addr::Stream(h))
|
||||
}
|
||||
&HeapCellValue::TcpListener(_) => {
|
||||
HeapCellValue::Addr(Addr::TcpListener(h))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,18 +288,15 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
HeapCellValue::Addr(addr) => {
|
||||
addr
|
||||
}
|
||||
val @ HeapCellValue::Atom(..)
|
||||
| val @ HeapCellValue::Integer(_)
|
||||
| val @ HeapCellValue::DBRef(_)
|
||||
| val @ HeapCellValue::Rational(_) => {
|
||||
val @ HeapCellValue::Atom(..) |
|
||||
val @ HeapCellValue::Integer(_) |
|
||||
val @ HeapCellValue::DBRef(_) |
|
||||
val @ HeapCellValue::Rational(_) => {
|
||||
Addr::Con(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::NamedStr(..) => {
|
||||
Addr::Str(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::Stream(..) => {
|
||||
Addr::Stream(self.push(val))
|
||||
}
|
||||
HeapCellValue::PartialString(pstr, has_tail) => {
|
||||
let h = self.push(HeapCellValue::PartialString(pstr, has_tail));
|
||||
|
||||
@@ -306,6 +306,12 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
|
||||
Addr::Con(h)
|
||||
}
|
||||
val @ HeapCellValue::Stream(..) => {
|
||||
Addr::Stream(self.push(val))
|
||||
}
|
||||
val @ HeapCellValue::TcpListener(..) => {
|
||||
Addr::TcpListener(self.push(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,7 +523,7 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
||||
pub
|
||||
fn index_addr<'a>(&'a self, addr: &Addr) -> RefOrOwned<'a, HeapCellValue> {
|
||||
match addr {
|
||||
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) => {
|
||||
&Addr::Con(h) | &Addr::Str(h) | &Addr::Stream(h) | &Addr::TcpListener(h) => {
|
||||
RefOrOwned::Borrowed(&self[h])
|
||||
}
|
||||
addr => {
|
||||
|
||||
@@ -17,13 +17,13 @@ enum ErrorProvenance {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct MachineError {
|
||||
pub(crate) struct MachineError {
|
||||
stub: MachineStub,
|
||||
location: Option<(usize, usize)>, // line_num, col_num
|
||||
from: ErrorProvenance,
|
||||
}
|
||||
|
||||
pub(super)
|
||||
pub(crate)
|
||||
trait TypeError {
|
||||
fn type_error(self, h: usize, valid_type: ValidType) -> MachineError;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ impl TypeError for Number {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super)
|
||||
pub(crate)
|
||||
trait PermissionError {
|
||||
fn permission_error(self, h: usize, index_str: &'static str, perm: Permission) -> MachineError;
|
||||
}
|
||||
@@ -250,7 +250,7 @@ impl MachineError {
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
ExistenceError::SourceSink(source) => {
|
||||
ExistenceError::ModuleSource(source) => {
|
||||
let source_stub = source.as_functor_stub();
|
||||
|
||||
let stub = functor!(
|
||||
@@ -265,6 +265,18 @@ impl MachineError {
|
||||
from: ErrorProvenance::Constructed,
|
||||
}
|
||||
}
|
||||
ExistenceError::SourceSink(culprit) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
[atom("source_sink"), addr(culprit)]
|
||||
);
|
||||
|
||||
MachineError {
|
||||
stub,
|
||||
location: None,
|
||||
from: ErrorProvenance::Received,
|
||||
}
|
||||
}
|
||||
ExistenceError::Stream(culprit) => {
|
||||
let stub = functor!(
|
||||
"existence_error",
|
||||
@@ -454,17 +466,22 @@ pub enum Permission {
|
||||
Create,
|
||||
InputStream,
|
||||
Modify,
|
||||
Open,
|
||||
OutputStream,
|
||||
Reposition,
|
||||
}
|
||||
|
||||
impl Permission {
|
||||
#[inline]
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
Permission::Access => "access",
|
||||
Permission::Create => "create",
|
||||
Permission::InputStream => "input",
|
||||
Permission::Modify => "modify",
|
||||
Permission::Open => "open",
|
||||
Permission::OutputStream => "output",
|
||||
Permission::Reposition => "reposition",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -475,20 +492,21 @@ pub enum ValidType {
|
||||
Atom,
|
||||
Atomic,
|
||||
// Boolean,
|
||||
// Byte,
|
||||
Byte,
|
||||
Callable,
|
||||
Character,
|
||||
Compound,
|
||||
Evaluable,
|
||||
Float,
|
||||
// InByte,
|
||||
// InCharacter,
|
||||
InByte,
|
||||
InCharacter,
|
||||
Integer,
|
||||
List,
|
||||
// Number,
|
||||
Pair,
|
||||
// PredicateIndicator,
|
||||
// Variable
|
||||
TcpListener,
|
||||
}
|
||||
|
||||
impl ValidType {
|
||||
@@ -497,26 +515,28 @@ impl ValidType {
|
||||
ValidType::Atom => "atom",
|
||||
ValidType::Atomic => "atomic",
|
||||
// ValidType::Boolean => "boolean",
|
||||
// ValidType::Byte => "byte",
|
||||
ValidType::Byte => "byte",
|
||||
ValidType::Callable => "callable",
|
||||
ValidType::Character => "character",
|
||||
ValidType::Compound => "compound",
|
||||
ValidType::Evaluable => "evaluable",
|
||||
ValidType::Float => "float",
|
||||
// ValidType::InByte => "in_byte",
|
||||
// ValidType::InCharacter => "in_character",
|
||||
ValidType::InByte => "in_byte",
|
||||
ValidType::InCharacter => "in_character",
|
||||
ValidType::Integer => "integer",
|
||||
ValidType::List => "list",
|
||||
// ValidType::Number => "number",
|
||||
ValidType::Pair => "pair",
|
||||
// ValidType::PredicateIndicator => "predicate_indicator",
|
||||
// ValidType::Variable => "variable"
|
||||
ValidType::TcpListener => "tcp_listener",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DomainErrorType {
|
||||
IOMode,
|
||||
NotLessThanZero,
|
||||
Order,
|
||||
Stream,
|
||||
@@ -526,6 +546,7 @@ pub enum DomainErrorType {
|
||||
impl DomainErrorType {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
DomainErrorType::IOMode => "io_mode",
|
||||
DomainErrorType::NotLessThanZero => "not_less_than_zero",
|
||||
DomainErrorType::Order => "order",
|
||||
DomainErrorType::Stream => "stream",
|
||||
@@ -537,9 +558,9 @@ impl DomainErrorType {
|
||||
// from 7.12.2 f) of 13211-1:1995
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum RepFlag {
|
||||
Character,
|
||||
// Character,
|
||||
CharacterCode,
|
||||
// InCharacterCode,
|
||||
InCharacterCode,
|
||||
MaxArity,
|
||||
// MaxInteger,
|
||||
// MinInteger
|
||||
@@ -548,9 +569,9 @@ pub enum RepFlag {
|
||||
impl RepFlag {
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
RepFlag::Character => "character",
|
||||
// RepFlag::Character => "character",
|
||||
RepFlag::CharacterCode => "character_code",
|
||||
// RepFlag::InCharacterCode => "in_character_code",
|
||||
RepFlag::InCharacterCode => "in_character_code",
|
||||
RepFlag::MaxArity => "max_arity",
|
||||
// RepFlag::MaxInteger => "max_integer",
|
||||
// RepFlag::MinInteger => "min_integer"
|
||||
@@ -681,6 +702,41 @@ impl MachineState {
|
||||
self.check_for_list_pairs(sorted)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn type_error<T: TypeError>(
|
||||
&self,
|
||||
valid_type: ValidType,
|
||||
culprit: T,
|
||||
caller: ClauseName,
|
||||
arity: usize,
|
||||
) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(caller, arity);
|
||||
let err = MachineError::type_error(
|
||||
self.heap.h(),
|
||||
valid_type,
|
||||
culprit,
|
||||
);
|
||||
|
||||
return self.error_form(err, stub);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate)
|
||||
fn representation_error(
|
||||
&self,
|
||||
rep_flag: RepFlag,
|
||||
caller: ClauseName,
|
||||
arity: usize,
|
||||
) -> MachineStub {
|
||||
let stub = MachineError::functor_stub(caller, arity);
|
||||
let err = MachineError::representation_error(
|
||||
rep_flag,
|
||||
);
|
||||
|
||||
return self.error_form(err, stub);
|
||||
}
|
||||
|
||||
pub(super)
|
||||
fn error_form(&self, err: MachineError, src: MachineStub) -> MachineStub {
|
||||
let location = err.location;
|
||||
@@ -726,8 +782,9 @@ impl MachineState {
|
||||
#[derive(Debug)]
|
||||
pub enum ExistenceError {
|
||||
Module(ClauseName),
|
||||
ModuleSource(ModuleSource),
|
||||
Procedure(ClauseName, usize),
|
||||
SourceSink(ModuleSource),
|
||||
SourceSink(Addr),
|
||||
Stream(Addr),
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@ use indexmap::IndexMap;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{BTreeMap, VecDeque};
|
||||
use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::net::TcpListener;
|
||||
use std::ops::{Add, AddAssign, Sub, SubAssign};
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -69,6 +70,7 @@ pub enum Addr {
|
||||
StackCell(usize, usize),
|
||||
Str(usize),
|
||||
Stream(usize),
|
||||
TcpListener(usize),
|
||||
Usize(usize),
|
||||
}
|
||||
|
||||
@@ -230,7 +232,7 @@ impl Addr {
|
||||
Addr::Lis(_) | Addr::PStrLocation(..) | Addr::Str(_) => {
|
||||
Some(TermOrderCategory::Compound)
|
||||
}
|
||||
Addr::CutPoint(_) | Addr::Stream(_) => {
|
||||
Addr::CutPoint(_) | Addr::Stream(_) | Addr::TcpListener(_) => {
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -388,6 +390,7 @@ pub enum HeapCellValue {
|
||||
Rational(Rc<Rational>),
|
||||
PartialString(PartialString, bool), // the partial string, a bool indicating whether it came from a Constant.
|
||||
Stream(Stream),
|
||||
TcpListener(TcpListener),
|
||||
}
|
||||
|
||||
impl HeapCellValue {
|
||||
@@ -410,6 +413,9 @@ impl HeapCellValue {
|
||||
HeapCellValue::Stream(_) => {
|
||||
Addr::Stream(focus)
|
||||
}
|
||||
HeapCellValue::TcpListener(_) => {
|
||||
Addr::TcpListener(focus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,8 +443,11 @@ impl HeapCellValue {
|
||||
&HeapCellValue::PartialString(ref pstr, has_tail) => {
|
||||
HeapCellValue::PartialString(pstr.clone(), has_tail)
|
||||
}
|
||||
&HeapCellValue::Stream(_) => {
|
||||
HeapCellValue::Stream(Stream::null_stream())
|
||||
&HeapCellValue::Stream(ref stream) => {
|
||||
HeapCellValue::Stream(stream.clone())
|
||||
}
|
||||
&HeapCellValue::TcpListener(_) => {
|
||||
HeapCellValue::Atom(clause_name!("$tcp_listener"), None)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -815,6 +824,7 @@ impl ModuleStub {
|
||||
|
||||
pub(crate) type ModuleStubDir = IndexMap<ClauseName, ModuleStub>;
|
||||
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
|
||||
pub(crate) type StreamDir = BTreeSet<Stream>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexStore {
|
||||
@@ -827,6 +837,7 @@ pub struct IndexStore {
|
||||
pub(super) module_dir: ModuleDir,
|
||||
pub(super) modules: ModuleDir,
|
||||
pub(super) op_dir: OpDir,
|
||||
pub(super) streams: StreamDir,
|
||||
pub(super) stream_aliases: StreamAliasDir,
|
||||
}
|
||||
|
||||
@@ -915,6 +926,7 @@ impl IndexStore {
|
||||
op_dir: default_op_dir(),
|
||||
modules: ModuleDir::new(),
|
||||
stream_aliases: StreamAliasDir::new(),
|
||||
streams: StreamDir::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ use crate::prolog::machine::machine_indices::*;
|
||||
use crate::prolog::machine::modules::*;
|
||||
use crate::prolog::machine::stack::*;
|
||||
use crate::prolog::machine::streams::*;
|
||||
use crate::prolog::read::{PrologStream, readline};
|
||||
use crate::prolog::rug::Integer;
|
||||
|
||||
use downcast::Any;
|
||||
@@ -614,88 +613,131 @@ pub struct MachineState {
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
pub(crate)
|
||||
fn open_parsing_stream(
|
||||
&self,
|
||||
stream: Stream,
|
||||
stub_name: &'static str,
|
||||
stub_arity: usize,
|
||||
) -> Result<PrologStream, MachineStub> {
|
||||
match parsing_stream(stream) {
|
||||
Ok(stream) => {
|
||||
Ok(stream)
|
||||
}
|
||||
Err(e) => {
|
||||
let stub = MachineError::functor_stub(clause_name!(stub_name), stub_arity);
|
||||
let err = MachineError::session_error(
|
||||
self.heap.h(),
|
||||
SessionError::from(e),
|
||||
);
|
||||
|
||||
Err(self.error_form(err, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate)
|
||||
fn read_term(
|
||||
&mut self,
|
||||
current_input_stream: &mut Stream,
|
||||
mut stream: Stream,
|
||||
indices: &mut IndexStore,
|
||||
) -> CallResult {
|
||||
let mut stream = self.open_parsing_stream(
|
||||
current_input_stream.clone(),
|
||||
"read_term",
|
||||
2,
|
||||
self.check_stream_properties(
|
||||
&mut stream,
|
||||
StreamType::Text,
|
||||
Some(self[temp_v!(2)]),
|
||||
clause_name!("read_term"),
|
||||
3,
|
||||
)?;
|
||||
|
||||
match self.read(
|
||||
&mut stream,
|
||||
indices.atom_tbl.clone(),
|
||||
&indices.op_dir,
|
||||
) {
|
||||
Ok(term_write_result) => {
|
||||
let a1 = self[temp_v!(1)];
|
||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), a1);
|
||||
if stream.past_end_of_stream() {
|
||||
if EOFAction::Reset != stream.options.eof_action {
|
||||
return return_from_clause!(self.last_call, self);
|
||||
} else if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let mut orig_stream = stream.clone();
|
||||
let mut stream = self.open_parsing_stream(stream, "read_term", 3)?;
|
||||
|
||||
loop {
|
||||
match self.read(
|
||||
&mut stream,
|
||||
indices.atom_tbl.clone(),
|
||||
&indices.op_dir,
|
||||
) {
|
||||
Ok(term_write_result) => {
|
||||
let term = self[temp_v!(2)];
|
||||
self.unify(Addr::HeapCell(term_write_result.heap_loc), term);
|
||||
|
||||
if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut list_of_var_eqs = vec![];
|
||||
|
||||
for (var, binding) in term_write_result.var_dict.into_iter() {
|
||||
let var_atom = clause_name!(var.to_string(), indices.atom_tbl);
|
||||
|
||||
let h = self.heap.h();
|
||||
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
|
||||
|
||||
self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
|
||||
self.heap.push(HeapCellValue::Atom(var_atom, None));
|
||||
self.heap.push(HeapCellValue::Addr(binding));
|
||||
|
||||
list_of_var_eqs.push(Addr::Str(h));
|
||||
}
|
||||
|
||||
let mut var_set: IndexMap<Ref, bool> = IndexMap::new();
|
||||
|
||||
for addr in self.acyclic_pre_order_iter(term) {
|
||||
if let Some(var) = addr.as_var() {
|
||||
if !var_set.contains_key(&var) {
|
||||
var_set.insert(var, true);
|
||||
} else {
|
||||
var_set.insert(var, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut var_list = vec![];
|
||||
let mut singleton_var_list = vec![];
|
||||
|
||||
for addr in self.acyclic_pre_order_iter(term) {
|
||||
if let Some(var) = addr.as_var() {
|
||||
if var_set.get(&var) == Some(&true) {
|
||||
singleton_var_list.push(var.as_addr());
|
||||
}
|
||||
|
||||
var_list.push(var.as_addr());
|
||||
}
|
||||
}
|
||||
|
||||
let singleton_addr = self[temp_v!(3)];
|
||||
let singletons_offset =
|
||||
Addr::HeapCell(self.heap.to_list(singleton_var_list.into_iter()));
|
||||
|
||||
self.unify(singletons_offset, singleton_addr);
|
||||
|
||||
if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let vars_addr = self[temp_v!(4)];
|
||||
let vars_offset =
|
||||
Addr::HeapCell(self.heap.to_list(var_list.into_iter()));
|
||||
|
||||
self.unify(vars_offset, vars_addr);
|
||||
|
||||
if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let var_names_addr = self[temp_v!(5)];
|
||||
let var_names_offset =
|
||||
Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
|
||||
|
||||
return Ok(self.unify(var_names_offset, var_names_addr));
|
||||
}
|
||||
Err(err) => {
|
||||
if let ParserError::UnexpectedEOF = err {
|
||||
self.eof_action(
|
||||
self[temp_v!(2)],
|
||||
&mut orig_stream,
|
||||
clause_name!("read_term"),
|
||||
3
|
||||
)?;
|
||||
|
||||
if orig_stream.options.eof_action == EOFAction::Reset {
|
||||
if self.fail == false {
|
||||
continue;
|
||||
} else {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.fail {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut list_of_var_eqs = vec![];
|
||||
|
||||
for (var, binding) in term_write_result.var_dict.into_iter() {
|
||||
let var_atom = clause_name!(var.to_string(), indices.atom_tbl);
|
||||
|
||||
let h = self.heap.h();
|
||||
let spec = fetch_atom_op_spec(clause_name!("="), None, &indices.op_dir);
|
||||
|
||||
self.heap.push(HeapCellValue::NamedStr(2, clause_name!("="), spec));
|
||||
self.heap.push(HeapCellValue::Atom(var_atom, None));
|
||||
self.heap.push(HeapCellValue::Addr(binding));
|
||||
|
||||
list_of_var_eqs.push(Addr::Str(h));
|
||||
}
|
||||
|
||||
let a2 = self[temp_v!(2)];
|
||||
let list_offset =
|
||||
Addr::HeapCell(self.heap.to_list(list_of_var_eqs.into_iter()));
|
||||
|
||||
Ok(self.unify(list_offset, a2))
|
||||
}
|
||||
Err(err) => {
|
||||
if let ParserError::UnexpectedEOF = err {
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
// reset the input stream after an input failure.
|
||||
*current_input_stream = readline::input_stream();
|
||||
|
||||
let h = self.heap.h();
|
||||
let syntax_error = MachineError::syntax_error(h, err);
|
||||
let stub = MachineError::functor_stub(clause_name!("read_term"), 2);
|
||||
|
||||
Err(self.error_form(syntax_error, stub))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -706,10 +748,10 @@ impl MachineState {
|
||||
op_dir: &'a OpDir,
|
||||
) -> Result<Option<HCPrinter<'a, PrinterOutputter>>, MachineStub>
|
||||
{
|
||||
let ignore_ops = self.store(self.deref(self[temp_v!(2)]));
|
||||
let numbervars = self.store(self.deref(self[temp_v!(3)]));
|
||||
let quoted = self.store(self.deref(self[temp_v!(4)]));
|
||||
let max_depth = self.store(self.deref(self[temp_v!(6)]));
|
||||
let ignore_ops = self.store(self.deref(self[temp_v!(3)]));
|
||||
let numbervars = self.store(self.deref(self[temp_v!(4)]));
|
||||
let quoted = self.store(self.deref(self[temp_v!(5)]));
|
||||
let max_depth = self.store(self.deref(self[temp_v!(7)]));
|
||||
|
||||
let mut printer = HCPrinter::new(&self, op_dir, PrinterOutputter::new());
|
||||
|
||||
@@ -759,7 +801,7 @@ impl MachineState {
|
||||
|
||||
let stub = MachineError::functor_stub(clause_name!("write_term"), 2);
|
||||
|
||||
match self.try_from_list(temp_v!(5), stub) {
|
||||
match self.try_from_list(temp_v!(6), stub) {
|
||||
Ok(addrs) => {
|
||||
let mut var_names: IndexMap<Addr, String> = IndexMap::new();
|
||||
|
||||
@@ -792,9 +834,11 @@ impl MachineState {
|
||||
|
||||
var_names.insert(var, atom);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => {
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1400,9 +1400,11 @@ impl MachineState {
|
||||
let addr = self.store(self.deref(addr));
|
||||
|
||||
let offset = match addr {
|
||||
Addr::HeapCell(_) | Addr::StackCell(..) |
|
||||
Addr::AttrVar(..) | Addr::Stream(_) => {
|
||||
v
|
||||
Addr::Stream(_) | Addr::TcpListener(_) => {
|
||||
0
|
||||
}
|
||||
Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => {
|
||||
v
|
||||
}
|
||||
Addr::PStrLocation(..) => {
|
||||
if !self.flags.double_quotes.is_atom() {
|
||||
|
||||
@@ -297,7 +297,7 @@ impl Machine {
|
||||
|
||||
Ok(self.indices.insert_module(module))
|
||||
} else {
|
||||
let err = ExistenceError::SourceSink(ModuleSource::File(
|
||||
let err = ExistenceError::ModuleSource(ModuleSource::File(
|
||||
clause_name!("$toplevel"),
|
||||
));
|
||||
|
||||
@@ -315,7 +315,10 @@ impl Machine {
|
||||
|
||||
if path.is_file() {
|
||||
let file_src = match File::open(&path) {
|
||||
Ok(file_handle) => Stream::from(file_handle),
|
||||
Ok(file_handle) => Stream::from_file_as_input(
|
||||
clause_name!(".scryerrc"),
|
||||
file_handle,
|
||||
),
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
@@ -409,6 +412,15 @@ impl Machine {
|
||||
)
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(PAIRS),
|
||||
true,
|
||||
ListingSource::from_file_and_path(
|
||||
clause_name!("pairs"),
|
||||
lib_path.clone(),
|
||||
)
|
||||
);
|
||||
|
||||
compile_user_module(&mut wam,
|
||||
Stream::from(LISTS),
|
||||
true,
|
||||
@@ -451,6 +463,28 @@ impl Machine {
|
||||
|
||||
wam.compile_scryerrc();
|
||||
|
||||
wam.current_input_stream.options.alias = Some(clause_name!("user_input"));
|
||||
|
||||
wam.indices.stream_aliases.insert(
|
||||
clause_name!("user_input"),
|
||||
wam.current_input_stream.clone(),
|
||||
);
|
||||
|
||||
wam.indices.streams.insert(
|
||||
wam.current_input_stream.clone()
|
||||
);
|
||||
|
||||
wam.current_output_stream.options.alias = Some(clause_name!("user_output"));
|
||||
|
||||
wam.indices.stream_aliases.insert(
|
||||
clause_name!("user_output"),
|
||||
wam.current_output_stream.clone(),
|
||||
);
|
||||
|
||||
wam.indices.streams.insert(
|
||||
wam.current_output_stream.clone()
|
||||
);
|
||||
|
||||
wam
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user