Merge branch 'master' of https://github.com/mthom/rusty-wam
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
:- module(charsio, [char_type/2,
|
:- module(charsio, [char_type/2,
|
||||||
chars_utf8bytes/2,
|
chars_utf8bytes/2,
|
||||||
get_single_char/1,
|
get_single_char/1,
|
||||||
|
read_line_to_chars/3,
|
||||||
read_term_from_chars/2,
|
read_term_from_chars/2,
|
||||||
write_term_to_chars/3]).
|
write_term_to_chars/3]).
|
||||||
|
|
||||||
@@ -182,3 +183,14 @@ continuation(Code, Chars, Nb) --> [Byte],
|
|||||||
% invalid continuation byte
|
% invalid continuation byte
|
||||||
% each remaining continuation byte (if any) will raise 0xFFFD too
|
% each remaining continuation byte (if any) will raise 0xFFFD too
|
||||||
continuation(_, ['\xFFFD\'|T], _) --> [_], decode_utf8(T).
|
continuation(_, ['\xFFFD\'|T], _) --> [_], decode_utf8(T).
|
||||||
|
|
||||||
|
|
||||||
|
read_line_to_chars(Stream, Cs0, Cs) :-
|
||||||
|
'$get_n_chars'(Stream, 1, Char), % this also works for binary streams
|
||||||
|
( Char == [] -> Cs0 = Cs
|
||||||
|
; Char = [C],
|
||||||
|
Cs0 = [C|Rest],
|
||||||
|
( C == '\n' -> Rest = Cs
|
||||||
|
; read_line_to_chars(Stream, Rest, Cs)
|
||||||
|
)
|
||||||
|
).
|
||||||
|
|||||||
@@ -375,20 +375,9 @@ format(Fs, Args) :-
|
|||||||
format(Stream, Fs, Args) :-
|
format(Stream, Fs, Args) :-
|
||||||
phrase(format_(Fs, Args), Cs),
|
phrase(format_(Fs, Args), Cs),
|
||||||
( stream_property(Stream, type(binary)) ->
|
( stream_property(Stream, type(binary)) ->
|
||||||
% maplist(char_code, Cs, Bytes) is currently a lot slower
|
|
||||||
% than first converting Cs to an atom, and then to codes.
|
|
||||||
% In the future, we can ideally avoid creating an atom here,
|
|
||||||
% since an atom leaves traces in the system.
|
|
||||||
atom_chars(A, Cs),
|
|
||||||
atom_codes(A, Bytes),
|
|
||||||
( member(NonByte, Bytes), NonByte > 255 ->
|
|
||||||
char_code(Char, NonByte),
|
|
||||||
throw(error(representation_error(Char), format/3))
|
|
||||||
; true
|
|
||||||
),
|
|
||||||
% For binary streams, we use a specialised internal predicate
|
% For binary streams, we use a specialised internal predicate
|
||||||
% that uses only a single "write" operation for efficiency.
|
% that uses only a single "write" operation for efficiency.
|
||||||
'$put_bytes'(Stream, Bytes)
|
'$put_bytes'(Stream, Cs)
|
||||||
; maplist(put_char(Stream), Cs)
|
; maplist(put_char(Stream), Cs)
|
||||||
).
|
).
|
||||||
|
|
||||||
@@ -471,7 +460,7 @@ portray_clause(Term) :-
|
|||||||
|
|
||||||
portray_clause(Stream, Term) :-
|
portray_clause(Stream, Term) :-
|
||||||
phrase(portray_clause_(Term), Ls),
|
phrase(portray_clause_(Term), Ls),
|
||||||
maplist(put_char(Stream), Ls).
|
format(Stream, "~s", [Ls]).
|
||||||
|
|
||||||
portray_clause_(Term) -->
|
portray_clause_(Term) -->
|
||||||
{ term_variables(Term, Vs),
|
{ term_variables(Term, Vs),
|
||||||
|
|||||||
@@ -2022,8 +2022,24 @@ impl MachineState {
|
|||||||
let mut stream =
|
let mut stream =
|
||||||
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
|
self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
|
||||||
|
|
||||||
let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2);
|
let mut iter = self.heap_pstr_iter(self[temp_v!(2)]);
|
||||||
let bytes = self.integers_to_bytevec(temp_v!(2), stub);
|
let mut bytes = Vec::new();
|
||||||
|
for c in iter.to_string().chars() {
|
||||||
|
if c as u32 > 255 {
|
||||||
|
|
||||||
|
let stub = MachineError::functor_stub(clause_name!("$put_bytes"), 2);
|
||||||
|
|
||||||
|
let err = MachineError::type_error(
|
||||||
|
self.heap.h(),
|
||||||
|
ValidType::Byte,
|
||||||
|
Addr::Char(c),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Err(self.error_form(err, stub));
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.push(c as u8);
|
||||||
|
}
|
||||||
|
|
||||||
match stream.write(&bytes) {
|
match stream.write(&bytes) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user