Remove '==' from definitions. (Bools)

I decided that the conceptual simplicity of omitting '==' is more useful
than the cosmetic value of keeping it.  The defs.txt file is now just one
definition per line with the first symbol giving the name.

Also, bools are literals.
This commit is contained in:
Simon Forman 2020-01-26 09:48:30 -08:00
parent ed41395560
commit e0a36eab8b
2 changed files with 99 additions and 103 deletions

View File

@ -1,73 +1,73 @@
-- == 1 - -- 1 -
? == dup bool ? dup bool
++ == 1 + ++ 1 +
anamorphism == [pop []] swap [dip swons] genrec anamorphism [pop []] swap [dip swons] genrec
app1 == grba infrst app1 grba infrst
app2 == [grba swap grba swap] dip [infrst] cons ii app2 [grba swap grba swap] dip [infrst] cons ii
app3 == 3 appN app3 3 appN
appN == [grabN] cons dip map disenstacken appN [grabN] cons dip map disenstacken
at == drop first at drop first
average == [sum 1.0 *] [size] cleave / average [sum 1.0 *] [size] cleave /
b == [i] dip i b [i] dip i
binary == unary popd binary unary popd
ccons == cons cons ccons cons cons
cleave == fork popdd cleave fork popdd
clop == cleave popdd clop cleave popdd
codireco == cons dip rest cons codireco cons dip rest cons
dinfrirst == dip infrst dinfrirst dip infrst
disenstacken == ? [uncons ?] loop pop disenstacken ? [uncons ?] loop pop
down_to_zero == [0 >] [dup --] while down_to_zero [0 >] [dup --] while
drop == [rest] times drop [rest] times
dupd == [dup] dip dupd [dup] dip
dupdd == [dup] dipd dupdd [dup] dipd
dupdipd == dup dipd dupdipd dup dipd
enstacken == stack [clear] dip enstacken stack [clear] dip
flatten == [] swap [concat] step flatten [] swap [concat] step
fork == [i] app2 fork [i] app2
fourth == rest third fourth rest third
gcd == true [tuck mod dup 0 >] loop pop gcd true [tuck mod dup 0 >] loop pop
grabN == [] swap [cons] times grabN [] swap [cons] times
grba == [stack popd] dip grba [stack popd] dip
hypot == [sqr] ii + sqrt hypot [sqr] ii + sqrt
ifte == [nullary] dipd swap branch ifte [nullary] dipd swap branch
ii == [dip] dupdip i ii [dip] dupdip i
infra == swons swaack [i] dip swaack infra swons swaack [i] dip swaack
infrst == infra first infrst infra first
make_generator == [codireco] ccons make_generator [codireco] ccons
neg == 0 swap - neg 0 swap -
not == [true] [false] branch not [true] [false] branch
nullary == [stack] dinfrirst nullary [stack] dinfrirst
of == swap at of swap at
pam == [i] map pam [i] map
pm == [+] [-] clop pm [+] [-] clop
popd == [pop] dip popd [pop] dip
popdd == [pop] dipd popdd [pop] dipd
popop == pop pop popop pop pop
popopd == [popop] dip popopd [popop] dip
popopdd == [popop] dipd popopdd [popop] dipd
primrec == [i] genrec primrec [i] genrec
product == 1 swap [*] step product 1 swap [*] step
quoted == [unit] dip quoted [unit] dip
range == [0 <=] [1 - dup] anamorphism range [0 <=] [1 - dup] anamorphism
range_to_zero == unit [down_to_zero] infra range_to_zero unit [down_to_zero] infra
reverse == [] swap shunt reverse [] swap shunt
rrest == rest rest rrest rest rest
run == [] swap infra run [] swap infra
second == rest first second rest first
shift == uncons [swons] dip shift uncons [swons] dip
shunt == [swons] step shunt [swons] step
size == 0 swap [pop ++] step size 0 swap [pop ++] step
split_at == [drop] [take] clop split_at [drop] [take] clop
sqr == dup * sqr dup *
step_zero == 0 roll> step step_zero 0 roll> step
sum == 0 swap [+] step sum 0 swap [+] step
swons == swap cons swons swap cons
take == [] rolldown [shift] times pop take [] rolldown [shift] times pop
ternary == binary popd ternary binary popd
third == rest second third rest second
unary == nullary popd unary nullary popd
unit == [] cons unit [] cons
unquoted == [i] dip unquoted [i] dip
unswons == uncons swap unswons uncons swap
while == swap [nullary] cons dup dipd concat loop while swap [nullary] cons dup dipd concat loop
x == dup i x dup i

View File

