ADDED: phrase_from_file/3 in library(pio)

This allows us to specify type(binary), and read from binary files
with DCGs.
This commit is contained in:
Markus Triska
2020-05-19 18:44:28 +02:00
parent 1c0c660c32
commit 0bd9831eec
3 changed files with 56 additions and 23 deletions

View File

@@ -533,7 +533,7 @@ impl SystemClauseType {
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal), ("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar), ("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset), ("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
("$file_to_chars", 2) => Some(SystemClauseType::FileToChars), ("$file_to_chars", 3) => Some(SystemClauseType::FileToChars),
("$get_byte", 2) => Some(SystemClauseType::GetByte), ("$get_byte", 2) => Some(SystemClauseType::GetByte),
("$get_char", 2) => Some(SystemClauseType::GetChar), ("$get_char", 2) => Some(SystemClauseType::GetChar),
("$get_code", 2) => Some(SystemClauseType::GetCode), ("$get_code", 2) => Some(SystemClauseType::GetCode),

View File

@@ -1,12 +1,23 @@
:- module(pio, [phrase_from_file/2]). :- module(pio, [phrase_from_file/2,
phrase_from_file/3]).
:- use_module(library(dcgs)). :- use_module(library(dcgs)).
:- use_module(library(error)). :- use_module(library(error)).
phrase_from_file(NT, File) :- phrase_from_file(NT, File) :-
( var(File) -> instantiation_error(phrase_from_file/2) phrase_from_file(NT, File, []).
phrase_from_file(NT, File, Options) :-
( var(File) -> instantiation_error(phrase_from_file/3)
; (\+ atom(File) ; File = []) -> ; (\+ atom(File) ; File = []) ->
domain_error(source_sink, File, phrase_from_file/2) domain_error(source_sink, File, phrase_from_file/3)
; '$file_to_chars'(File, Chars), ; must_be(list, Options),
( member(Var, Options), var(Var) -> instantiation_error(phrase_from_file/3)
; member(type(Type), Options) ->
must_be(atom, Type),
member(Type, [text,binary])
; Type = text
),
'$file_to_chars'(File, Chars, Type),
phrase(NT, Chars) phrase(NT, Chars)
). ).

View File

@@ -1905,15 +1905,36 @@ impl MachineState {
} }
}; };
let type_str = match self.store(self.deref(self[temp_v!(3)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str()
} else {
unreachable!()
}
}
_ => {
unreachable!()
}
};
let complete_string = { let complete_string = {
let mut buffer = String::new(); let mut buffer = String::new();
match file.read_to_string(&mut buffer) { match type_str {
"text" => { match file.read_to_string(&mut buffer) {
Ok(_size) => { Ok(_size) => {
self.heap.put_complete_string(&buffer) self.heap.put_complete_string(&buffer)
} }
Err(_e) => { Err(_e) => {
// This case if the data isn't UTF-8 valid. // the data isn't valid UTF-8, so we fail.
let mut buffer = Vec::new(); self.fail = true;
return Ok(());
}
}
}
"binary" => { let mut buffer = Vec::new();
let _ = match file.read_to_end(&mut buffer) { let _ = match file.read_to_end(&mut buffer) {
Ok(size) => size, Ok(size) => size,
Err(_e) => unreachable!() Err(_e) => unreachable!()
@@ -1925,6 +1946,7 @@ impl MachineState {
self.heap.put_complete_string(&buffer) self.heap.put_complete_string(&buffer)
} }
_ => { unreachable!() }
} }
}; };