Merge branch 'sockets-develop'

This commit is contained in:
Mark Thom
2020-05-09 14:26:29 -06:00
25 changed files with 3291 additions and 446 deletions

View File

@@ -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
));

View File

@@ -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;

View File

@@ -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 => {

View File

@@ -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),
}

View File

@@ -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(),
}
}

View File

@@ -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!(),
_ => {
}
}
}

View File

@@ -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() {

View File

@@ -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