Functions for working with the idealized calendar of Planet Xhilr
Révision | 746c818c56c8880b88dea46b9f10f414d5d2476b (tree) |
---|---|
l'heure | 2017-06-13 18:09:13 |
Auteur | Joel Matthew Rees <joel.rees@gmai...> |
Commiter | Joel Matthew Rees |
cycles and the digging into the actual calendar
@@ -23,17 +23,17 @@ | ||
23 | 23 | ( In gforth and most modern or emulated environments, ) |
24 | 24 | ( just paste it into the terminal of a running Forth session. ) |
25 | 25 | |
26 | -( Run it with | |
26 | +( Run it with ) | |
27 | 27 | |
28 | - 7 SHOWIDEALMONTHS | |
28 | +( 7 SHOWIDEALMONTHS ) | |
29 | 29 | |
30 | - for seven years, etc. ) | |
30 | +( for seven years, etc. ) | |
31 | 31 | |
32 | 32 | ( gforth can be found in the repositories at ) |
33 | 33 | ( <https://www.gnu.org/software/gforth/>. ) |
34 | 34 | |
35 | 35 | ( It can also be obtained as a package from most modern OS distributions ) |
36 | -( and in many applications stores (Android, yes, iOS, not yet for a while). ) | |
36 | +( and in many applications stores -- Android, yes, iOS, not yet for a while. ) | |
37 | 37 | ( Or, for MSWindows, you can get it through Cygwin: <https://www.cygwin.com/>. ) |
38 | 38 | |
39 | 39 | ( HTML documentation can be found on the web at ) |
@@ -41,7 +41,7 @@ | ||
41 | 41 | ( which includes a tutorial for experienced programmers. ) |
42 | 42 | |
43 | 43 | ( An easier tutorial for Forth can be found at ) |
44 | -( <https://www.forth.com/starting-forth/>.) | |
44 | +( <https://www.forth.com/starting-forth/>. ) | |
45 | 45 | |
46 | 46 | ( There is a newsgroup: comp.lang.forth, ) |
47 | 47 | ( which can be accessed from the web via, for example, Google newsgroups. ) |
@@ -154,19 +154,19 @@ SP@ SP@ - ABS CONSTANT CELLWIDTH | ||
154 | 154 | ; |
155 | 155 | |
156 | 156 | ( Left shifts can be done with addition. ) |
157 | -: SUM2* DUP + ; ( u1 --- u2 : Double the top cell. Not fastest, not too slow. ) | |
158 | -: SUMD2* 2DUP D+ ; ( ud1 --- ud2 : Double the top double cell. Not fastest. ) | |
159 | -: SLOWQ2* ( uq1 --- uq2 : Double the top double cell. Not fastest. ) | |
160 | - SUMD2* >R OVER 0< IF | |
157 | +: SUM-2* DUP + ; ( u1 --- u2 : Double the top cell. Not fastest, not too slow. ) | |
158 | +: SUM-D2* 2DUP D+ ; ( ud1 --- ud2 : Double the top double cell. Not fastest. ) | |
159 | +: SLOW-Q2* ( uq1 --- uq2 : Double the top double cell. Not fastest. ) | |
160 | + SUM-D2* >R OVER 0< IF | |
161 | 161 | 1 OR ( carry ) |
162 | 162 | THEN |
163 | 163 | >R |
164 | - SUMD2* | |
164 | + SUM-D2* | |
165 | 165 | R> R> ; |
166 | 166 | |
167 | 167 | : MY-BIT-COUNTER ( --- u ) ( Let's figure out how wide a CELL is. ) |
168 | 168 | 0. 1. BEGIN |
169 | - SUMD2* 2SWAP 1. D+ 2SWAP SP@ @ | |
169 | + SUM-D2* 2SWAP 1. D+ 2SWAP SP@ @ | |
170 | 170 | UNTIL 2DROP DROP ; |
171 | 171 | |
172 | 172 | MY-BIT-COUNTER CONSTANT CELLBITS |
@@ -341,12 +341,12 @@ CELLBITS CELLWIDTH /MOD CONSTANT BYTEBITS CONSTANT LEFTOVERBITS | ||
341 | 341 | ( Some dividends will overflow quotient, not valid for such cases. ) |
342 | 342 | ( Intended to be used for known products of two doubles. |
343 | 343 | ( AL AML AMH AH BL BH --- RL RH QL QH : unsigned quad by unsigned double yielding unsigned double ) |
344 | -: MOLASSES-UMD/MOD ( uqdividend uddivisor --- udremainder udquotient ) | |
344 | +: SLOW-UMD/MOD ( uqdividend uddivisor --- udremainder udquotient ) | |
345 | 345 | DUP 0= IF |
346 | 346 | DROP UQS/MOD 2DROP 0 ROT ROT ( Get divisor high word 0 easy case done quickly. ) |
347 | 347 | ELSE |
348 | 348 | 2ROT 2ROT ( Get the divisor out of the way, but accessible with pick. ) |
349 | - CELLBITS SUM2* 1+ >R ( Count ) | |
349 | + CELLBITS SUM-2* 1+ >R ( Count ) | |
350 | 350 | 0 >R ( Force flag ) |
351 | 351 | BEGIN ( BL BH AL AML AMH AH ) ( [ count force ] ) |
352 | 352 | 2DUP ( high double of dividend : BL BH AL AML AMH AH AMH AH ) |
@@ -361,7 +361,7 @@ CELLBITS CELLWIDTH /MOD CONSTANT BYTEBITS CONSTANT LEFTOVERBITS | ||
361 | 361 | ( BL BH AL AML bit ) ( [ count AH AMH ] ) |
362 | 362 | OVER >R ( Remember the carry from bottom to top half -- AML. ) |
363 | 363 | ( BL BH AL AML bit ) ( [ count AH AMH AML ] ) |
364 | - >R SUMD2* ( Save subtraction flag and shift the bottom half: AL AML. ) | |
364 | + >R SUM-D2* ( Save subtraction flag and shift the bottom half: AL AML. ) | |
365 | 365 | ( BL BH sAL rsAML ) ( [ count AH AMH AML bit ] ) |
366 | 366 | SWAP ( BL BH rsAML sAL ) ( [ count AH AMH AML bit ] ) |
367 | 367 | R> OR SWAP ( Record the subtraction in emptied bit of remainder. ) |
@@ -374,7 +374,7 @@ CELLBITS CELLWIDTH /MOD CONSTANT BYTEBITS CONSTANT LEFTOVERBITS | ||
374 | 374 | WHILE ( BL BH rsAL rsAML carry AMH AH ) ( [ newcount ] ) |
375 | 375 | DUP 0< >R ( Remember the high bit of the remainder, to force subtract. ) |
376 | 376 | ( BL BH rsAL rsAML carry AMH AH ) ( [ newcount newforce ] ) |
377 | - SUMD2* ( BL BH rsAL rsAML carry sAMH rsAH ) ( [ newcount newforce ] ) | |
377 | + SUM-D2* ( BL BH rsAL rsAML carry sAMH rsAH ) ( [ newcount newforce ] ) | |
378 | 378 | >R OR R> ( Shift the remainder, with the bit from the low half. ) |
379 | 379 | ( BL BH rsAL rsAML rsAMH rsAH ) ( [ newcount newforce ] ) |
380 | 380 | REPEAT ( BL BH rsAL rsAML rsAMH rsAH ) ( [ newcount newforce ] ) |
@@ -386,19 +386,6 @@ CELLBITS CELLWIDTH /MOD CONSTANT BYTEBITS CONSTANT LEFTOVERBITS | ||
386 | 386 | THEN |
387 | 387 | ; |
388 | 388 | |
389 | -( If your 16-bit Forth has UD/MOD, uncomment this and comment out the fake! *********** ) | |
390 | -( : JUD/MOD UD/MOD ; ( uqdividend uddivisor -- udremainder udquotient : If it exists. ) | |
391 | -( If UD/MOD does not exist and we are working on 32 or 64 bit, fake it. ) | |
392 | -( But make it safe! ) | |
393 | -: JUD/MOD ( uqdividend uddivisor -- udremainder udquotien : fake double division ) | |
394 | - | |
395 | - CELLWIDTH 4 < 0= IF | |
396 | - DROP >R 2DROP R> JM/MOD | |
397 | - ELSE ( Things get hairy! ) | |
398 | - | |
399 | - THEN ; | |
400 | -( In 32-bit or more, get rid of unneeded stuff and use single division. ) | |
401 | - | |
402 | 389 | |
403 | 390 | ( Make things easier to read. ) |
404 | 391 | ( Infix will be confusing here, too. ) |
@@ -410,6 +397,10 @@ CELLBITS CELLWIDTH /MOD CONSTANT BYTEBITS CONSTANT LEFTOVERBITS | ||
410 | 397 | : POINT 46 PRCH ; |
411 | 398 | : LPAREN 40 PRCH ; |
412 | 399 | : RPAREN 41 PRCH ; |
400 | +: VBAR 124 EMIT ; | |
401 | +: PLUS 43 EMIT ; | |
402 | +: DASH 45 EMIT ; | |
403 | +: STAR 42 EMIT ; | |
413 | 404 | |
414 | 405 | ( No trailing space. ) |
415 | 406 | : PSNUM ( number -- ) |
@@ -514,7 +505,7 @@ MDENOMINATOR 2 / CONSTANT MROUNDFUDGE | ||
514 | 505 | ELSE |
515 | 506 | MDENOMINATOR - ( Take one whole day from the fractional part. ) |
516 | 507 | ROT ROT 1 S>D D+ ( Restore stack and add the day carried in. ) |
517 | - ENDIF | |
508 | + THEN | |
518 | 509 | ; |
519 | 510 | |
520 | 511 | : PRMONTH ( fractional ddays -- fractional ddays ) |
@@ -534,7 +525,7 @@ MDENOMINATOR 2 / CONSTANT MROUNDFUDGE | ||
534 | 525 | I PSNUM COLON SPACE |
535 | 526 | SU1MONTH |
536 | 527 | 2DUP 5 DLC@ D- ( difference in days ) |
537 | - 4 LC@ ( push difference to ceiling ) IF 1. D+ ENDIF | |
528 | + 4 LC@ ( push difference to ceiling ) IF 1. D+ THEN | |
538 | 529 | 2DUP PSDNUM SPACE ( show theoretical days in month ) |
539 | 530 | 5 DLC@ D+ ( sum of days: adjusted difference plus daysmemory ) |
540 | 531 | LPAREN 2DUP PSDNUM COMMA SPACE |
@@ -566,14 +557,17 @@ LCYCLE LPLONGCYC + CONSTANT LPLONGCYC2 | ||
566 | 557 | ( Calendar system starts with year 0, not year 1. ) |
567 | 558 | ( Would need to check and adjust if the calendar started with year ) |
568 | 559 | : ISKIPYEAR ( year -- flag ) |
569 | - DUP MCYCLE MOD SKMEDIUMCYC = | |
560 | + DUP 0< IF | |
561 | + NEGATE 2LCYCLE MOD 2LCYCLE SWAP - | |
562 | + THEN | |
563 | + DUP MCYCLE MOD SKMEDIUMCYC = | |
570 | 564 | IF DROP -1 ( One specified extra skip year in medium cycle. ) |
571 | 565 | ELSE |
572 | 566 | DUP SCYCLE MOD DUP |
573 | 567 | SK1SHORTCYC = |
574 | 568 | SWAP SK2SHORTCYC = OR ( Two specified skip years in short cycle, but ... ) |
575 | 569 | SWAP LCYCLE MOD LPLONGCYC = 0= AND ( not the specified exception in the long cycle. ) |
576 | - ENDIF | |
570 | + THEN | |
577 | 571 | ; |
578 | 572 | |
579 | 573 |
@@ -585,9 +579,9 @@ LCYCLE LPLONGCYC + CONSTANT LPLONGCYC2 | ||
585 | 579 | ( but has no initial characteristic code or value in modern standards. ) |
586 | 580 | ( So. ) |
587 | 581 | ( On ancient Forths, VARIABLE wants an initial value. We give it a zero. ) |
582 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
588 | 583 | ( The zero stays around forever on modern Forths, or until you drop it. ) |
589 | 584 | 0 VARIABLE DIMARRAY ( Days In Months array ) |
590 | -( Modern Forths don't initialize, will leave 0 on stack. ) | |
591 | 585 | |
592 | 586 | CELLWIDTH NEGATE ALLOT ( Back up to store values. ) |
593 | 587 |
@@ -605,7 +599,15 @@ CELLWIDTH NEGATE ALLOT ( Back up to store values. ) | ||
605 | 599 | 29 C, |
606 | 600 | 0 , |
607 | 601 | |
602 | +( Accept one year year plus or minus, to help calendar on first and last month. ) | |
608 | 603 | : DIMONTH ( year month -- days ) |
604 | + DUP 0< IF | |
605 | + SWAP 1 - SWAP 12 + | |
606 | + ELSE | |
607 | + DUP MPYEAR < 0= IF | |
608 | + SWAP 1 + SWAP 12 - | |
609 | + THEN | |
610 | + THEN | |
609 | 611 | DUP 0 < 0= |
610 | 612 | OVER MPYEAR < AND 0= |
611 | 613 | IF |
@@ -615,7 +617,7 @@ CELLWIDTH NEGATE ALLOT ( Back up to store values. ) | ||
615 | 617 | SWAP SKMONTH = ( true if skip month ) |
616 | 618 | ROT ISKIPYEAR AND ( true if skip month of skip year ) |
617 | 619 | 1 AND - ( Subtrahend is 1 only if skip month of skip year. ) |
618 | - ENDIF | |
620 | + THEN | |
619 | 621 | ; |
620 | 622 | |
621 | 623 | : SH1YEAR ( year ddaysmemory fractional ddays -- year ddaysmemory fractional ddays ) |
@@ -711,7 +713,7 @@ CELLWIDTH NEGATE ALLOT ( Back up to store values. ) | ||
711 | 713 | ; |
712 | 714 | |
713 | 715 | ( Saturates on month > 12. Generally use to month 11. ) |
714 | -: DTM ( year month --- days ) ( Just the days from the beginning of the year. ) | |
716 | +: DTM ( uyear umonth --- days ) ( Just the days from the beginning of the year. ) | |
715 | 717 | DUP IF |
716 | 718 | 0 SWAP 0 DO |
717 | 719 | OVER I DIMONTH + |
@@ -723,15 +725,19 @@ CELLWIDTH NEGATE ALLOT ( Back up to store values. ) | ||
723 | 725 | |
724 | 726 | 0 VARIABLE CALENDAR-WIDTH |
725 | 727 | 80 CALENDAR-WIDTH ! |
728 | +( But we won't use this because we don't have real strings. ) | |
726 | 729 | |
730 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
727 | 731 | 0 VARIABLE DAYCOUNT |
728 | -0 DAYCOUNT ! 0 , ( Double variable, initialize cleared. Modern Forths leave a zero. ) | |
732 | +0 DAYCOUNT ! 0 , ( Double variable, initialize cleared. ) | |
729 | 733 | |
730 | 734 | |
731 | 735 | 0 CONSTANT WKDAYOFFSET ( Weekday corresponding to day zero of year zero. ) |
732 | -0 CONSTANT 1STDAYOFWEEK ( Weekday corresponding to first day of week. ) | |
736 | +0 VARIABLE 1STDAYOFWEEK ( Weekday corresponding to first day of week. ) | |
737 | +0 1STDAYOFWEEK ! | |
733 | 738 | |
734 | -0 VARIABLE DOWKSTATE ( Current day of week. Modern Forths leave a zero. ) | |
739 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
740 | +0 VARIABLE DOWKSTATE ( Current day of week. ) | |
735 | 741 | |
736 | 742 | 7 CONSTANT DPWK ( Days per week. ) |
737 | 743 |
@@ -752,9 +758,11 @@ RD2LCYCLE 16 * CONSTANT NUCYCLE ( numerator: 7760 ) | ||
752 | 758 | 0 CONSTANT SMOFFINT ( Slow moon offset at year 0 day 0, integer part. ) |
753 | 759 | 0 CONSTANT SMOFFFRAC10976 ( Fractional part. ) |
754 | 760 | |
755 | -0 VARIABLE SMSTATEINT ( Slow moon state integer part. Modern Forths leave a zero. ) | |
761 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
762 | +0 VARIABLE SMSTATEINT ( Slow moon state integer part. ) | |
756 | 763 | 0 SMSTATEINT ! 0 , ( Initialize cleared, make double variable. ) |
757 | -0 VARIABLE SMSTATEFRAC10976 ( Fractional part. Modern Forths leave a zero. ) | |
764 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
765 | +0 VARIABLE SMSTATEFRAC10976 ( Fractional part. ) | |
758 | 766 | 0 SMSTATEFRAC10976 ! 0 , ( Initialize cleared, make double variable. ) |
759 | 767 | |
760 | 768 |
@@ -769,20 +777,25 @@ RD2LCYCLE 16 * CONSTANT NUCYCLE ( numerator: 7760 ) | ||
769 | 777 | 0 CONSTANT FMOFFINT ( Fast moon offset at year 0 day 0, integer part. ) |
770 | 778 | 0 CONSTANT FMOFFFRAC10976 ( Fractional part. ) |
771 | 779 | |
772 | -0 VARIABLE FMSTATEINT ( Fast moon state integer part. Modern Forths leave a zero. ) | |
780 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
781 | +0 VARIABLE FMSTATEINT ( Fast moon state integer part. ) | |
773 | 782 | 0 FMSTATEINT ! 0 , ( Initialize cleared, make double variable. ) |
774 | -0 VARIABLE FMSTATEFRAC10976 ( Fractional part. Modern Forths leave a zero. ) | |
783 | +( Modern Forths initialize to 0, will leave the 0 given here on the stack. ) | |
784 | +0 VARIABLE FMSTATEFRAC10976 ( Fractional part. ) | |
775 | 785 | 0 FMSTATEFRAC10976 ! 0 , ( Initialize cleared, make double variable. ) |
776 | 786 | |
777 | 787 | |
778 | -: WSTYCYCLES ( year --- ) ( Start the weekday counter for the year, keep the days. ) | |
779 | - DTY 2DUP DAYCOUNT D! | |
788 | +( Start the weekday counter for the year and month, remember the days. ) | |
789 | +: WKSTCYCLES ( uyear umonth --- ) | |
790 | + OVER DTY | |
791 | + 2SWAP DTM 0 D+ | |
792 | + 2DUP DAYCOUNT D! | |
780 | 793 | WKDAYOFFSET 0 D- DPWK JM/MOD 2DROP DOWKSTATE ! |
781 | 794 | ; |
782 | 795 | |
783 | -: SSTYCYCLES ( ddays --- ) ( Start the slowmoon cycle counter for the year. ) | |
784 | - DECYCLE UDS* DROP SMPERIOD10976 DROP JM/MOD >R >R S>D R> R> ( 32-bit, 64-bit ) | |
785 | -( DECYCLE S>D UMD* SMPERIOD10976 UD/MOD ( 16-bit ) | |
796 | +( Start the slowmoon cycle counter by the day count. ) | |
797 | +: SLOMSTCYCLES ( ddays --- ) | |
798 | + DECYCLE S>D UMD* SMPERIOD10976 SLOW-UMD/MOD | |
786 | 799 | 2SWAP SMOFFFRAC10976 S>D D+ |
787 | 800 | 2DUP SMPERIOD10976 D< 0= IF |
788 | 801 | SMPERIOD10976 D- 2SWAP 1. D+ 2SWAP |
@@ -791,9 +804,9 @@ RD2LCYCLE 16 * CONSTANT NUCYCLE ( numerator: 7760 ) | ||
791 | 804 | SMOFFINT S>D D+ SMSTATEINT D! |
792 | 805 | ; |
793 | 806 | |
794 | -: FSTYCYCLES ( ddays --- ) ( Start the fastmoon cycle counter for the year. ) | |
795 | - DECYCLE UDS* DROP FMPERIOD10976 DROP JM/MOD >R >R S>D R> R> ( 32-bit, 64-bit ) | |
796 | -( DECYCLE S>D UMD* FMPERIOD10976 UD/MOD ( 16-bit ) | |
807 | +( Start the fastmoon cycle counter by the day count. ) | |
808 | +: FASMSTCYCLES ( ddays --- ) | |
809 | + DECYCLE S>D UMD* FMPERIOD10976 SLOW-UMD/MOD | |
797 | 810 | 2SWAP FMOFFFRAC10976 S>D D+ |
798 | 811 | 2DUP FMPERIOD10976 D< 0= IF |
799 | 812 | FMPERIOD10976 D- 2SWAP 1. D+ 2SWAP |
@@ -802,42 +815,26 @@ RD2LCYCLE 16 * CONSTANT NUCYCLE ( numerator: 7760 ) | ||
802 | 815 | FMOFFINT S>D D+ FMSTATEINT D! |
803 | 816 | ; |
804 | 817 | |
805 | -: STYCYCLES ( year --- ) ( Start the counters for the year. ) | |
806 | - WSTYCYCLES | |
807 | - DAYCOUNT D@ 2DUP SSTYCYCLES FSTYCYCLES | |
818 | +: STYCYCLES ( year month --- ) ( Start the counters for the year. ) | |
819 | + WKSTCYCLES | |
820 | + DAYCOUNT D@ 2DUP SLOMSTCYCLES FASMSTCYCLES | |
808 | 821 | ; |
809 | 822 | |
810 | -: STMCYCLES ( year month --- ) ( The year is started, start the month. ) | |
811 | - DTM 0 DAYCOUNT D@ D+ 2DUP DAYCOUNT ! | |
812 | - 2DUP DPWK JM/MOD 2DROP DOWKSTATE ! ( Overwrite the state, don't sum it. ) | |
813 | - | |
814 | -; | |
815 | - | |
816 | - | |
817 | - | |
818 | -: PRMONTH ( year month day --- ) | |
819 | - >R OVER STYCYCLES | |
820 | - | |
821 | -Have to adjust by defined 1st day of week. | |
822 | - | |
823 | - | |
824 | - | |
825 | - | |
826 | -( Lots -- 6? -- of 0s left behind on modern Forths. ) | |
823 | +( : TEST STYCYCLES DAYCOUNT D@ D. CR SMSTATEINT D@ D. CR SMSTATEFRAC10976 D@ D. CR ) | |
824 | +( FMSTATEINT D@ D. CR FMSTATEFRAC10976 D@ D. CR ; ) | |
827 | 825 | |
828 | 826 | |
829 | 827 | ( Ancient Forths do not have standard WORDs, ) |
830 | 828 | ( and that makes it hard to have portable arrays of strings for those Forths. ) |
831 | -: TPWDAY ( n --- ) ( TYPE the name of the day of the week. ) | |
829 | +: TPWDAY ( n --- ) ( TYPE the name of the day of the week, modulo. ) | |
830 | + DPWK MOD | |
832 | 831 | DUP 0 = IF ." Sunday " ELSE ( Fake case format to line the strings up. ) |
833 | 832 | DUP 1 = IF ." Moonsday" ELSE |
834 | 833 | DUP 2 = IF ." Aegisday" ELSE |
835 | - DUP 3 = IF ." Gefnday" ELSE | |
836 | - DUP 4 = IF ." Freyday" ELSE | |
837 | - DUP 5 = IF ." Tewesday" ELSE | |
838 | - DUP 6 = IF ." Vensday" ELSE ( DUP here allows final single DROP. ) | |
839 | - ." ??? " | |
840 | - THEN | |
834 | + DUP 3 = IF ." Gefnday " ELSE | |
835 | + DUP 4 = IF ." Freyday " ELSE | |
836 | + DUP 5 = IF ." Tewesday" ELSE ( DUP here allows final single DROP. ) | |
837 | + ." Vensday " | |
841 | 838 | THEN |
842 | 839 | THEN |
843 | 840 | THEN |
@@ -846,6 +843,8 @@ Have to adjust by defined 1st day of week. | ||
846 | 843 | THEN |
847 | 844 | DROP ; |
848 | 845 | |
846 | +8 CONSTANT DWIDTH | |
847 | + | |
849 | 848 | : TPMONTH ( n --- ) ( TYPE the name of the month. ) |
850 | 849 | ( DUP 6 < IF * Use this if the compile stack overflows. ) |
851 | 850 | DUP 0 = IF ." Time-division" ELSE ( Fake case format to line the strings up. ) |
@@ -863,7 +862,7 @@ Have to adjust by defined 1st day of week. | ||
863 | 862 | DUP 9 = IF ." Harvest " ELSE |
864 | 863 | DUP 10 = IF ." Gratitude " ELSE |
865 | 864 | DUP 11 = IF ." Winter-month" ELSE ( DUP here allows final single DROP. ) |
866 | - ." ???" | |
865 | + ." ??? " | |
867 | 866 | THEN |
868 | 867 | THEN |
869 | 868 | THEN |
@@ -880,6 +879,112 @@ Have to adjust by defined 1st day of week. | ||
880 | 879 | ( THEN ) |
881 | 880 | DROP ; |
882 | 881 | |
882 | +13 CONSTANT MWIDTH | |
883 | + | |
884 | +CALENDAR-WIDTH @ DPWK / 1 - CONSTANT DFIELD | |
885 | + | |
886 | +: WLINELENGTH CALENDAR-WIDTH @ DPWK / DPWK * ; | |
887 | + | |
888 | +: DASHES ( count --- ) ( EMIT a string of count DASHes. ) | |
889 | + DUP 0 > IF | |
890 | + 0 DO DASH LOOP | |
891 | + ELSE | |
892 | + DROP | |
893 | + THEN | |
894 | +; | |
895 | + | |
896 | +: HLINE ( --- ) | |
897 | + PLUS | |
898 | + DPWK 0 DO | |
899 | + DFIELD DASHES PLUS | |
900 | + LOOP | |
901 | + CR | |
902 | +; | |
903 | + | |
904 | +: SPLINE ( --- ) | |
905 | + VBAR | |
906 | + DPWK 0 DO | |
907 | + DFIELD SPACES VBAR | |
908 | + LOOP | |
909 | + CR | |
910 | +; | |
911 | + | |
912 | +: PWKDAYS ( --- ) ( Adjust by 1STDAYOFWEEK. ) | |
913 | + VBAR | |
914 | + DFIELD DWIDTH - 1 - 2 /MOD | |
915 | + SWAP OVER + | |
916 | + 1STDAYOFWEEK @ DUP DPWK + SWAP | |
917 | + DO | |
918 | + DUP SPACES | |
919 | + I TPWDAY | |
920 | + DUP SPACES OVER SPACES | |
921 | + VBAR | |
922 | + LOOP CR | |
923 | + DROP DROP | |
924 | +; | |
925 | + | |
926 | +: BOLD ( n1 n2 --- n1 n2 ) | |
927 | + 2DUP = IF STAR ELSE SPACE THEN ; | |
928 | + | |
929 | +: PDFIELD ( day today --- day today ) ( Print one numeric day field, emphasis on today. ) | |
930 | + DFIELD 4 - 2 /MOD SWAP ( day today half rem ) | |
931 | + OVER + ( day today half rem+half ) | |
932 | + SPACES >R ( day today ) ( [ half ] ) | |
933 | + BOLD OVER 2 .R BOLD ( day today ) ( [ half ] ) | |
934 | + R> SPACES | |
935 | + VBAR | |
936 | +; | |
937 | + | |
938 | +: DAYLINE ( rollover start today --- ) ( DPWK days from start, from 0 at rollove ) | |
939 | + >R ( rollover start ) ( [ today ] ) | |
940 | + VBAR | |
941 | + DPWK 0 DO | |
942 | + 2DUP > 0= IF DROP 0 THEN ( rollover day ) ( [ today ] ) | |
943 | + R> PDFIELD >R | |
944 | + 1+ | |
945 | + LOOP | |
946 | + R> DROP | |
947 | + DROP DROP | |
948 | +; | |
949 | + | |
950 | + | |
951 | +: CALMONTH ( year month day --- ) | |
952 | + CR | |
953 | + WLINELENGTH MWIDTH - 2 - 2 / SPACES | |
954 | + ROT DUP 4 .R SPACE | |
955 | + ROT DUP TPMONTH CR | |
956 | + HLINE | |
957 | + PWKDAYS | |
958 | + HLINE | |
959 | + SPLINE | |
960 | + ROT ROT ( Save day away. ) | |
961 | + 2DUP STYCYCLES | |
962 | + DOWKSTATE @ 1STDAYOFWEEK @ - DUP 0< IF DPWK + THEN | |
963 | + DUP ( Save back up count. ) | |
964 | + IF | |
965 | + back up phases of moons to beginning of week | |
966 | + >R 1 - DIMONTH ( Of previous month. ) | |
967 | + DUP R> - ( day rollover start ) | |
968 | + DAYLINE | |
969 | + print phases of moons | |
970 | + add dPWK to start | |
971 | + calculate rolloever of current month. | |
972 | + ELSE | |
973 | + drop DIMONTH ( Of current month. ) | |
974 | + set start to zero | |
975 | + THEN | |
976 | + BEGIN | |
977 | + | |
978 | + | |
979 | + pass rollover UNTIL | |
980 | + | |
981 | +; | |
982 | + | |
983 | + | |
984 | + | |
985 | + | |
986 | +( Lots -- 7? -- of 0s left behind on modern Forths. ) | |
987 | + | |
883 | 988 | |
884 | 989 | |
885 | 990 |