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:
@@ -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),
|
||||||
|
|||||||
@@ -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)
|
||||||
).
|
).
|
||||||
|
|||||||
@@ -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!() }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user