Krishna Kalyan
Krishna Kalyan

Reputation: 1702

Converting input stream to ASCII: explanation of Prolog code

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

Answers (2)

repeat
repeat

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

CapelliC
CapelliC

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

Related Questions