From 1d31ca99c3d276104eb43269992caaed865b3e68 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 10 Aug 2019 19:57:00 -0700 Subject: [PATCH] Fold in parser, main loop, and support. --- .hgignore | 1 + thun/gnu-prolog/thun.pl | 75 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/.hgignore b/.hgignore index c065e98..e5e27ee 100644 --- a/.hgignore +++ b/.hgignore @@ -1,4 +1,5 @@ .*\.pyc$ +.*\.swp$ .hypothesis .pytest_cache .vscode diff --git a/thun/gnu-prolog/thun.pl b/thun/gnu-prolog/thun.pl index 3ef45af..83eef69 100644 --- a/thun/gnu-prolog/thun.pl +++ b/thun/gnu-prolog/thun.pl @@ -1,6 +1,3 @@ -:- dynamic(func/3). -:- discontiguous(func/3). - /* Copyright 2018, 2019 Simon Forman @@ -20,6 +17,12 @@ along with Thun. If not see . */ +:- dynamic(func/3). +:- discontiguous(func/3). + +:- initialization(loop). + + /* Interpreter thun(Expression, InputStack, OutputStack) @@ -35,7 +38,7 @@ thun([Combo|E], Si, So) :- combo(Combo, Si, S, E, Eo), thun(Eo, S, So). thun([Unknown|E], Si, So) :- damned_thing(Unknown), - write("wtf? "), + write(`wtf? `), write(Unknown), nl, So = [[Unknown|E]|Si]. @@ -102,6 +105,70 @@ Definitions def(x, [dup, i]). +/* +Parser +*/ + +joy_parse([T|S]) --> blanks, joy_term(T), blanks, joy_parse(S). +joy_parse([]) --> []. + +joy_term(N) --> num(N), !. +joy_term(S) --> [0'[], !, joy_parse(S), [0']]. +joy_term(A) --> chars(Chars), !, {atom_codes(A, Chars)}. + + +/* +Main Loop +*/ + +loop :- line(Line), loop(Line, [], _Out). + +loop([eof], S, S) :- !. +loop( Line, In, Out) :- + do_line(Line, In, S), + write(S), nl, + line(NextLine), !, + loop(NextLine, S, Out). + + +do_line(Line, In, Out) :- phrase(joy_parse(E), Line), thun(E, In, Out). +do_line(_Line, S, S) :- write('Err'), nl. +% Line is the next new-line delimited line from standard input stream as +% a list of character codes. + +line(Line) :- get_code(X), line(X, Line). + +line(10, []) :- !. % break on new-lines. +line(-1, [eof]) :- !. % break on EOF +line(X, [X|Line]) :- get_code(Y), !, line(Y, Line). + + +chars([Ch|Rest]) --> char(Ch), chars(Rest). +chars([Ch]) --> char(Ch). + +char(Ch) --> [Ch], { Ch \== 0'[, Ch \== 0'], Ch >= 33, Ch =< 126 }. + + +blanks --> blank, !, blanks. +blanks --> []. + +blank --> [32]. + + +% TODO: negative numbers, floats, scientific notation. + +num(N) --> digits(Codes), !, { num(N, Codes) }. + +num(_, []) :- fail, !. +num(N, [C|Codes]) :- number_codes(N, [C|Codes]). + + +digits([H|T]) --> digit(H), !, digits(T). +digits([]) --> []. + +digit(C) --> [C], { nonvar(C), C =< 57, C >= 48 }. + +