1 # -*- coding: utf-8 -*-
3 # Copyright © 2014, 2015, 2017 Simon Forman
5 # This file is part of joy.py
7 # joy.py is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # joy.py is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with joy.py. If not see <http://www.gnu.org/licenses/>.
20 from inspect import getdoc
23 from .parser import text_to_expression, Symbol
24 from .utils.stack import list_to_stack, iter_stack, pick, pushback
32 ('mod', ['%', 'rem', 'remainder', 'modulus']),
35 ('getitem', ['pick', 'at']),
46 ('rolldown', ['roll<']),
47 ('rollup', ['roll>']),
52 def add_aliases(D, A=ALIASES):
54 Given a dict and a iterable of (name, [alias, ...]) pairs, create
55 additional entries in the dict mapping each alias to the named function
56 if it's in the dict. Aliases for functions not in the dict are ignored.
58 for name, aliases in A:
69 third == rest rest first
71 product == 1 swap [*] step
73 swoncat == swap concat
74 flatten == [] swap [concat] step
78 enstacken == stack [clear] dip
79 disenstacken == ? [uncons ?] loop pop
81 dinfrirst == dip infra first
82 nullary == [stack] dinfrirst
83 unary == [stack [pop] dip] dinfrirst
84 binary == [stack [popop] dip] dinfrirst
85 ternary == [stack [popop pop] dip] dinfrirst
89 size == 0 swap [pop ++] step
90 cleave == [i] app2 [popd] dip
91 average == [sum 1.0 *] [size] cleave /
92 gcd == 1 [tuck modulus dup 0 >] loop pop
93 least_fraction == dup [gcd] infra [div] concat map
94 *fraction == [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons
95 *fraction0 == concat [[swap] dip * [*] dip] infra
96 down_to_zero == [0 >] [dup --] while
97 range_to_zero == unit [down_to_zero] infra
98 anamorphism == [pop []] swap [dip swons] genrec
99 range == [0 <=] [1 - dup] anamorphism
100 while == swap [nullary] cons dup dipd concat loop
102 primrec == [i] genrec
103 step_zero == 0 roll> step
107 ##z-down == [] swap uncons swap
108 ##z-up == swons swap shunt
109 ##z-right == [swons] cons dip uncons swap
110 ##z-left == swons [uncons swap] dip swap
113 ##divisor == popop 2 *
115 ##radical == swap dup * rollup * 4 * - sqrt
118 ##q0 == [[divisor] [minusb] [radical]] pam
119 ##q1 == [[root1] [root2]] pam
120 ##quadratic == [q0] ternary i [q1] ternary
124 ##PE1.1 == + dup [+] dip
125 ##PE1.2 == dup [3 & PE1.1] dip 2 >>
126 ##PE1.3 == 14811 swap [PE1.2] times pop
127 ##PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop
129 #PE1.2 == [PE1.1] step
130 #PE1 == 0 0 66 [[3 2 1 3 1 2 3] PE1.2] times [3 2 1 3] PE1.2 pop
134 class FunctionWrapper(object):
136 Allow functions to have a nice repr().
138 At some point it's likely this class and its subclasses would gain
139 machinery to support type checking and inference.
142 def __init__(self, f):
144 self.name = f.__name__.rstrip('_') # Don't shadow builtins.
145 self.__doc__ = f.__doc__ or str(f)
147 def __call__(self, stack, expression, dictionary):
149 Functions in general receive and return all three.
151 return self.f(stack, expression, dictionary)
157 class SimpleFunctionWrapper(FunctionWrapper):
159 Wrap functions that take and return just a stack.
162 def __call__(self, stack, expression, dictionary):
163 return self.f(stack), expression, dictionary
166 class BinaryBuiltinWrapper(FunctionWrapper):
168 Wrap functions that take two arguments and return a single result.
171 def __call__(self, stack, expression, dictionary):
172 (a, (b, stack)) = stack
173 result = self.f(b, a)
174 return (result, stack), expression, dictionary
177 class UnaryBuiltinWrapper(FunctionWrapper):
179 Wrap functions that take one argument and return a single result.
182 def __call__(self, stack, expression, dictionary):
185 return (result, stack), expression, dictionary
188 class DefinitionWrapper(FunctionWrapper):
190 Provide implementation of defined functions, and some helper methods.
193 def __init__(self, name, body_text, doc=None):
194 self.name = self.__name__ = name
195 self.body = text_to_expression(body_text)
196 self._body = tuple(iter_stack(self.body))
197 self.__doc__ = doc or body_text
199 def __call__(self, stack, expression, dictionary):
200 expression = list_to_stack(self._body, expression)
201 return stack, expression, dictionary
204 def parse_definition(class_, defi):
206 Given some text describing a Joy function definition parse it and
207 return a DefinitionWrapper.
209 name, proper, body_text = (n.strip() for n in defi.partition('=='))
211 raise ValueError('Definition %r failed' % (defi,))
212 return class_(name, body_text)
215 def add_definitions(class_, defs, dictionary):
216 for definition in _text_to_defs(defs):
217 class_.add_def(definition, dictionary)
220 def add_def(class_, definition, dictionary):
221 F = class_.parse_definition(definition)
222 dictionary[F.name] = F
225 def _text_to_defs(text):
226 return filter(None, (line.strip() for line in text.splitlines()))
234 def parse((text, stack)):
235 '''Parse the string on the stack to a Joy expression.'''
236 expression = text_to_expression(text)
237 return expression, stack
240 def first(((head, tail), stack)):
241 '''first == uncons pop'''
245 def rest(((head, tail), stack)):
246 '''rest == uncons popd'''
251 '''Coerce the item on the top of the stack to its Boolean value.'''
253 return bool(n), stack
258 getitem == drop first
260 Expects an integer and a quote on the stack and returns the item at the
261 nth position in the quote counting from 0.
264 -------------------------
268 n, (Q, stack) = stack
269 return pick(Q, n), stack
276 Expects an integer and a quote on the stack and returns the quote with
277 n items removed off the top.
280 ----------------------
284 n, (Q, stack) = stack
296 Expects an integer and a quote on the stack and returns the quote with
297 just the top n items in reverse order (because that's easier and you can
298 use reverse if needed.)
301 ----------------------
305 n, (Q, stack) = stack
319 Use a Boolean value to select one of two items.
322 ----------------------
327 ---------------------
330 Currently Python semantics are used to evaluate the "truthiness" of the
331 Boolean value (so empty string, zero, etc. are counted as false, etc.)
333 (if_, (then, (else_, stack))) = stack
334 return then if if_ else else_, stack
339 Use a Boolean value to select one of two items from a sequence.
342 ------------------------
347 -----------------------
350 The sequence can contain more than two items but not fewer.
351 Currently Python semantics are used to evaluate the "truthiness" of the
352 Boolean value (so empty string, zero, etc. are counted as false, etc.)
354 (flag, (choices, stack)) = stack
355 (else_, (then, _)) = choices
356 return then if flag else else_, stack
360 '''Given a list find the maximum.'''
362 return max(iter_stack(tos)), stack
366 '''Given a list find the minimum.'''
368 return min(iter_stack(tos)), stack
372 '''Given a quoted sequence of numbers return the sum.
374 sum == 0 swap [+] step
377 return sum(iter_stack(tos)), stack
382 Expects an item on the stack and a quote under it and removes that item
383 from the the quote. The item is only removed once.
386 ------------------------
390 (tos, (second, stack)) = S
391 l = list(iter_stack(second))
393 return list_to_stack(l), stack
397 '''Given a list remove duplicate items.'''
399 I = list(iter_stack(tos))
400 list_to_stack(sorted(set(I), key=I.index))
401 return list_to_stack(sorted(set(I), key=I.index)), stack
405 '''Given a list return it sorted.'''
407 return list_to_stack(sorted(iter_stack(tos))), stack
412 The cons operator expects a list on top of the stack and the potential
413 member below. The effect is to add the potential member into the
416 (tos, (second, stack)) = S
417 return (second, tos), stack
422 Inverse of cons, removes an item from the top of the list on the stack
423 and places it under the remaining list.
427 return tos, (item, stack)
431 '''Clear everything from the stack.
441 '''Duplicate the top item on the stack.'''
443 return tos, (tos, stack)
448 Copy the second item down on the stack to the top of the stack.
461 Copy the item at TOS under the second item of the stack.
468 (tos, (second, stack)) = S
469 return tos, (second, (tos, stack))
473 '''Swap the top two items on stack.'''
474 (tos, (second, stack)) = S
475 return second, (tos, stack)
480 old_stack, stack = stack
481 return stack, old_stack
486 The stack operator pushes onto the stack a list containing all the
487 elements of the stack.
494 The unstack operator expects a list on top of the stack and makes that
495 the stack discarding the rest of the stack.
502 '''Pop and discard the top item from the stack.'''
508 '''Pop and discard the second item from the stack.'''
509 (tos, (second, stack)) = S
514 '''Pop and discard the third item from the stack.'''
515 (tos, (second, (third, stack))) = S
516 return tos, (second, stack)
520 '''Pop and discard the first and second items from the stack.'''
521 (tos, (second, stack)) = S
526 '''Duplicate the second item on the stack.'''
527 (tos, (second, stack)) = S
528 return tos, (second, (second, stack))
532 '''Reverse the list on the top of the stack.
534 reverse == [] swap shunt
538 for term in iter_stack(tos):
544 '''Concatinate the two lists on the top of the stack.'''
545 (tos, (second, stack)) = S
546 for term in reversed(list(iter_stack(second))):
551 def shunt((tos, (second, stack))):
553 shunt == [swons] step
555 Like concat but reverses the top list into the second.
559 second = term, second
565 Replace the two lists on the top of the stack with a list of the pairs
566 from each list. The smallest list sets the length of the result list.
568 (tos, (second, stack)) = S
571 for a, b in zip(iter_stack(tos), iter_stack(second))
573 return list_to_stack(accumulator), stack
579 return tos + 1, stack
585 return tos - 1, stack
597 a, (b, stack) = stack
603 return int(math.floor(n))
605 floor.__doc__ = math.floor.__doc__
613 divmod_.__doc__ = divmod.__doc__
618 Return the square root of the number a.
619 Negative numbers return complex roots.
624 assert a < 0, repr(a)
625 r = math.sqrt(-a) * 1j
631 (a, (b, (c, stack))) = S
632 return b, (c, (a, stack))
637 (a, (b, (c, stack))) = S
638 return c, (a, (b, stack))
643 # if isinstance(text, str):
644 # return run(text, stack)
654 return _void(form), stack
658 return any(not _void(i) for i in iter_stack(form))
667 def words(stack, expression, dictionary):
668 '''Print all the words in alphabetical order.'''
669 print(' '.join(sorted(dictionary)))
670 return stack, expression, dictionary
673 def sharing(stack, expression, dictionary):
674 '''Print redistribution information.'''
675 print("You may convey verbatim copies of the Program's source code as"
676 ' you receive it, in any medium, provided that you conspicuously'
677 ' and appropriately publish on each copy an appropriate copyright'
678 ' notice; keep intact all notices stating that this License and'
679 ' any non-permissive terms added in accord with section 7 apply'
680 ' to the code; keep intact all notices of the absence of any'
681 ' warranty; and give all recipients a copy of this License along'
683 ' You should have received a copy of the GNU General Public License'
684 ' along with Joypy. If not see <http://www.gnu.org/licenses/>.')
685 return stack, expression, dictionary
688 def warranty(stack, expression, dictionary):
689 '''Print warranty information.'''
690 print('THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY'
691 ' APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE'
692 ' COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM'
693 ' "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR'
694 ' IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES'
695 ' OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE'
696 ' ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS'
697 ' WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE'
698 ' COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.')
699 return stack, expression, dictionary
702 # def simple_manual(stack):
704 # Print words and help for each word.
706 # for name, f in sorted(FUNCTIONS.items()):
708 # boxline = '+%s+' % ('-' * (len(name) + 2))
711 # '| %s |' % (name,),
713 # d if d else ' ...',
721 def help_(S, expression, dictionary):
722 '''Accepts a quoted symbol on the top of the stack and prints its docs.'''
723 ((symbol, _), stack) = S
724 word = dictionary[symbol]
726 return stack, expression, dictionary
734 # Several combinators depend on other words in their definitions,
735 # we use symbols to prevent hard-coding these, so in theory, you
736 # could change the word in the dictionary to use different semantics.
737 S_choice = Symbol('choice')
738 S_first = Symbol('first')
739 S_getitem = Symbol('getitem')
740 S_genrec = Symbol('genrec')
741 S_loop = Symbol('loop')
743 S_ifte = Symbol('ifte')
744 S_infra = Symbol('infra')
745 S_step = Symbol('step')
746 S_times = Symbol('times')
747 S_swaack = Symbol('swaack')
748 S_truthy = Symbol('truthy')
751 def i(stack, expression, dictionary):
753 The i combinator expects a quoted program on the stack and unpacks it
754 onto the pending expression for evaluation.
762 return stack, pushback(quote, expression), dictionary
765 def x(stack, expression, dictionary):
769 ... [Q] x = ... [Q] dup i
770 ... [Q] x = ... [Q] [Q] i
771 ... [Q] x = ... [Q] Q
775 return stack, pushback(quote, expression), dictionary
778 def b(stack, expression, dictionary):
782 ... [P] [Q] b == ... [P] i [Q] i
783 ... [P] [Q] b == ... P Q
786 q, (p, (stack)) = stack
787 return stack, pushback(p, pushback(q, expression)), dictionary
790 def dupdip(stack, expression, dictionary):
792 [F] dupdip == dup [F] dip
802 return stack, pushback(F, (a, expression)), dictionary
805 def infra(stack, expression, dictionary):
807 Accept a quoted program and a list on the stack and run the program
808 with the list as its stack.
810 ... [a b c] [Q] . infra
811 -----------------------------
812 c b a . Q [...] swaack
815 (quote, (aggregate, stack)) = stack
816 return aggregate, pushback(quote, (stack, (S_swaack, expression))), dictionary
819 def genrec(stack, expression, dictionary):
821 General Recursion Combinator.
823 [if] [then] [rec1] [rec2] genrec
824 ---------------------------------------------------------------------
825 [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
827 From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun:
828 "The genrec combinator takes four program parameters in addition to
829 whatever data parameters it needs. Fourth from the top is an if-part,
830 followed by a then-part. If the if-part yields true, then the then-part
831 is executed and the combinator terminates. The other two parameters are
832 the rec1-part and the rec2-part. If the if-part yields false, the
833 rec1-part is executed. Following that the four program parameters and
834 the combinator are again pushed onto the stack bundled up in a quoted
835 form. Then the rec2-part is executed, where it will find the bundled
836 form. Typically it will then execute the bundled form, either with i or
837 with app2, or some other combinator."
839 The way to design one of these is to fix your base case [then] and the
840 test [if], and then treat rec1 and rec2 as an else-part "sandwiching"
841 a quotation of the whole function.
843 For example, given a (general recursive) function 'F':
845 F == [I] [T] [R1] [R2] genrec
847 If the [I] if-part fails you must derive R1 and R2 from:
851 Just set the stack arguments in front, and figure out what R1 and R2
852 have to do to apply the quoted [F] in the proper way. In effect, the
853 genrec combinator turns into an ifte combinator with a quoted copy of
854 the original definition in the else-part:
856 F == [I] [T] [R1] [R2] genrec
857 == [I] [T] [R1 [F] R2] ifte
859 (Primitive recursive functions are those where R2 == i.
861 P == [I] [T] [R] primrec
862 == [I] [T] [R [P] i] ifte
863 == [I] [T] [R P] ifte
866 (rec2, (rec1, stack)) = stack
867 (then, (if_, _)) = stack
868 F = (if_, (then, (rec1, (rec2, (S_genrec, ())))))
869 else_ = pushback(rec1, (F, rec2))
870 return (else_, stack), (S_ifte, expression), dictionary
873 def map_(S, expression, dictionary):
875 Run the quoted program on TOS on the items in the list under it, push a
876 new list with the results (in place of the program and original list.
878 # (quote, (aggregate, stack)) = S
879 # results = list_to_stack([
880 # joy((term, stack), quote, dictionary)[0][0]
881 # for term in iter_stack(aggregate)
883 # return (results, stack), expression, dictionary
884 (quote, (aggregate, stack)) = S
886 return (aggregate, stack), expression, dictionary
888 for term in iter_stack(aggregate):
890 batch = (s, (quote, (S_infra, (S_first, batch))))
891 stack = (batch, ((), stack))
892 return stack, (S_infra, expression), dictionary
895 #def cleave(S, expression, dictionary):
897 # The cleave combinator expects two quotations, and below that an item X.
898 # It first executes [P], with X on top, and saves the top result element.
899 # Then it executes [Q], again with X, and saves the top result.
900 # Finally it restores the stack to what it was below X and pushes the two
901 # results P(X) and Q(X).
903 # (Q, (P, (x, stack))) = S
904 # p = joy((x, stack), P, dictionary)[0][0]
905 # q = joy((x, stack), Q, dictionary)[0][0]
906 # return (q, (p, stack)), expression, dictionary
909 def branch(stack, expression, dictionary):
911 Use a Boolean value to select one of two quoted programs to run.
913 branch == roll< choice i
917 --------------------------
921 -------------------------
925 (then, (else_, (flag, stack))) = stack
926 return stack, pushback(then if flag else else_, expression), dictionary
929 def ifte(stack, expression, dictionary):
931 If-Then-Else Combinator
933 ... [if] [then] [else] ifte
934 ---------------------------------------------------
935 ... [[else] [then]] [...] [if] infra select i
940 ... [if] [then] [else] ifte
941 -------------------------------------------------------
942 ... [else] [then] [...] [if] infra first choice i
945 Has the effect of grabbing a copy of the stack on which to run the
948 (else_, (then, (if_, stack))) = stack
949 expression = (S_infra, (S_first, (S_choice, (S_i, expression))))
950 stack = (if_, (stack, (then, (else_, stack))))
951 return stack, expression, dictionary
954 def dip(stack, expression, dictionary):
956 The dip combinator expects a quoted program on the stack and below it
957 some item, it hoists the item into the expression and runs the program
958 on the rest of the stack.
965 (quote, (x, stack)) = stack
966 expression = (x, expression)
967 return stack, pushback(quote, expression), dictionary
970 def dipd(S, expression, dictionary):
972 Like dip but expects two items.
975 ---------------------
979 (quote, (x, (y, stack))) = S
980 expression = (y, (x, expression))
981 return stack, pushback(quote, expression), dictionary
984 def dipdd(S, expression, dictionary):
986 Like dip but expects three items.
989 -----------------------
993 (quote, (x, (y, (z, stack)))) = S
994 expression = (z, (y, (x, expression)))
995 return stack, pushback(quote, expression), dictionary
998 def app1(S, expression, dictionary):
1000 Given a quoted program on TOS and anything as the second stack item run
1001 the program and replace the two args with the first result of the
1005 -----------------------------------
1006 ... [x ...] [Q] . infra first
1008 (quote, (x, stack)) = S
1009 stack = (quote, ((x, stack), stack))
1010 expression = (S_infra, (S_first, expression))
1011 return stack, expression, dictionary
1014 def app2(S, expression, dictionary):
1015 '''Like app1 with two items.
1018 -----------------------------------
1019 ... [y ...] [Q] . infra first
1020 [x ...] [Q] infra first
1023 (quote, (x, (y, stack))) = S
1024 expression = (S_infra, (S_first,
1025 ((x, stack), (quote, (S_infra, (S_first,
1027 stack = (quote, ((y, stack), stack))
1028 return stack, expression, dictionary
1031 def app3(S, expression, dictionary):
1032 '''Like app1 with three items.
1034 ... z y x [Q] . app3
1035 -----------------------------------
1036 ... [z ...] [Q] . infra first
1037 [y ...] [Q] infra first
1038 [x ...] [Q] infra first
1041 (quote, (x, (y, (z, stack)))) = S
1042 expression = (S_infra, (S_first,
1043 ((y, stack), (quote, (S_infra, (S_first,
1044 ((x, stack), (quote, (S_infra, (S_first,
1045 expression))))))))))
1046 stack = (quote, ((z, stack), stack))
1047 return stack, expression, dictionary
1050 def step(S, expression, dictionary):
1052 Run a quoted program on each item in a sequence.
1055 -----------------------
1060 ------------------------
1064 ... [a b c] [Q] . step
1065 ----------------------------------------
1066 ... a . Q [b c] [Q] step
1068 The step combinator executes the quotation on each member of the list
1069 on top of the stack.
1071 (quote, (aggregate, stack)) = S
1073 return stack, expression, dictionary
1074 head, tail = aggregate
1075 stack = quote, (head, stack)
1077 expression = tail, (quote, (S_step, expression))
1078 expression = S_i, expression
1079 return stack, expression, dictionary
1082 def times(stack, expression, dictionary):
1084 times == [-- dip] cons [swap] infra [0 >] swap while pop
1087 --------------------- w/ n <= 0
1092 ---------------------------------
1097 --------------------------------- w/ n > 1
1098 ... . Q (n - 1) [Q] times
1101 # times == [-- dip] cons [swap] infra [0 >] swap while pop
1102 (quote, (n, stack)) = stack
1104 return stack, expression, dictionary
1107 expression = n, (quote, (S_times, expression))
1108 expression = pushback(quote, expression)
1109 return stack, expression, dictionary
1112 # The current definition above works like this:
1115 # --------------------------------------
1116 # [P] nullary [Q [P] nullary] loop
1118 # while == [pop i not] [popop] [dudipd] primrec
1120 #def while_(S, expression, dictionary):
1121 # '''[if] [body] while'''
1122 # (body, (if_, stack)) = S
1123 # while joy(stack, if_, dictionary)[0][0]:
1124 # stack = joy(stack, body, dictionary)[0]
1125 # return stack, expression, dictionary
1128 def loop(stack, expression, dictionary):
1130 Basic loop combinator.
1133 -----------------------
1137 ------------------------
1141 quote, (flag, stack) = stack
1143 expression = pushback(quote, (quote, (S_loop, expression)))
1144 return stack, expression, dictionary
1147 #def nullary(S, expression, dictionary):
1149 # Run the program on TOS and return its first result without consuming
1150 # any of the stack (except the program on TOS.)
1152 # (quote, stack) = S
1153 # result = joy(stack, quote, dictionary)
1154 # return (result[0][0], stack), expression, dictionary
1157 #def unary(S, expression, dictionary):
1158 # (quote, stack) = S
1159 # _, return_stack = stack
1160 # result = joy(stack, quote, dictionary)[0]
1161 # return (result[0], return_stack), expression, dictionary
1164 #def binary(S, expression, dictionary):
1165 # (quote, stack) = S
1166 # _, (_, return_stack) = stack
1167 # result = joy(stack, quote, dictionary)[0]
1168 # return (result[0], return_stack), expression, dictionary
1171 #def ternary(S, expression, dictionary):
1172 # (quote, stack) = S
1173 # _, (_, (_, return_stack)) = stack
1174 # result = joy(stack, quote, dictionary)[0]
1175 # return (result[0], return_stack), expression, dictionary
1179 BinaryBuiltinWrapper(operator.add),
1180 BinaryBuiltinWrapper(operator.and_),
1181 BinaryBuiltinWrapper(operator.div),
1182 BinaryBuiltinWrapper(operator.eq),
1183 BinaryBuiltinWrapper(operator.floordiv),
1184 BinaryBuiltinWrapper(operator.ge),
1185 BinaryBuiltinWrapper(operator.gt),
1186 BinaryBuiltinWrapper(operator.le),
1187 BinaryBuiltinWrapper(operator.lshift),
1188 BinaryBuiltinWrapper(operator.lt),
1189 BinaryBuiltinWrapper(operator.mod),
1190 BinaryBuiltinWrapper(operator.mul),
1191 BinaryBuiltinWrapper(operator.ne),
1192 BinaryBuiltinWrapper(operator.or_),
1193 BinaryBuiltinWrapper(operator.pow),
1194 BinaryBuiltinWrapper(operator.rshift),
1195 BinaryBuiltinWrapper(operator.sub),
1196 BinaryBuiltinWrapper(operator.truediv),
1197 BinaryBuiltinWrapper(operator.xor),
1199 UnaryBuiltinWrapper(abs),
1200 UnaryBuiltinWrapper(floor),
1201 UnaryBuiltinWrapper(operator.neg),
1202 UnaryBuiltinWrapper(operator.not_),
1203 UnaryBuiltinWrapper(sqrt),
1208 FunctionWrapper(app1),
1209 FunctionWrapper(app2),
1210 FunctionWrapper(app3),
1212 FunctionWrapper(branch),
1213 # FunctionWrapper(binary),
1214 # FunctionWrapper(cleave),
1215 FunctionWrapper(dip),
1216 FunctionWrapper(dipd),
1217 FunctionWrapper(dipdd),
1218 FunctionWrapper(dupdip),
1219 FunctionWrapper(genrec),
1220 FunctionWrapper(help_),
1222 FunctionWrapper(ifte),
1223 FunctionWrapper(infra),
1224 FunctionWrapper(loop),
1225 FunctionWrapper(map_),
1226 # FunctionWrapper(nullary),
1227 FunctionWrapper(step),
1228 FunctionWrapper(times),
1229 # FunctionWrapper(ternary),
1230 # FunctionWrapper(unary),
1231 # FunctionWrapper(while_),
1232 FunctionWrapper(words),
1238 SimpleFunctionWrapper(choice),
1239 SimpleFunctionWrapper(clear),
1240 SimpleFunctionWrapper(concat),
1241 SimpleFunctionWrapper(cons),
1242 SimpleFunctionWrapper(divmod_),
1243 SimpleFunctionWrapper(drop),
1244 SimpleFunctionWrapper(dup),
1245 SimpleFunctionWrapper(dupd),
1246 SimpleFunctionWrapper(first),
1247 SimpleFunctionWrapper(getitem),
1248 SimpleFunctionWrapper(id_),
1249 SimpleFunctionWrapper(max_),
1250 SimpleFunctionWrapper(min_),
1251 SimpleFunctionWrapper(over),
1252 SimpleFunctionWrapper(parse),
1253 SimpleFunctionWrapper(pm),
1254 SimpleFunctionWrapper(pop),
1255 SimpleFunctionWrapper(popd),
1256 SimpleFunctionWrapper(popdd),
1257 SimpleFunctionWrapper(popop),
1258 SimpleFunctionWrapper(pred),
1259 SimpleFunctionWrapper(remove),
1260 SimpleFunctionWrapper(rest),
1261 SimpleFunctionWrapper(reverse),
1262 SimpleFunctionWrapper(rolldown),
1263 SimpleFunctionWrapper(rollup),
1264 SimpleFunctionWrapper(select),
1265 SimpleFunctionWrapper(shunt),
1266 SimpleFunctionWrapper(sort_),
1267 SimpleFunctionWrapper(stack_),
1268 SimpleFunctionWrapper(succ),
1269 SimpleFunctionWrapper(sum_),
1270 SimpleFunctionWrapper(swaack),
1271 SimpleFunctionWrapper(swap),
1272 SimpleFunctionWrapper(take),
1273 SimpleFunctionWrapper(truthy),
1274 SimpleFunctionWrapper(tuck),
1275 SimpleFunctionWrapper(uncons),
1276 SimpleFunctionWrapper(unique),
1277 SimpleFunctionWrapper(unstack),
1278 SimpleFunctionWrapper(unstack),
1279 SimpleFunctionWrapper(void),
1280 SimpleFunctionWrapper(zip_),
1282 FunctionWrapper(sharing),
1283 FunctionWrapper(warranty),
1287 def initialize(dictionary=None):
1288 if dictionary is None:
1290 dictionary.update((F.name, F) for F in builtins)
1291 dictionary.update((F.name, F) for F in combinators)
1292 dictionary.update((F.name, F) for F in primitives)
1293 add_aliases(dictionary)
1294 DefinitionWrapper.add_definitions(definitions, dictionary)