@ -35,14 +35,15 @@ joy(InputString, StackIn, StackOut) :-
Parser Parser
The grammar of Joy is very simple. A Joy expression is zero or more Joy The grammar of Joy is very simple. A Joy expression is zero or more Joy
terms separated by blanks and terms can be either integers, quoted Joy terms separated by blanks and terms can be either integers, Booleans,
expressions, or symbols (names of functions.) quoted Joy expressions, or symbols (names of functions.)
joy ::= ( blanks term blanks )* joy ::= ( blanks term blanks )*
term ::= integer | '[' joy ']' | symbol term ::= integer | bool | '[' joy ']' | symbol
integer ::= [ '-' | '+' ] ('0'...'9')+ integer ::= [ '-' | '+' ] ('0'...'9')+
bool ::= 'true' | 'false'
symbol ::= char+ symbol ::= char+
char ::= <Any non-space other than '[' and ']'.> char ::= <Any non-space other than '[' and ']'.>
@ -54,15 +55,8 @@ blank//0 matches and discards space and newline characters and integer//1
into an integer." (https://www.swi-prolog.org/pldoc/man?section=basics) into an integer." (https://www.swi-prolog.org/pldoc/man?section=basics)
Symbols can be made of any non-blank characters except '['and ']' which Symbols can be made of any non-blank characters except '['and ']' which
are fully reserved for list literals ("quotes"), and '==' is reserved as are fully reserved for list literals (aka "quotes"). 'true' and 'false'
a kind of meta-logical punctuation for definitions (it's not a symbol, would be valid symbols but they are reserved for Boolean literals.
you can't use it in code, it only appears in the defs.txt file as a
visual aid to humans. The rule of one definition per line with the
name as the first symbol in the definition would suffice, but I tried it
and it looked ugly to me. Any number of '=' characters can appear as
part of a symbol, and any number of them other than two can be a symbol.)
Symbols 'true' and 'false' are treated as literals for Boolean values.
For now strings are neglected in favor of lists of numbers. (But there's For now strings are neglected in favor of lists of numbers. (But there's
no support for parsing string notation and converting to lists of ints.) no support for parsing string notation and converting to lists of ints.)
@ -73,8 +67,8 @@ square bracket but a little weird when it's a symbol term. E.g. "2[3]"
parses as [2, [3]] but "23x" parses as [23, x]. It's a minor thing not parses as [2, [3]] but "23x" parses as [23, x]. It's a minor thing not
worth disfiguring the grammar to change IMO. worth disfiguring the grammar to change IMO.
Integers are converted to Prolog integers, symbols to Prolog atoms, and Integers are converted to Prolog integers, symbols and bools to Prolog
list literals to Prolog lists. atoms, and list literals to Prolog lists.
*/ */
@ -87,7 +81,6 @@ joy_term(bool(true)) --> "true", !.
joy_term(bool(false)) --> "false", !. joy_term(bool(false)) --> "false", !.
joy_term(symbol(S)) --> symbol(S). joy_term(symbol(S)) --> symbol(S).
symbol(_) --> "==", !, {fail}. % prevents '==' parsing as [= =].
symbol(C) --> chars(Chars), !, {atom_string(C, Chars)}. symbol(C) --> chars(Chars), !, {atom_string(C, Chars)}.
chars([Ch|Rest]) --> char(Ch), chars(Rest). chars([Ch|Rest]) --> char(Ch), chars(Rest).
@ -105,6 +98,7 @@ thun([], S, S).
thun([Term|E], Si, So) :- thun(Term, E, Si, So). thun([Term|E], Si, So) :- thun(Term, E, Si, So).
thun( int(I), E, Si, So) :- thun(E, [ int(I)|Si], So). thun( int(I), E, Si, So) :- thun(E, [ int(I)|Si], So).
thun(bool(B), E, Si, So) :- thun(E, [bool(B)|Si], So).
thun(list(L), E, Si, So) :- thun(E, [list(L)|Si], So). thun(list(L), E, Si, So) :- thun(E, [list(L)|Si], So).
thun(symbol(Def), E, Si, So) :- def(Def, Body), !, append(Body, E, Eo), thun(Eo, Si, So). thun(symbol(Def), E, Si, So) :- def(Def, Body), !, append(Body, E, Eo), thun(Eo, Si, So).
thun(symbol(Func), E, Si, So) :- func(Func, Si, S), thun(E, S, So). thun(symbol(Func), E, Si, So) :- func(Func, Si, S), thun(E, S, So).
@ -264,28 +258,30 @@ prepare_mapping( P, S, [T|In], Acc, Out) :-
Definitions Definitions
*/ */
joy_def(def(Def, Body)) --> symbol(Def), blanks, "==", joy_parse(Body). joy_def --> joy_parse([symbol(Name)|Body]), { assert_def(Name, Body) }.
joy_defs([Def|Rest]) --> blanks, joy_def(Def), blanks, joy_defs(Rest).
joy_defs([]) --> [].
assert_defs(DefsFile) :- assert_defs(DefsFile) :-
read_file_to_codes(DefsFile, Codes, []), read_file_to_codes(DefsFile, Codes, []),
phrase(joy_defs(Defs), Codes), lines(Codes, Lines),
maplist(assert_def, Defs). maplist(phrase(joy_def), Lines).
assert_def(def(Def, Body)) :- assert_def(Symbol, Body) :-
( % Don't let Def "shadow" functions or combinators. ( % Don't let this "shadow" functions or combinators.
\+ func(Def, _, _), \+ func(Symbol, _, _),
\+ combo(Def, _, _, _, _) \+ combo(Symbol, _, _, _, _)
) -> ( ) -> ( % Replace any existing defs of this name.
retractall(def(Def, _)), retractall(def(Symbol, _)),
assertz(def(Def, Body)) assertz(def(Symbol, Body))
) ; true. % Otherwise it's okay. ) ; true.
% Split on newline chars a list of codes into a list of lists of codes
% one per line. Helper function.
lines([], []) :- !.
lines(Codes, [Line|Lines]) :- append(Line, [0'\n|Rest], Codes), !, lines(Rest, Lines).
lines(Codes, [Codes]).
:- assert_defs("defs.txt"). :- assert_defs("defs.txt").
words(Words) :- words(Words) :-
findall(Name, clause(func(Name, _, _), _), Funcs), findall(Name, clause(func(Name, _, _), _), Funcs),
findall(Name, clause(combo(Name, _, _, _, _), _), Combos, Funcs), findall(Name, clause(combo(Name, _, _, _, _), _), Combos, Funcs),