diff --git a/.hgignore b/.hgignore index 194a39e..7998c55 100644 --- a/.hgignore +++ b/.hgignore @@ -5,4 +5,4 @@ .vscode docs/.ipynb_checkpoints test/* -thun +gnu-prolog/thun diff --git a/thun/gnu-prolog/DCG_basics.pl b/thun/gnu-prolog/DCG_basics.pl new file mode 100644 index 0000000..b44fd1b --- /dev/null +++ b/thun/gnu-prolog/DCG_basics.pl @@ -0,0 +1,59 @@ +/* + Copyright 2019 Simon Forman + + This file is part of Thun + + Thun is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Thun is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Thun. If not see . + + +DCG basics. For some of this I cribbed the source from SWI library code +and adapted it for GNU Prolog Compiler. + +N.B. is_glyph//1 excludes '[' and ']' characters. D'oh! FIXME + +*/ + + +:- set_prolog_flag(double_quotes, codes). + + +% TODO: scientific notation. + +signed_float_or_integer(Codes) --> signed_digits(J), ".", !, digits(I), + { append(J, [0'.|I], Codes) }. +signed_float_or_integer(Codes) --> signed_digits(Codes). + +signed_digits([0'-|Codes]) --> "-", !, digits(Codes). +signed_digits( Codes ) --> digits(Codes). + +% Groups of characters. + +chars(Chars) --> one_or_more(char, Chars). +blanks --> blank, !, blanks | []. +digits(Digits) --> one_or_more(digit, Digits). + +% Character types. + +char(Ch) --> [Ch], { nonvar(Ch), is_glyph(Ch) }. +blank --> [Ch], { nonvar(Ch), is_space(Ch) }. +digit(Ch) --> [Ch], { nonvar(Ch), between(0'0, 0'9, Ch) }. + +is_glyph(Ch) :- Ch =\= 0'[, Ch =\= 0'], between(0'!, 0'~, Ch). +is_space(Ch) :- Ch =:= 32 ; between(9, 13, Ch). + +one_or_more(E, List) --> one_or_more_(List, E). + +one_or_more_([Ch|Rest], P) --> call(P, Ch), one_or_more_(Rest, P). +one_or_more_([Ch], P) --> call(P, Ch). + diff --git a/thun/gnu-prolog/Makefile b/thun/gnu-prolog/Makefile index 3c702ce..781b1b2 100644 --- a/thun/gnu-prolog/Makefile +++ b/thun/gnu-prolog/Makefile @@ -2,14 +2,15 @@ GPLC_OPTIONS=--no-top-level #GPLC_OPTIONS= -thun: thun.pl parser.pl defs.pl main.pl math.pl Makefile - gplc $(GPLC_OPTIONS) -o thun thun.pl parser.pl defs.pl main.pl math.pl +thun: thun.pl parser.pl defs.pl main.pl math.pl DCG_basics.pl Makefile + gplc $(GPLC_OPTIONS) -o thun thun.pl parser.pl defs.pl main.pl DCG_basics.pl math.pl -defs.pl: meta-defs.pl parser.pl defs.txt thun.pl +defs.pl: meta-defs.pl parser.pl defs.txt thun.pl DCG_basics.pl gprolog \ --consult-file meta-defs.pl \ --consult-file parser.pl \ --consult-file thun.pl \ + --consult-file DCG_basics.pl \ --query-goal do math.pl: meta-math.pl diff --git a/thun/gnu-prolog/parser.pl b/thun/gnu-prolog/parser.pl index ecf73da..c60d328 100644 --- a/thun/gnu-prolog/parser.pl +++ b/thun/gnu-prolog/parser.pl @@ -37,38 +37,10 @@ symbol(C) --> chars(Chars), !, { Chars \= "==", atom_codes(C, Chars) }. num(N) --> number_digits(Codes), { number_codes(N, Codes) }. number_digits(Codes) --> signed_float_or_integer(Codes), !, end_num. -% TODO: floats, scientific notation. - -signed_float_or_integer(Codes) --> signed_digits(J), ".", !, digits(I), - { append(J, [0'.|I], Codes) }. -signed_float_or_integer(Codes) --> signed_digits(Codes). - -signed_digits([45|Codes]) --> "-", !, digits(Codes). -signed_digits( Codes ) --> digits(Codes). end_num, [Ch] --> [Ch], { [Ch] = "[" ; is_space(Ch) }. end_num([], []). -% Groups of characters. - -chars(Chars) --> one_or_more(char, Chars). -blanks --> blank, !, blanks | []. -digits(Digits) --> one_or_more(digit, Digits). - -% Character types. - -char(Ch) --> [Ch], { nonvar(Ch), is_glyph(Ch) }. -blank --> [Ch], { nonvar(Ch), is_space(Ch) }. -digit(Ch) --> [Ch], { nonvar(Ch), between(0'0, 0'9, Ch) }. - -is_glyph(Ch) :- Ch =\= 0'[, Ch =\= 0'], between(0'!, 0'~, Ch). -is_space(Ch) :- Ch =:= 32 ; between(9, 13, Ch). - -one_or_more(E, List) --> one_or_more_(List, E). - -one_or_more_([Ch|Rest], P) --> call(P, Ch), one_or_more_(Rest, P). -one_or_more_([Ch], P) --> call(P, Ch). - /*