Small patch for library pio

This commit is contained in:
notoria
2020-04-26 14:54:20 +02:00
parent ae2402f4a7
commit 9b1272da51
2 changed files with 52 additions and 32 deletions

View File

@@ -3,5 +3,9 @@
:- use_module(library(dcgs)).
phrase_from_file(NT, File) :-
'$file_to_chars'(File, Chars),
phrase(NT, Chars).
( var(File) -> throw(error(instantiation_error, phrase_from_file/2))
; (\+ atom(File) ; File = []) ->
throw(error(domain_error(source_sink, File), phrase_from_file/2))
; '$file_to_chars'(File, Chars),
phrase(NT, Chars)
).

View File

@@ -1522,6 +1522,8 @@ impl MachineState {
};
}
&SystemClauseType::FileToChars => {
// TODO: Replace this with stream.
use std::io;
let a1 = self.store(self.deref(self[temp_v!(1)]));
let a2 = self.store(self.deref(self[temp_v!(2)]));
@@ -1542,50 +1544,64 @@ impl MachineState {
let name = clause_name!("$file_to_chars");
let mut file = match File::open(&file_name) {
Ok(f) => f,
Err(_e) => {
Err(e) => {
let file_name_ = clause_name!(file_name.clone(),
indices.atom_tbl.clone());
let arity = 2;
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h();
let err = MachineError::existence_error(
let err = match e.kind() {
io::ErrorKind::NotFound => {
MachineError::existence_error(
h,
ExistenceError::SourceSink(
ModuleSource::File(file_name_)
),
)
}
io::ErrorKind::PermissionDenied => {
let stub = MachineError::functor_stub(
name.clone(),
arity
);
let source_sink = self.store(self.deref(a1));
MachineError::permission_error(
h,
Permission::Access,
"source_sink",
source_sink
)
}
_ => unreachable!() // Not nice.
};
let err = self.error_form(err, stub);
self.throw_exception(err);
return Ok(());
}
};
let char_list = {
let mut buffer = String::new();
let _ = match file.read_to_string(&mut buffer) {
Ok(size) => size,
match file.read_to_string(&mut buffer) {
Ok(_size) => {
let chars = buffer.chars().map(|c| Addr::Char(c));
Addr::HeapCell(self.heap.to_list(chars))
}
Err(_e) => {
// TODO: Distinguish the case/error.
let file_name_ = clause_name!(file_name.clone(),
indices.atom_tbl.clone());
let arity = 2;
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h();
let err = MachineError::existence_error(
h,
ExistenceError::SourceSink(
ModuleSource::File(file_name_)
),
);
let err = self.error_form(err, stub);
self.throw_exception(err);
return Ok(());
// This case if the data isn't UTF-8 valid.
let mut buffer = Vec::new();
let _ = match file.read_to_end(&mut buffer) {
Ok(size) => size,
Err(_e) => unreachable!()
};
let chars = buffer
.into_iter()
.map(|b| Addr::Char(b as char));
Addr::HeapCell(self.heap.to_list(chars))
}
}
};
let chars = buffer.chars().map(|c| Addr::Char(c));
let char_list = Addr::HeapCell(self.heap.to_list(chars));
self.unify(char_list, a2);
}