( Program by Prof. Ting) [NEEDS lib/enter.4th] VARIABLE JULIAN ( Julian date of 1st of a year, from Jan. 1, 1950) VARIABLE LEAP ( 1 for a leap year, 0 otherwise. ) 1461 CONSTANT 4YEARS ( number of days in 4 years ) : YEAR ( YEAR --, compute Julian date and leap year ) 1949 - 4YEARS 4 */MOD ( days since 1/1/1949 ) 365 - JULIAN ! ( 0 for 1/1/1950 ) 3 = ( modulus 3 for a leap year ) IF 1 LEAP ! ( leap year ) ELSE 0 LEAP ! ( normal year ) THEN ; : 1ST ( MONTH -- 1ST, 1st of a month from Jan. 1 ) DUP 1 = IF DROP 0 ( 0 for Jan. 1 ) ELSE DUP 2 = IF DROP 31 ( 31 for Feb. 1 ) ELSE DUP 3 = IF DROP 59 LEAP @ + ( 59/60 for Mar. 1 ) ELSE 4 - 30624 1000 */ 90 + LEAP @ + ( Apr. 1 to Dec. 1 ) THEN THEN THEN ; : DAY ( DD MM YYYY -- JULIAN-DAY ) YEAR ( Compute JULIAN and LEAP) 1ST + 1- ( add DD to 1st of the month ) JULIAN @ + ( add to Jan. 1 of the year ) ; : STARS 0 DO 42 EMIT LOOP ; ( form the boarder ) create MonthTable ," January " ," February " ," March " ," April " ," May " ," June " ," July " ," August " ," September" ," October " ," November " ," December " : header ( n -- ) ( print title bar ) cr cr 26 stars space 1- MonthTable + @c COUNT TYPE space 27 stars cr cr ." SUN MON TUE WED THU FRI SAT" cr cr ( print weekdays ) ; : BLANKS ( MONTH -- ) ( skip days not in this month ) 1ST JULIAN @ + ( Julian date of 1st of month ) 7 MOD 8 * SPACES ; ( skip colums if not Sunday ) : .DAYS ( MONTH -- ) ( print days in a month ) DUP 1ST ( days of 1st this month ) SWAP 1 + 1ST ( days of 1st next month ) OVER - 0 ( loop to print the days ) DO I OVER + JULIAN @ + 7 MOD ( which day in the week? ) 0= IF CR THEN ( start a new line if Sunday ) I 1 + 8 .R ( print day in 8 column field ) LOOP DROP ; ( discard 1st day in this month ) : MONTH ( N -- ) ( print a month calendar ) DUP HEADER DUP BLANKS ( print header ) .DAYS ; ( print days ) : CALENDAR ( YEAR --- ) ( print year calendar ) YEAR ( compute JULIAN and LEAP ) 13 1 DO I MONTH LOOP ( print 12 month calendars ) CR CR 64 STARS ; ( print last boarder ) : CHECKYEAR DUP 1950 < IF ." Wrong year" CR QUIT THEN ; : CHECKMONTH ( check month in range ) DUP 0< IF DROP 0 ELSE DUP 12 > IF DROP 0 THEN THEN ; : PROMPT ( ask for parameters ) ." Enter year : " ENTER CHECKYEAR ." Enter month: " ENTER CHECKMONTH DUP 0= IF DROP CALENDAR ELSE SWAP YEAR MONTH THEN CR ; PROMPT