Reputation: 1702
I'm trying to read and convert string to ASCII value using the Prolog predicate read_command/1
.
The following code works. Could someone please explain how to understand this code below?
read_command(L) :- % read_command/1 get0(C), read_command(_, L, C). read_command(_, [], X) :- % auxiliary predicate read_command/3 member(X, `.\n\t`), !. read_command(X, [C|L], C) :- get0(C1), read_command(X, L, C1).
Upvotes: 4
Views: 882
Reputation: 18726
TL;DR: Don't use get0/1
!
get0/1
is considered deprecated—even by Prolog processors that implement it (like SWI).
Instead, use get_char/1
and represent strings as lists of characters—not as lists of codes!
read_command(Chars) :- get_char(Next), read_command_aux(Chars, Next). read_command_aux(Chars, Char) :- member(Char, ['.', '\t', '\n', end_of_file]), !, Chars = []. read_command_aux([Char|Chars], Char) :- get_char(Next), read_command_aux(Chars, Next).
Here are some sample queries using SWI-Prolog 7.3.15:
?- read_command(Chars). |: abc Chars = [a, b, c]. ?- read_command(Chars). |: abc. Chars = [a, b, c]. ?- read_command(Chars). |: 123abc Chars = ['1', '2', '3', a, b, c].
For further use of commands you might want to utilize atoms, like so:
?- read_command(Chars), atom_chars(Command, Chars). |: abcd. Chars = [a, b, c, d], Command = abcd.
Note that this does not only work with SWI, but also with SICStus Prolog 4.3.2 (and others).
Upvotes: 2
Reputation: 60034
read_command/1 reads the first char available from current input stream, and uses it as lookahead.
read_command/3 just stop when the lookahead is either a whitespace or a dot. Otherwise, put the lookahead in list, get a new lookahead from stream, and recurse.
I think the first clause of read_command/3 should also handle the case when X is -1, means end of file (for instance, after hitting Ctrl+D)
Upvotes: 3