-
Notifications
You must be signed in to change notification settings - Fork 150
Add chars_stream/1
and chars_to_stream/{2,3}
#2968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Thank you a lot for working on this! What is the source/target of the resulting stream? Would it be more useful to make it so that the source/target is a string? |
Oh interesting. What did you have in mind? |
Yes exactly, Alternatively, maybe |
Interesting. Would the 2 arrity be string and stream or stream and opts? |
Tests are extremely flakey, I assume it has something to do with the hack I used to implement the memory stream. $ scryer-prolog -f --no-add-history src/tests/charsio.pl -f -g "use_module(library(charsio_tests)), charsio_tests:main(charsio_tests)"
Running test "can create string char stream"
Running test "can spell simple word with char stream"
thread 'main' panicked at src/arena.rs:210:5:
value contains invalid bit pattern for field ArenaHeader.tag: InvalidBitPattern { invalid_bytes: 0 }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ scryer-prolog -f --no-add-history src/tests/charsio.pl -f -g "use_module(library(charsio_tests)), charsio_tests:main(charsio_tests)"
Running test "can create string char stream"
Running test "can spell simple word with char stream"
Running test "can read from and write to char stream"
Running test "can convert string to char stream"
Running test "can convert string to char stream with options" Edit: tests fine now after better implementation |
chars_to_stream/{1,2,3}
char_stream/1
and chars_to_stream/{2,3}
src/lib/charsio.pl
Outdated
@@ -393,3 +397,52 @@ | |||
; '$chars_base64'(Cs, Bs, Padding, Charset) | |||
) | |||
). | |||
|
|||
%% put_chars(+Stream, +Chars). % |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this we have format/3
from library format
.
For instance, even |
inline put_chars/2 mthom#2968 (comment) char_stream/1 -> chars_stream/1 mthom#2968 (comment)
Interesting, do you suppose This line of code is very mysterious to me but I will investigate. let stream = Stream::from_owned_string("".to_string(), &mut self.machine_st.arena); |
Does anyone know that the |
src/lib/charsio.pl
Outdated
@@ -445,4 +426,4 @@ | |||
chars_to_stream(Chars, Stream, _) :- | |||
must_be(chars, Chars), | |||
'$memory_stream'(Stream), | |||
put_chars(Stream, Chars). | |||
maplist(put_char(Stream), Chars). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
format/3
should make this much faster, since it writes more at once.
Oh, perhaps it already is in binary? #[inline]
pub fn from_owned_string(string: String, arena: &mut Arena) -> Stream {
Stream::Byte(arena_alloc!(
StreamLayout::new(CharReader::new(ByteStream(Cursor::new(
string.into_bytes()
)))),
arena
))
} |
The options must be useable to specify the type (text or binary) of the resulting stream. In this way, we can access the encoded bytes directly, and also get Unicode characters from the stream when needed. Reading a term from characters could be bootstrapped from this. |
In the original design, what was supposed to be the source of the memory stream, i.e., where did the characters come from? (The original predicate only had a single argument, the stream.) |
Sounds good, I will investigate in the morning |
Semantically I just assumed it would be an empty stream for writing into. |
char_stream/1
and chars_to_stream/{2,3}
chars_stream/1
and chars_to_stream/{2,3}
Does anyone have any examples of byte semantics so I can write a spec to work against? i.e., what would it look like to write a byte to (or read from) a stream vs text? |
Bytes would allow having |
You can use |
I settled on this as an acceptable spec: test("can read bytes",
(
chars_to_stream("abc", Stream, [type(binary)]),
get_byte(Stream, A),
get_byte(Stream, B),
get_byte(Stream, C),
A=97,
B=98,
C=99
)). In studying how |
The options appear to be parsed in Prolog code at https://github.com/mthom/scryer-prolog/blob/rebis-dev/src%2Flib%2Fbuiltins.pl#L1964 |
amazing... I thought |
Ok I ripped off the parser from Is it ok that this means that the "chars" could also be bytes, depending on the options? test("can read/write bytes",
(
A=97,
B=98,
C=99,
chars_to_stream([A,B,C], Stream, [type(binary)]),
get_byte(Stream, A),
get_byte(Stream, B),
get_byte(Stream, C),
put_byte(Stream, A),
put_byte(Stream, B),
put_byte(Stream, C),
get_byte(Stream, A),
get_byte(Stream, B),
get_byte(Stream, C)
)). or should we come up with different semantics? Because I'm not sure it's always "chars" now. Also, if anyone has any better suggestions for the implementation of parsing the options, I'd certainly be open to that feedback. |
src/lib/charsio.pl
Outdated
@@ -423,7 +423,85 @@ | |||
% Stream = stream('$memory_stream'(2048)). | |||
% ``` | |||
|
|||
chars_to_stream(Chars, Stream, _) :- | |||
must_be(chars, Chars), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why delete this? The interface should be checked prior to any side-effects.
Ok I cleaned up the parsing code and the validation logic. The last two commits are a little outside my comfort/confidence zone in terms of approach and style, so if anyone has any suggestions I'd certainly be interested. I'll take at least one more refactoring pass to clean up white space issues and layout. Especially the error messages, I just totally made those up. |
%% chars_to_stream(+Chars, -Stream, +Options) :- | ||
% Creates a character stream from a list of characters. | ||
% | ||
% Chars is the list of characters to write to the stream. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chars is the list of characters that the stream will yield, no?
Intended usage:
Currently, I have implemented this in the dumbest possible way.Suggestions appreciated.