PeekCode,
PointsToContinuationResetMarker,
PutByte,
- PutBytes,
PutChar,
+ PutChars,
PutCode,
REPL(REPLCodePtr),
ReadQueryTerm,
&SystemClauseType::PutByte => {
clause_name!("$put_byte")
}
- &SystemClauseType::PutBytes => {
- clause_name!("$put_bytes")
- }
&SystemClauseType::PutChar => {
clause_name!("$put_char")
}
+ &SystemClauseType::PutChars => {
+ clause_name!("$put_chars")
+ }
&SystemClauseType::PutCode => {
clause_name!("$put_code")
}
("$put_byte", 2) => {
Some(SystemClauseType::PutByte)
}
- ("$put_bytes", 2) => {
- Some(SystemClauseType::PutBytes)
- }
("$put_char", 2) => {
Some(SystemClauseType::PutChar)
}
+ ("$put_chars", 2) => {
+ Some(SystemClauseType::PutChars)
+ }
("$put_code", 2) => {
Some(SystemClauseType::PutCode)
}
Part of Scryer Prolog.
This library provides the nonterminal format_//2 to describe
- formatted strings. format/2 is provided for impure output.
+ formatted strings. format/[2,3] are provided for impure output.
Usage:
======
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
format(Fs, Args) :-
- phrase(format_(Fs, Args), Cs),
- maplist(write, Cs).
+ current_output(Stream),
+ format(Stream, Fs, Args).
format(Stream, Fs, Args) :-
phrase(format_(Fs, Args), Cs),
- ( stream_property(Stream, type(binary)) ->
- % For binary streams, we use a specialised internal predicate
- % that uses only a single "write" operation for efficiency.
- '$put_bytes'(Stream, Cs)
- ; maplist(put_char(Stream), Cs)
- ).
+ % we use a specialised internal predicate that uses only a
+ % single "write" operation for efficiency. It is equivalent to
+ % maplist(put_char(Stream), Cs). It also works for binary streams.
+ '$put_chars'(Stream, Cs).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
?- phrase(cells("hello", [], 0, []), Cs).
}
}
}
+ &SystemClauseType::PutChars => {
+ let mut stream =
+ self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_chars", 2)?;
+
+ let mut bytes = Vec::new();
+ let string = self.heap_pstr_iter(self[temp_v!(2)]).to_string();
+
+ if stream.options.stream_type == StreamType::Binary {
+ for c in string.chars() {
+ if c as u32 > 255 {
+
+ let stub = MachineError::functor_stub(clause_name!("$put_chars"), 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);
+ }
+ } else {
+ bytes = string.into_bytes();
+ }
+
+ match stream.write(&bytes) {
+ Ok(_) => {
+ return return_from_clause!(self.last_call, self);
+ }
+ _ => {
+ let stub = MachineError::functor_stub(
+ clause_name!("$put_chars"),
+ 2,
+ );
+
+ let addr = self.heap.to_unifiable(
+ HeapCellValue::Stream(stream.clone()),
+ );
+
+ return Err(self.error_form(
+ MachineError::existence_error(
+ self.heap.h(),
+ ExistenceError::Stream(addr),
+ ),
+ stub,
+ ));
+ }
+ }
+ }
&SystemClauseType::PutByte => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "put_byte", 2)?;
}
}
}
- &SystemClauseType::PutBytes => {
- let mut stream =
- self.get_stream_or_alias(self[temp_v!(1)], indices, "$put_bytes", 2)?;
-
- let mut iter = self.heap_pstr_iter(self[temp_v!(2)]);
- 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) {
- Ok(_) => {
- return return_from_clause!(self.last_call, self);
- }
- _ => {
- let stub = MachineError::functor_stub(
- clause_name!("$put_bytes"),
- 2,
- );
-
- let addr = self.heap.to_unifiable(
- HeapCellValue::Stream(stream.clone()),
- );
-
- return Err(self.error_form(
- MachineError::existence_error(
- self.heap.h(),
- ExistenceError::Stream(addr),
- ),
- stub,
- ));
- }
- }
- }
&SystemClauseType::GetByte => {
let mut stream =
self.get_stream_or_alias(self[temp_v!(1)], indices, "get_byte", 2)?;