• R/O
  • SSH

Joypy: Commit

This repo is not current. Development has moved from Hg to Git. For the latest code use the "Source Code" tab above to go to the "Thun" git repo or navigate to:
https://osdn.net/projects/joypy/scm/git/Thun


Commit MetaInfo

Revision5bdb539d2d746316caea630d6d1cd126bbc9ee68 (tree)
Time2018-04-17 04:27:52
AuthorSimon Forman <sforman@hush...>
CommiterSimon Forman

Log Message

Bringing over some changes.

I need to harmonize my local repo and the OSDN repo.

Change Summary

Incremental Difference

diff -r 6fa14b6647f4 -r 5bdb539d2d74 joy/library.py
--- a/joy/library.py Sat Apr 14 18:13:13 2018 -0700
+++ b/joy/library.py Mon Apr 16 12:27:52 2018 -0700
@@ -1,22 +1,28 @@
11 # -*- coding: utf-8 -*-
22 #
3-# Copyright © 2014, 2015, 2017 Simon Forman
3+# Copyright © 2014, 2015, 2017, 2018 Simon Forman
44 #
5-# This file is part of joy.py
5+# This file is part of Joypy
66 #
7-# joy.py is free software: you can redistribute it and/or modify
7+# Joypy is free software: you can redistribute it and/or modify
88 # it under the terms of the GNU General Public License as published by
99 # the Free Software Foundation, either version 3 of the License, or
1010 # (at your option) any later version.
1111 #
12-# joy.py is distributed in the hope that it will be useful,
12+# Joypy is distributed in the hope that it will be useful,
1313 # but WITHOUT ANY WARRANTY; without even the implied warranty of
1414 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515 # GNU General Public License for more details.
1616 #
1717 # 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/>.
18+# along with Joypy. If not see <http://www.gnu.org/licenses/>.
1919 #
20+'''
21+This module contains the Joy function infrastructure and a library of
22+functions. It's main export is a Python function initialize() that
23+returns a dictionary of Joy functions suitable for use with the joy()
24+function.
25+'''
2026 from inspect import getdoc
2127 import operator, math
2228
@@ -24,9 +30,24 @@
2430 from .utils.stack import list_to_stack, iter_stack, pick, pushback
2531
2632
33+_dictionary = {}
34+
35+
36+def inscribe(function):
37+ '''A decorator to inscribe functions in to the default dictionary.'''
38+ _dictionary[function.name] = function
39+ return function
40+
41+
42+def initialize():
43+ '''Return a dictionary of Joy functions for use with joy().'''
44+ return _dictionary.copy()
45+
46+
2747 ALIASES = (
2848 ('add', ['+']),
2949 ('and', ['&']),
50+ ('bool', ['truthy']),
3051 ('mul', ['*']),
3152 ('truediv', ['/']),
3253 ('mod', ['%', 'rem', 'remainder', 'modulus']),
@@ -231,28 +252,30 @@
231252 #
232253
233254
255+@inscribe
256+@SimpleFunctionWrapper
234257 def parse((text, stack)):
235258 '''Parse the string on the stack to a Joy expression.'''
236259 expression = text_to_expression(text)
237260 return expression, stack
238261
239262
263+@inscribe
264+@SimpleFunctionWrapper
240265 def first(((head, tail), stack)):
241266 '''first == uncons pop'''
242267 return head, stack
243268
244269
270+@inscribe
271+@SimpleFunctionWrapper
245272 def rest(((head, tail), stack)):
246273 '''rest == uncons popd'''
247274 return tail, stack
248275
249276
250-def truthy(stack):
251- '''Coerce the item on the top of the stack to its Boolean value.'''
252- n, stack = stack
253- return bool(n), stack
254-
255-
277+@inscribe
278+@SimpleFunctionWrapper
256279 def getitem(stack):
257280 '''
258281 getitem == drop first
@@ -269,6 +292,8 @@
269292 return pick(Q, n), stack
270293
271294
295+@inscribe
296+@SimpleFunctionWrapper
272297 def drop(stack):
273298 '''
274299 drop == [rest] times
@@ -291,6 +316,8 @@
291316 return Q, stack
292317
293318
319+@inscribe
320+@SimpleFunctionWrapper
294321 def take(stack):
295322 '''
296323 Expects an integer and a quote on the stack and returns the quote with
@@ -314,6 +341,8 @@
314341 return x, stack
315342
316343
344+@inscribe
345+@SimpleFunctionWrapper
317346 def choice(stack):
318347 '''
319348 Use a Boolean value to select one of two items.
@@ -334,6 +363,8 @@
334363 return then if if_ else else_, stack
335364
336365
366+@inscribe
367+@SimpleFunctionWrapper
337368 def select(stack):
338369 '''
339370 Use a Boolean value to select one of two items from a sequence.
@@ -356,18 +387,24 @@
356387 return then if flag else else_, stack
357388
358389
390+@inscribe
391+@SimpleFunctionWrapper
359392 def max_(S):
360393 '''Given a list find the maximum.'''
361394 tos, stack = S
362395 return max(iter_stack(tos)), stack
363396
364397
398+@inscribe
399+@SimpleFunctionWrapper
365400 def min_(S):
366401 '''Given a list find the minimum.'''
367402 tos, stack = S
368403 return min(iter_stack(tos)), stack
369404
370405
406+@inscribe
407+@SimpleFunctionWrapper
371408 def sum_(S):
372409 '''Given a quoted sequence of numbers return the sum.
373410
@@ -377,6 +414,8 @@
377414 return sum(iter_stack(tos)), stack
378415
379416
417+@inscribe
418+@SimpleFunctionWrapper
380419 def remove(S):
381420 '''
382421 Expects an item on the stack and a quote under it and removes that item
@@ -393,6 +432,8 @@
393432 return list_to_stack(l), stack
394433
395434
435+@inscribe
436+@SimpleFunctionWrapper
396437 def unique(S):
397438 '''Given a list remove duplicate items.'''
398439 tos, stack = S
@@ -401,12 +442,16 @@
401442 return list_to_stack(sorted(set(I), key=I.index)), stack
402443
403444
445+@inscribe
446+@SimpleFunctionWrapper
404447 def sort_(S):
405448 '''Given a list return it sorted.'''
406449 tos, stack = S
407450 return list_to_stack(sorted(iter_stack(tos))), stack
408451
409452
453+@inscribe
454+@SimpleFunctionWrapper
410455 def cons(S):
411456 '''
412457 The cons operator expects a list on top of the stack and the potential
@@ -417,6 +462,8 @@
417462 return (second, tos), stack
418463
419464
465+@inscribe
466+@SimpleFunctionWrapper
420467 def uncons(S):
421468 '''
422469 Inverse of cons, removes an item from the top of the list on the stack
@@ -427,6 +474,8 @@
427474 return tos, (item, stack)
428475
429476
477+@inscribe
478+@SimpleFunctionWrapper
430479 def clear(stack):
431480 '''Clear everything from the stack.
432481
@@ -437,12 +486,16 @@
437486 return ()
438487
439488
489+@inscribe
490+@SimpleFunctionWrapper
440491 def dup(S):
441492 '''Duplicate the top item on the stack.'''
442493 (tos, stack) = S
443494 return tos, (tos, stack)
444495
445496
497+@inscribe
498+@SimpleFunctionWrapper
446499 def over(S):
447500 '''
448501 Copy the second item down on the stack to the top of the stack.
@@ -456,6 +509,8 @@
456509 return second, S
457510
458511
512+@inscribe
513+@SimpleFunctionWrapper
459514 def tuck(S):
460515 '''
461516 Copy the item at TOS under the second item of the stack.
@@ -469,18 +524,24 @@
469524 return tos, (second, (tos, stack))
470525
471526
527+@inscribe
528+@SimpleFunctionWrapper
472529 def swap(S):
473530 '''Swap the top two items on stack.'''
474531 (tos, (second, stack)) = S
475532 return second, (tos, stack)
476533
477534
535+@inscribe
536+@SimpleFunctionWrapper
478537 def swaack(stack):
479538 '''swap stack'''
480539 old_stack, stack = stack
481540 return stack, old_stack
482541
483542
543+@inscribe
544+@SimpleFunctionWrapper
484545 def stack_(stack):
485546 '''
486547 The stack operator pushes onto the stack a list containing all the
@@ -489,45 +550,56 @@
489550 return stack, stack
490551
491552
492-def unstack(S):
553+@inscribe
554+@SimpleFunctionWrapper
555+def unstack(stack):
493556 '''
494557 The unstack operator expects a list on top of the stack and makes that
495558 the stack discarding the rest of the stack.
496559 '''
497- (tos, stack) = S
498- return tos
560+ return stack[0]
499561
500562
501-def pop(S):
563+@inscribe
564+@SimpleFunctionWrapper
565+def pop(stack):
502566 '''Pop and discard the top item from the stack.'''
503- (tos, stack) = S
504- return stack
567+ return stack[1]
505568
506569
507-def popd(S):
570+@inscribe
571+@SimpleFunctionWrapper
572+def popd(stack):
508573 '''Pop and discard the second item from the stack.'''
509- (tos, (second, stack)) = S
574+ (tos, (_, stack)) = stack
510575 return tos, stack
511576
512577
513-def popdd(S):
578+@inscribe
579+@SimpleFunctionWrapper
580+def popdd(stack):
514581 '''Pop and discard the third item from the stack.'''
515- (tos, (second, (third, stack))) = S
582+ (tos, (second, (_, stack))) = stack
516583 return tos, (second, stack)
517584
518585
519-def popop(S):
586+@inscribe
587+@SimpleFunctionWrapper
588+def popop(stack):
520589 '''Pop and discard the first and second items from the stack.'''
521- (tos, (second, stack)) = S
522- return stack
590+ return stack[1][1]
523591
524592
593+@inscribe
594+@SimpleFunctionWrapper
525595 def dupd(S):
526596 '''Duplicate the second item on the stack.'''
527597 (tos, (second, stack)) = S
528598 return tos, (second, (second, stack))
529599
530600
601+@inscribe
602+@SimpleFunctionWrapper
531603 def reverse(S):
532604 '''Reverse the list on the top of the stack.
533605
@@ -540,6 +612,8 @@
540612 return res, stack
541613
542614
615+@inscribe
616+@SimpleFunctionWrapper
543617 def concat(S):
544618 '''Concatinate the two lists on the top of the stack.'''
545619 (tos, (second, stack)) = S
@@ -548,6 +622,8 @@
548622 return tos, stack
549623
550624
625+@inscribe
626+@SimpleFunctionWrapper
551627 def shunt((tos, (second, stack))):
552628 '''
553629 shunt == [swons] step
@@ -560,6 +636,8 @@
560636 return second, stack
561637
562638
639+@inscribe
640+@SimpleFunctionWrapper
563641 def zip_(S):
564642 '''
565643 Replace the two lists on the top of the stack with a list of the pairs
@@ -573,18 +651,24 @@
573651 return list_to_stack(accumulator), stack
574652
575653
654+@inscribe
655+@SimpleFunctionWrapper
576656 def succ(S):
577657 '''Increment TOS.'''
578658 (tos, stack) = S
579659 return tos + 1, stack
580660
581661
662+@inscribe
663+@SimpleFunctionWrapper
582664 def pred(S):
583665 '''Decrement TOS.'''
584666 (tos, stack) = S
585667 return tos - 1, stack
586668
587669
670+@inscribe
671+@SimpleFunctionWrapper
588672 def pm(stack):
589673 '''
590674 Plus or minus
@@ -605,6 +689,8 @@
605689 floor.__doc__ = math.floor.__doc__
606690
607691
692+@inscribe
693+@SimpleFunctionWrapper
608694 def divmod_(S):
609695 a, (b, stack) = S
610696 d, m = divmod(a, b)
@@ -626,12 +712,16 @@
626712 return r
627713
628714
715+@inscribe
716+@SimpleFunctionWrapper
629717 def rollup(S):
630718 '''a b c -> b c a'''
631719 (a, (b, (c, stack))) = S
632720 return b, (c, (a, stack))
633721
634722
723+@inscribe
724+@SimpleFunctionWrapper
635725 def rolldown(S):
636726 '''a b c -> c a b'''
637727 (a, (b, (c, stack))) = S
@@ -645,10 +735,14 @@
645735 # return stack
646736
647737
738+@inscribe
739+@SimpleFunctionWrapper
648740 def id_(stack):
649741 return stack
650742
651743
744+@inscribe
745+@SimpleFunctionWrapper
652746 def void(stack):
653747 form, stack = stack
654748 return _void(form), stack
@@ -664,12 +758,16 @@
664758 ## take
665759
666760
761+@inscribe
762+@FunctionWrapper
667763 def words(stack, expression, dictionary):
668764 '''Print all the words in alphabetical order.'''
669765 print(' '.join(sorted(dictionary)))
670766 return stack, expression, dictionary
671767
672768
769+@inscribe
770+@FunctionWrapper
673771 def sharing(stack, expression, dictionary):
674772 '''Print redistribution information.'''
675773 print("You may convey verbatim copies of the Program's source code as"
@@ -685,6 +783,8 @@
685783 return stack, expression, dictionary
686784
687785
786+@inscribe
787+@FunctionWrapper
688788 def warranty(stack, expression, dictionary):
689789 '''Print warranty information.'''
690790 print('THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY'
@@ -718,6 +818,8 @@
718818 # return stack
719819
720820
821+@inscribe
822+@FunctionWrapper
721823 def help_(S, expression, dictionary):
722824 '''Accepts a quoted symbol on the top of the stack and prints its docs.'''
723825 ((symbol, _), stack) = S
@@ -748,6 +850,8 @@
748850 S_truthy = Symbol('truthy')
749851
750852
853+@inscribe
854+@FunctionWrapper
751855 def i(stack, expression, dictionary):
752856 '''
753857 The i combinator expects a quoted program on the stack and unpacks it
@@ -762,6 +866,8 @@
762866 return stack, pushback(quote, expression), dictionary
763867
764868
869+@inscribe
870+@FunctionWrapper
765871 def x(stack, expression, dictionary):
766872 '''
767873 x == dup i
@@ -775,6 +881,8 @@
775881 return stack, pushback(quote, expression), dictionary
776882
777883
884+@inscribe
885+@FunctionWrapper
778886 def b(stack, expression, dictionary):
779887 '''
780888 b == [i] dip i
@@ -787,6 +895,8 @@
787895 return stack, pushback(p, pushback(q, expression)), dictionary
788896
789897
898+@inscribe
899+@FunctionWrapper
790900 def dupdip(stack, expression, dictionary):
791901 '''
792902 [F] dupdip == dup [F] dip
@@ -802,6 +912,8 @@
802912 return stack, pushback(F, (a, expression)), dictionary
803913
804914
915+@inscribe
916+@FunctionWrapper
805917 def infra(stack, expression, dictionary):
806918 '''
807919 Accept a quoted program and a list on the stack and run the program
@@ -816,6 +928,8 @@
816928 return aggregate, pushback(quote, (stack, (S_swaack, expression))), dictionary
817929
818930
931+@inscribe
932+@FunctionWrapper
819933 def genrec(stack, expression, dictionary):
820934 '''
821935 General Recursion Combinator.
@@ -870,6 +984,8 @@
870984 return (else_, stack), (S_ifte, expression), dictionary
871985
872986
987+@inscribe
988+@FunctionWrapper
873989 def map_(S, expression, dictionary):
874990 '''
875991 Run the quoted program on TOS on the items in the list under it, push a
@@ -906,6 +1022,8 @@
9061022 # return (q, (p, stack)), expression, dictionary
9071023
9081024
1025+@inscribe
1026+@FunctionWrapper
9091027 def branch(stack, expression, dictionary):
9101028 '''
9111029 Use a Boolean value to select one of two quoted programs to run.
@@ -926,6 +1044,8 @@
9261044 return stack, pushback(then if flag else else_, expression), dictionary
9271045
9281046
1047+@inscribe
1048+@FunctionWrapper
9291049 def ifte(stack, expression, dictionary):
9301050 '''
9311051 If-Then-Else Combinator
@@ -951,6 +1071,8 @@
9511071 return stack, expression, dictionary
9521072
9531073
1074+@inscribe
1075+@FunctionWrapper
9541076 def dip(stack, expression, dictionary):
9551077 '''
9561078 The dip combinator expects a quoted program on the stack and below it
@@ -967,6 +1089,8 @@
9671089 return stack, pushback(quote, expression), dictionary
9681090
9691091
1092+@inscribe
1093+@FunctionWrapper
9701094 def dipd(S, expression, dictionary):
9711095 '''
9721096 Like dip but expects two items.
@@ -981,6 +1105,8 @@
9811105 return stack, pushback(quote, expression), dictionary
9821106
9831107
1108+@inscribe
1109+@FunctionWrapper
9841110 def dipdd(S, expression, dictionary):
9851111 '''
9861112 Like dip but expects three items.
@@ -995,6 +1121,8 @@
9951121 return stack, pushback(quote, expression), dictionary
9961122
9971123
1124+@inscribe
1125+@FunctionWrapper
9981126 def app1(S, expression, dictionary):
9991127 '''
10001128 Given a quoted program on TOS and anything as the second stack item run
@@ -1011,6 +1139,8 @@
10111139 return stack, expression, dictionary
10121140
10131141
1142+@inscribe
1143+@FunctionWrapper
10141144 def app2(S, expression, dictionary):
10151145 '''Like app1 with two items.
10161146
@@ -1028,6 +1158,8 @@
10281158 return stack, expression, dictionary
10291159
10301160
1161+@inscribe
1162+@FunctionWrapper
10311163 def app3(S, expression, dictionary):
10321164 '''Like app1 with three items.
10331165
@@ -1047,6 +1179,8 @@
10471179 return stack, expression, dictionary
10481180
10491181
1182+@inscribe
1183+@FunctionWrapper
10501184 def step(S, expression, dictionary):
10511185 '''
10521186 Run a quoted program on each item in a sequence.
@@ -1079,6 +1213,8 @@
10791213 return stack, expression, dictionary
10801214
10811215
1216+@inscribe
1217+@FunctionWrapper
10821218 def times(stack, expression, dictionary):
10831219 '''
10841220 times == [-- dip] cons [swap] infra [0 >] swap while pop
@@ -1125,6 +1261,8 @@
11251261 # return stack, expression, dictionary
11261262
11271263
1264+@inscribe
1265+@FunctionWrapper
11281266 def loop(stack, expression, dictionary):
11291267 '''
11301268 Basic loop combinator.
@@ -1175,7 +1313,15 @@
11751313 # return (result[0], return_stack), expression, dictionary
11761314
11771315
1178-builtins = (
1316+# FunctionWrapper(binary),
1317+# FunctionWrapper(cleave),
1318+# FunctionWrapper(nullary),
1319+# FunctionWrapper(ternary),
1320+# FunctionWrapper(unary),
1321+# FunctionWrapper(while_),
1322+
1323+
1324+for F in (
11791325 BinaryBuiltinWrapper(operator.add),
11801326 BinaryBuiltinWrapper(operator.and_),
11811327 BinaryBuiltinWrapper(operator.div),
@@ -1197,99 +1343,16 @@
11971343 BinaryBuiltinWrapper(operator.xor),
11981344
11991345 UnaryBuiltinWrapper(abs),
1346+ UnaryBuiltinWrapper(bool),
12001347 UnaryBuiltinWrapper(floor),
12011348 UnaryBuiltinWrapper(operator.neg),
12021349 UnaryBuiltinWrapper(operator.not_),
12031350 UnaryBuiltinWrapper(sqrt),
1204- )
1205-
1206-
1207-combinators = (
1208- FunctionWrapper(app1),
1209- FunctionWrapper(app2),
1210- FunctionWrapper(app3),
1211- FunctionWrapper(b),
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_),
1221- FunctionWrapper(i),
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),
1233- FunctionWrapper(x),
1234- )
1351+ ):
1352+ inscribe(F)
12351353
12361354
1237-primitives = (
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_),
1281-
1282- FunctionWrapper(sharing),
1283- FunctionWrapper(warranty),
1284- )
1355+add_aliases(_dictionary)
12851356
12861357
1287-def initialize(dictionary=None):
1288- if dictionary is None:
1289- dictionary = {}
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)
1295- return dictionary
1358+DefinitionWrapper.add_definitions(definitions, _dictionary)
diff -r 6fa14b6647f4 -r 5bdb539d2d74 setup.py
--- a/setup.py Sat Apr 14 18:13:13 2018 -0700
+++ b/setup.py Mon Apr 16 12:27:52 2018 -0700
@@ -34,7 +34,7 @@
3434 behaviour of the original version written in C.'''),
3535 author='Simon Forman',
3636 author_email='forman.simon@gmail.com',
37- url='https://github.com/calroc/joypy',
37+ url='https://osdn.net/projects/joypy',
3838 packages=['joy', 'joy.utils'],
3939 classifiers=[
4040 'Development Status :: 3 - Alpha',
Show on old repository browser