summaryrefslogtreecommitdiff
path: root/src/parser.prolog
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.prolog')
-rw-r--r--src/parser.prolog77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/parser.prolog b/src/parser.prolog
new file mode 100644
index 0000000..c9f9771
--- /dev/null
+++ b/src/parser.prolog
@@ -0,0 +1,77 @@
+
+:- module(parser, [prompt/1, readList/1, readLine/1, split/2, join/2, intercalate/3]).
+
+
+% functions for dealing with lines of text
+% eg obtaining one, parsing it into a list of words, and rejoining it
+
+% prompt provides the user with a '>' prompt
+% readList merely obtains and parses the input
+% readLine obtains a raw line of input
+% split parses a line of text into words
+% join takes a list of words and joins them into one string
+
+
+prompt(L) :-
+ write('> '),
+ readList(L).
+
+
+readList(L) :-
+ readLine(X),
+ split(X,L).
+
+
+readLine(L) :-
+ get_char(C),
+ readLine_tail(C,L).
+
+
+readLine_tail('\n',[]) :- !.
+readLine_tail(C,[C|X]) :-
+ get_char(C2),
+ readLine_tail(C2,X).
+
+
+split(X,R) :-
+ wordList(R,X,[]), !.
+
+
+join([X|Y],R) :-
+ join(Y,Rx),
+ atom_concat(X,Rx,R).
+join([X],R) :-
+ R = X.
+
+
+intercalate([X|Y], Spacer, Result) :-
+ intercalate(Y, Spacer, Tail),
+ atom_concat(X, Spacer, Head),
+ atom_concat(Head, Tail, Result).
+intercalate([X], _, Result) :- Result = X.
+
+
+wordList(X) --> whitespace, wordList(X).
+wordList([X]) --> word(X).
+wordList([X]) --> word(X), whitespace.
+wordList([X|Y]) --> word(X), whitespace, wordList(Y).
+
+
+word(W) --> charList(X), {atom_chars(W,X)}.
+
+
+charList([X|Xs]) --> char(X), charList(Xs).
+charList([X]) --> char(X).
+
+
+whitespace --> whsp, whitespace.
+whitespace --> whsp.
+
+
+whsp --> oneOf(_,[' ', '\r', '\n', '\t']).
+char(X) --> noneOf(X,[' ', '\r', '\n', '\t']).
+
+
+oneOf(X,L) --> [X], {member(X,L)}.
+noneOf(X,L) --> [X], {not(member(X,L))}.
+