Calendar - for "REAL" programmers: Difference between revisions
m
→{{header|Phix}}: use pygments
(Added Sidef) |
m (→{{header|Phix}}: use pygments) |
||
(75 intermediate revisions by 35 users not shown) | |||
Line 1:
[[Category:Handicap]]
{{task|Date and time}}
;Task:
Provide an algorithm as per the [[Calendar]] task, except the entire code for the algorithm must be presented ''entirely without lowercase''.
Also - as per many 1969 era [[wp:line printer#Paper (forms) handling|line printer]]s - format the calendar to nicely fill a page that is 132 characters wide.
Line 30 ⟶ 31:
FYI: a nice ASCII art file of Snoopy can be found at [http://www.textfiles.com/artscene/asciiart/cursepic.art textfiles.com]. Save with a .txt extension.
'''Trivia:''' The terms uppercase and lowercase date back to the early days of the mechanical printing press. Individual metal alloy casts of each needed letter, or punctuation symbol, were meticulously added to a press block, by hand, before rolling out copies of a page. These metal casts were stored and organized in wooden cases. The more often needed ''
<br><br>
=={{header|360 Assembly}}==
<!-- Calendar for real programmers -->
This is for real programmers who code only in assembler :). The code could have been run in april 1964, punched on
80-column cards, read on a card reader, and printed with a 132-column line printer on fan-folded paper with perforated edges.
<syntaxhighlight lang="360asm">* CALENDAR FOR REAL PROGRAMMERS 05/03/2017
CALENDAR CSECT
USING CALENDAR,R13 BASE REGISTER
B 72(R15) SKIP MY SAVEAREA
DC 17F'0' MY SAVEAREA
STM R14,R12,12(R13) SAVE CALLER'S REGISTERS
ST R13,4(R15) LINK BACKWARD
ST R15,8(R13) LINK FORWARD
LR R13,R15 SET ADDRESSABILITY
L R4,YEAR YEAR
SRDA R4,32 .
D R4,=F'4' YEAR//4
LTR R4,R4 IF YEAR//4=0
BNZ LYNOT
L R4,YEAR YEAR
SRDA R4,32 .
D R4,=F'100' YEAR//100
LTR R4,R4 IF YEAR//100=0
BNZ LY
L R4,YEAR YEAR
SRDA R4,32 .
D R4,=F'400' IF YEAR//400
LTR R4,R4 IF YEAR//400=0
BNZ LYNOT
LY MVC ML+2,=H'29' ML(2)=29 LEAPYEAR
LYNOT SR R10,R10 LTD1=0
LA R6,1 I=1
LOOPI1 C R6,=F'31' DO I=1 TO 31
BH ELOOPI1
XDECO R6,XDEC EDIT I
LA R14,TD1 TD1
AR R14,R10 TD1+LTD1
MVC 0(3,R14),XDEC+9 SUB(TD1,LTD1+1,3)=PIC(I,3)
LA R10,3(R10) LTD1+3
LA R6,1(R6) I=I+1
B LOOPI1
ELOOPI1 LA R6,1 I=1
LOOPI2 C R6,=F'12' DO I=1 TO 12
BH ELOOPI2
ST R6,M M=I
MVC D,=F'1' D=1
MVC YY,YEAR YY=YEAR
L R4,M M
C R4,=F'3' IF M<3
BNL GE3
L R2,M M
LA R2,12(R2) M+12
ST R2,M M=M+12
L R2,YY YY
BCTR R2,0 YY-1
ST R2,YY YY=YY-1
GE3 L R2,YY YY
LR R1,R2 YY
SRA R1,2 YY/4
AR R2,R1 YY+(YY/4)
L R4,YY YY
SRDA R4,32 .
D R4,=F'100' YY/100
SR R2,R5 YY+(YY/4)-(YY/100)
L R4,YY YY
SRDA R4,32 .
D R4,=F'400' YY/400
AR R2,R5 YY+(YY/4)-(YY/100)+(YY/400)
A R2,D R2=YY+(YY/4)-(YY/100)+(YY/400)+D
LA R5,153 153
M R4,M 153*M
LA R5,8(R5) 153*M+8
D R4,=F'5' (153*M+8)/5
AR R5,R2 ((153*M+8)/5+R2
LA R4,0 .
D R4,=F'7' R4=MOD(R5,7) 0=SUN 1=MON ... 6=SAT
LTR R4,R4 IF J=0
BNZ JNE0
LA R4,7 J=7
JNE0 BCTR R4,0 J-1
MH R4,=H'3' J*3
LR R10,R4 J1=J*3
LR R1,R6 I
SLA R1,1 *2
LH R11,ML-2(R1) ML(I)
MH R11,=H'3' J2=ML(I)*3
MVC TD2,BLANK TD2=' '
LA R4,TD1 @TD1
LR R5,R11 J2
LA R2,TD2 @TD2
AR R2,R10 @TD2+J1
LR R3,R5 J2
MVCL R2,R4 SUB(TD2,J1+1,J2)=SUB(TD1,1,J2)
LR R1,R6 I
MH R1,=H'144' *144
LA R14,DA-144(R1) @DA(I)
MVC 0(144,R14),TD2 DA(I)=TD2
LA R6,1(R6) I=I+1
B LOOPI2
ELOOPI2 XPRNT SNOOPY,132 PRINT SNOOPY
L R1,YEAR YEAR
XDECO R1,PG+56 EDIT YEAR
XPRNT PG,L'PG PRINT YEAR
MVC WDLINE,BLANK WDLINE=' '
LA R10,1 LWDLINE=1
LA R8,1 K=1
LOOPK3 C R8,=F'6' DO K=1 TO 6
BH ELOOPK3
LA R4,WDLINE @WDLINE
AR R4,R10 +LWDLINE
MVC 0(20,R4),WDNA SUB(WDLINE,LWDLINE+1,20)=WDNA
LA R10,20(R10) LWDLINE=LWDLINE+20
C R8,=F'6' IF K<6
BNL ITERK3
LA R10,2(R10) LWDLINE=LWDLINE+2
ITERK3 LA R8,1(R8) K=K+1
B LOOPK3
ELOOPK3 LA R6,1 I=1
LOOPI4 C R6,=F'12' DO I=1 TO 12 BY 6
BH ELOOPI4
MVC MOLINE,BLANK MOLINE=' '
LA R10,6 LMOLINE=6
LR R8,R6 K=I
LOOPK4 LA R2,5(R6) I+5
CR R8,R2 DO K=I TO I+5
BH ELOOPK4
LR R1,R8 K
MH R1,=H'10' *10
LA R3,MO-10(R1) MO(K)
LA R4,MOLINE @MOLINE
AR R4,R10 +LMOLINE
MVC 0(10,R4),0(R3) SUB(MOLINE,LMOLINE+1,10)=MO(K)
LA R10,22(R10) LMOLINE=LMOLINE+22
LA R8,1(R8) K=K+1
B LOOPK4
ELOOPK4 XPRNT MOLINE,L'MOLINE PRINT MONTHS
XPRNT WDLINE,L'WDLINE PRINT DAYS OF WEEK
LA R7,1 J=1
LOOPJ4 C R7,=F'106' DO J=1 TO 106 BY 21
BH ELOOPJ4
MVC PG,BLANK CLEAR BUFFER
LA R9,PG PGI=0
LR R8,R6 K=I
LOOPK5 LA R2,5(R6) I+5
CR R8,R2 DO K=I TO I+5
BH ELOOPK5
LR R1,R8 K
MH R1,=H'144' *144
LA R4,DA-144(R1) DA(K)
BCTR R4,0 -1
AR R4,R7 +J
MVC 0(21,R9),0(R4) SUBSTR(DA(K),J,21)
LA R9,22(R9) PGI=PGI+22
LA R8,1(R8) K=K+1
B LOOPK5
ELOOPK5 XPRNT PG,L'PG PRINT BUFFER
LA R7,21(R7) J=J+21
B LOOPJ4
ELOOPJ4 LA R6,6(R6) I=I+6
B LOOPI4
ELOOPI4 L R13,4(0,R13) RESTORE PREVIOUS SAVEAREA POINTER
LM R14,R12,12(R13) RESTORE CALLER'S REGISTERS
XR R15,R15 SET RETURN CODE TO 0
BR R14 RETURN TO CALLER
SNOOPY DC CL57' ',CL18'INSERT SNOOPY HERE',CL57' '
YEAR DC F'1969' <== 1969
MO DC CL10' JANUARY ',CL10' FEBRUARY ',CL10' MARCH '
DC CL10' APRIL ',CL10' MAY ',CL10' JUNE '
DC CL10' JULY ',CL10' AUGUST ',CL10'SEPTEMBER '
DC CL10' OCTOBER ',CL10' NOVEMBER ',CL10' DECEMBER '
ML DC H'31',H'28',H'31',H'30',H'31',H'30'
DC H'31',H'31',H'30',H'31',H'30',H'31'
WDNA DC CL20'MO TU WE TH FR SA SU'
M DS F
D DS F
YY DS F
TD1 DS CL93
TD2 DS CL144
MOLINE DS CL132
WDLINE DS CL132
PG DC CL132' ' BUFFER FOR THE LINE PRINTER
XDEC DS CL12
BLANK DC CL144' '
DA DS 12CL144
YREGS
END CALENDAR</syntaxhighlight>
{{out}}
<pre> INSERT SNOOPY HERE
1969
JANUARY FEBRUARY MARCH APRIL MAY JUNE
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2 1 2 3 4 5 6 1 2 3 4 1
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
31 30
JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 1 2 1 2 3 4 5 6 7
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Ada}}==
Line 38 ⟶ 242:
Instead of doing that, the implementation below reuses the package "PRINTABLE_CALENDAR" (same as "Printable_Calendar" or "printable_calendar") from [[Calendar#Ada|the calendar task]]:
<
PROCEDURE REAL_CAL IS
Line 58 ⟶ 262:
C.NEW_LINE;
C.PRINT(1969, "NINETEEN-SIXTY-NINE");
END REAL_CAL;</
{{out}}
Line 83 ⟶ 287:
To change the output to 80-character devices, replace "INIT_132" by "INIT_80".
=={{header|ALGOL 68}}==
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
Line 91 ⟶ 294:
Note: to run this code with [[ALGOL 68G]] you need to use the '''--quote-stropping''' option.
<
'PROC' PRINT CALENDAR = ('INT' YEAR, PAGE WIDTH)'VOID': 'BEGIN'
Line 198 ⟶ 401:
LINE PRINTER WIDTH = 132; # AS AT 1969! #
PRINT CALENDAR(MANKIND STEPPED ON THE MOON, LINE PRINTER WIDTH)
'END'</
{{out}}
<pre>
Line 221 ⟶ 424:
31 30
</pre>
=={{header|AutoHotkey}}==
<
LASTDAY := [], DAY := []
TITLES =
Line 261 ⟶ 463:
STRINGREPLACE, RES, RES,%A_SPACE%0,%A_SPACE%%A_SPACE%, ALL
RETURN RES
}</
Examples:<
GUI, FONT,S8, COURIER
GUI, ADD, EDIT, VYR W40 R1 LIMIT4 NUMBER, 1969
Line 277 ⟶ 479:
GUICLOSE:
EXITAPP
RETURN</
{{out}}
<pre> 1969
Line 316 ⟶ 518:
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
</pre>
=={{header|BASIC}}==
==={{header|BaCon}}===
Choosing 132 character output. Same as the "Calendar" from [[Calendar#BaCon|the calendar task]] but using all capitals:
<syntaxhighlight lang="freebasic">DECLARE MON$[] = { "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER" }
DECLARE MON[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
Y$ = "1969"
' Leap year
INCR MON[1], IIF(MOD(VAL(Y$), 4) = 0 OR MOD(VAL(Y$), 100) = 0 AND MOD(VAL(Y$), 400) <> 0, 1, 0)
PRINT ALIGN$("[SNOOPY HERE]", 132, 2)
PRINT ALIGN$(Y$, 132, 2)
FOR NR = 0 TO 11
ROW = 3
GOTOXY 1+(NR %6)*22, ROW+(NR/6)*9
PRINT ALIGN$(MON$[NR], 21, 2);
INCR ROW
GOTOXY 1+(NR %6)*22, ROW+(NR/6)*9
PRINT ALIGN$("MO TU WE TH FR SA SU", 21, 2);
INCR ROW
' Each day
FOR D = 1 TO MON[NR]
' Zeller
J = VAL(LEFT$(Y$, 2))
K = VAL(MID$(Y$, 3, 2))
M = NR+1
IF NR < 2 THEN
INCR M, 12
DECR K
END IF
H = (D + ((M+1)*26)/10 + K + (K/4) + (J/4) + 5*J)
DAYNR = MOD(H, 7) - 2
IF DAYNR < 0 THEN INCR DAYNR, 7
IF DAYNR = 0 AND D > 1 THEN INCR ROW
GOTOXY 1+(NR %6)*22+DAYNR*3, ROW+(NR/6)*9
PRINT D;
NEXT
NEXT</syntaxhighlight>
{{out}}
<pre> [SNOOPY HERE]
1969
JANUARY FEBRUARY MARCH APRIL MAY JUNE
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2 1 2 3 4 5 6 1 2 3 4 1
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
31 30
JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 1 2 1 2 3 4 5 6 7
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<
YEAR = 1969
Line 363 ⟶ 622:
DEF FNDIM(M%,Y%)
CASE M% OF
WHEN 2: = 28
WHEN 4,6,9,11: = 30
OTHERWISE = 31
ENDCASE</
{{out}}
<pre>
Line 389 ⟶ 648:
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
31 30</pre>
=={{header|C}}==
<b>Note:</b> Historically, some UNIX systems were connected to upper-case only terminals, and users of those systems needed to write C programs. One could configure the terminal using the "stty" command, setting the olcuc and iuclc options to translate uppercase to lowercase on input, and convert lowercase to uppercase on output (although typically the setting was applied by the "getty" program so that logging in would be possible).
So the text that was actually saved in the C source code would be lowercase, but it would appear on the terminal as uppercase.
<br>
This would also apply to any other language source or document.
<br>
<br>
Modern versions of Linux and MacOS have preserved this feature.
<br>
<br>
However, the following is an actual upper-case only version of the C Calendar task.
It relies on the ability of most C compilers to allow #defines to be specified on the command line and also declares the putchar function to avoid needing any #includes (neither #define nor #include could be specified in upper-case without a non-standard pre-processor).
<br>
The program can be compiled with the following (substitute the name of your compiler for tcc):
<pre>
tcc -DSTRUCT=struct -DCONST=const -DINT=int -DCHAR=char -DVOID=void -DMAIN=main -DIF=if -DELSE=else -DWHILE=while -DFOR=for -DDO=do -DBREAK=break -DRETURN=return -DPUTCHAR=putchar UCCALENDAR.c
</pre>
<syntaxhighlight lang="c">/* UPPER CASE ONLY VERSION OF THE ORIGINAL CALENDAR.C, CHANGES MOSTLY TO AVOID NEEDING #INCLUDES */
/* ERROR MESSAGES GO TO STDOUT TO SLIGHTLY SIMPLIFY THE I/O HANDLING */
/* WHEN COMPILING THIS, THE COMMAND LINE SHOULD SPECIFY -D OPTIONS FOR THE FOLLOWING WORDS: */
/* STRUCT, VOID, INT, CHAR, CONST, MAIN, IF, ELSE, WHILE, FOR, DO, BREAK, RETURN, PUTCHAR */
/* THE VALUE OF EACH MACRO SHOULD BE THE WORD IN LOWER-CASE */
INT PUTCHAR(INT);
INT WIDTH = 80, YEAR = 1969;
INT COLS, LEAD, GAP;
CONST CHAR *WDAYS[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
STRUCT MONTHS {
CONST CHAR *NAME;
INT DAYS, START_WDAY, AT;
} MONTHS[12] = {
{ "JANUARY", 31, 0, 0 },
{ "FEBRUARY", 28, 0, 0 },
{ "MARCH", 31, 0, 0 },
{ "APRIL", 30, 0, 0 },
{ "MAY", 31, 0, 0 },
{ "JUNE", 30, 0, 0 },
{ "JULY", 31, 0, 0 },
{ "AUGUST", 31, 0, 0 },
{ "SEPTEMBER", 30, 0, 0 },
{ "OCTOBER", 31, 0, 0 },
{ "NOVEMBER", 30, 0, 0 },
{ "DECEMBER", 31, 0, 0 }
};
VOID SPACE(INT N) { WHILE (N-- > 0) PUTCHAR(' '); }
VOID PRINT(CONST CHAR * S){ WHILE (*S != '\0') { PUTCHAR(*S++); } }
INT STRLEN(CONST CHAR * S)
{
INT L = 0;
WHILE (*S++ != '\0') { L ++; };
RETURN L;
}
INT ATOI(CONST CHAR * S)
{
INT I = 0;
INT SIGN = 1;
CHAR C;
WHILE ((C = *S++) != '\0') {
IF (C == '-')
SIGN *= -1;
ELSE {
I *= 10;
I += (C - '0');
}
}
RETURN I * SIGN;
}
VOID INIT_MONTHS(VOID)
{
INT I;
IF ((!(YEAR % 4) && (YEAR % 100)) || !(YEAR % 400))
MONTHS[1].DAYS = 29;
YEAR--;
MONTHS[0].START_WDAY
= (YEAR * 365 + YEAR/4 - YEAR/100 + YEAR/400 + 1) % 7;
FOR (I = 1; I < 12; I++)
MONTHS[I].START_WDAY =
(MONTHS[I-1].START_WDAY + MONTHS[I-1].DAYS) % 7;
COLS = (WIDTH + 2) / 22;
WHILE (12 % COLS) COLS--;
GAP = COLS - 1 ? (WIDTH - 20 * COLS) / (COLS - 1) : 0;
IF (GAP > 4) GAP = 4;
LEAD = (WIDTH - (20 + GAP) * COLS + GAP + 1) / 2;
YEAR++;
}
VOID PRINT_ROW(INT ROW)
{
INT C, I, FROM = ROW * COLS, TO = FROM + COLS;
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
I = STRLEN(MONTHS[C].NAME);
SPACE((20 - I)/2);
PRINT(MONTHS[C].NAME);
SPACE(20 - I - (20 - I)/2 + ((C == TO - 1) ? 0 : GAP));
}
PUTCHAR('\012');
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
FOR (I = 0; I < 7; I++) {
PRINT(WDAYS[I]);
PRINT(I == 6 ? "" : " ");
}
IF (C < TO - 1) SPACE(GAP);
ELSE PUTCHAR('\012');
}
WHILE (1) {
FOR (C = FROM; C < TO; C++)
IF (MONTHS[C].AT < MONTHS[C].DAYS) BREAK;
IF (C == TO) BREAK;
SPACE(LEAD);
FOR (C = FROM; C < TO; C++) {
FOR (I = 0; I < MONTHS[C].START_WDAY; I++) SPACE(3);
WHILE(I++ < 7 && MONTHS[C].AT < MONTHS[C].DAYS) {
INT MM = ++MONTHS[C].AT;
PUTCHAR((MM < 10) ? ' ' : '0' + (MM /10));
PUTCHAR('0' + (MM %10));
IF (I < 7 || C < TO - 1) PUTCHAR(' ');
}
WHILE (I++ <= 7 && C < TO - 1) SPACE(3);
IF (C < TO - 1) SPACE(GAP - 1);
MONTHS[C].START_WDAY = 0;
}
PUTCHAR('\012');
}
PUTCHAR('\012');
}
VOID PRINT_YEAR(VOID)
{
INT Y = YEAR;
INT ROW;
CHAR BUF[32];
CHAR * B = &(BUF[31]);
*B-- = '\0';
DO {
*B-- = '0' + (Y % 10);
Y /= 10;
} WHILE (Y > 0);
B++;
SPACE((WIDTH - STRLEN(B)) / 2);
PRINT(B);PUTCHAR('\012');PUTCHAR('\012');
FOR (ROW = 0; ROW * COLS < 12; ROW++)
PRINT_ROW(ROW);
}
INT MAIN(INT C, CHAR **V)
{
INT I, YEAR_SET = 0, RESULT = 0;
FOR (I = 1; I < C && RESULT == 0; I++) {
IF (V[I][0] == '-' && V[I][1] == 'W' && V[I][2] == '\0') {
IF (++I == C || (WIDTH = ATOI(V[I])) < 20)
RESULT = 1;
} ELSE IF (!YEAR_SET) {
YEAR = ATOI(V[I]);
IF (YEAR <= 0)
YEAR = 1969;
YEAR_SET = 1;
} ELSE
RESULT = 1;
}
IF (RESULT == 0) {
INIT_MONTHS();
PRINT_YEAR();
} ELSE {
PRINT("BAD ARGS\012USAGE: ");
PRINT(V[0]);
PRINT(" YEAR [-W WIDTH (>= 20)]\012");
}
RETURN RESULT;
}</syntaxhighlight>
=={{header|COBOL}}==
Although it seems to be missing the pinup of Snoopy, see [[Calendar#COBOL|COBOL Calendar task entry]]
where the code, and output, is already an example of a "REAL programmer" calendar; even down to the 6 character, all uppercase, program name ''CALEND''.
=={{header|Common Lisp}}==
<
(DEFPARAMETER *DAY-ROW* "SU MO TU WE TH FR SA")
Line 469 ⟶ 910:
(LAMBDA (&REST HEADS)
(FORMAT T FORMAT-STRING HEADS))
ROW))))</
{{out}}
<pre>CL-USER> (PRINT-CALENDAR 1969)
Line 508 ⟶ 949:
30
NIL</pre>
=={{header|D}}==
D keywords are lower case, so this silly solution uses the whole Calendar Task code, with small changes and all in upper case, in a text file named "CALENDAR":
Line 565 ⟶ 1,005:
Then in another source code file there is a little loader, that imports it and mixes-in it (for safety this program must be compiled with <code>-Jsomepath</code>):
<
{{out}}
<pre> [Snoopy Picture]
Line 605 ⟶ 1,045:
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30 </pre>
=={{header|Elena}}==
ELENA 6.x :
<syntaxhighlight lang="elena">import system'text;
import system'routines;
import system'calendar;
import extensions;
import extensions'routines;
const MonthNames = new string[]{"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"};
const DayNames = new string[]{"MO", "TU", "WE", "TH", "FR", "SA", "SU"};
class CalendarMonthPrinter
{
Date _date;
TextBuilder _line;
int _month;
int _year;
Reference<int> _row;
constructor(year, month)
{
_month := month;
_year := year;
_line := new TextBuilder();
_row := 0;
}
writeTitle()
{
_row.Value := 0;
_date := Date.new(_year, _month, 1);
DayNames.forEach::(name)
{ _line.print(" ",name) }
}
writeLine()
{
_line.clear();
if (_date.Month == _month)
{
var dw := _date.DayOfWeek;
_line.writeCopies(" ",_date.DayOfWeek == 0 ? 6 : (_date.DayOfWeek - 1));
_line.writePaddingLeft(_date.Day.toPrintable(), $32, 3);
_date := _date.addDays(1)
}
until(_date.Month != _month || _date.DayOfWeek == 1)
};
int length := _line.Length;
if (length < 21)
{ _line.writeCopies(" ", 21 - length) };
_row.append(1)
}
indexer() = new Indexer
bool Available
if (index <= _row)
{ self.writeTitle() };
{ self.writeLine() }
}
}
appendIndex(int index)
{
this self.Index := _row.Value + index
}
get int Length() { ^ 7 }
get Value()
set Value(o) { NotSupportedException.raise() }
};
}
{
output.writeLine();
output.writePadding(_year.toPrintable(), $32, _rowLength * 25);
new CalendarMonthPrinter(_year, i * _rowLength + j + 1)));
var r
{
month.printTitleTo(output);
output.write(" ")
};
output.writeLine();
ParallelEnumerator.new(row).forEach::(line)
output.writeLine()
}
}
}
}
{
}</syntaxhighlight>
{{out}}
<pre>
Line 791 ⟶ 1,246:
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Forth}}==
<syntaxhighlight lang="forth">
: WEEKDAY ( D M Y -- U )
OVER 3 < IF SWAP 12 + SWAP 1- THEN
DUP 4 / OVER 100 / - OVER 400 / + + SWAP 1+ 13 * 5 / + + 2 - 7 MOD ;
: MDAYS ( M Y -- MSIZE MDAY )
OVER 12 = IF 31 1 2SWAP WEEKDAY NEGATE EXIT THEN
2>R 1 2R@ WEEKDAY 1 2R> SWAP 1+ SWAP WEEKDAY OVER -
7 + 7 MOD 28 + SWAP NEGATE ;
: .WEEK ( MSIZE MDAY -- MSIZE MDAY' )
7 0 DO DUP 0< IF 1+ 3 SPACES ELSE
2DUP > IF 1+ DUP 2 .R SPACE ELSE 3 SPACES THEN THEN LOOP ;
: .3MONTHS ( Y M -- )
3 0 DO ." MO TU WE TH FR SA SU " LOOP CR
3 OVER + SWAP DO I OVER MDAYS ROT LOOP DROP
6 0 DO 2ROT .WEEK 2 SPACES 2ROT .WEEK 2 SPACES 2ROT .WEEK CR LOOP
2DROP 2DROP 2DROP ;
: CAL ( Y -- )
30 SPACES ." [SNOOPY]" CR
32 SPACES DUP . CR
." JANUARY FEBRUARY MARCH" CR
DUP 1 .3MONTHS
." APRIL MAY JUNE" CR
DUP 4 .3MONTHS
." JULY AUGUST SEPTEMBER" CR
DUP 7 .3MONTHS
." OCTOBER NOVEMBER DECEMBER" CR
10 .3MONTHS ;
1969 CAL
</syntaxhighlight>
{{out}}
<pre>
[SNOOPY]
1969
JANUARY FEBRUARY MARCH
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30
31
APRIL MAY JUNE
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 4 1
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
30
JULY AUGUST SEPTEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28
28 29 30 31 25 26 27 28 29 30 31 29 30
OCTOBER NOVEMBER DECEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2 3 4 5 6 7
6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Fortran}}==
Alas, the header "FORTRAN" is not recognised - REAL programmers were absent that day? Even upon the apperance of lower case, I have preferred to use shouting for programme source, and normal upper/lower case for commentary. Aside from petty details such as 1 and l being nowhere as distinct as 1 and L, this allows the two sorts of blather to be identifiably different without ratiocination as the hours drag past. Further, the names of variables can easily be distinguished from the same word in discussion, as in ... the text in TEXT will be printed as the subtitle to the text in TITLE ... Anyway, in the spirit of old, herewith the source without tedious commentary:
<syntaxhighlight lang="fortran">
MODULE DATEGNASH
Line 970 ⟶ 1,495:
END DO
END
</syntaxhighlight>
And for output, the wide form:
Line 992 ⟶ 1,517:
31 30
</pre>
Actual lineprinters offer the opportunity of overprinting lines
=={{header|FreeBASIC}}==
<
' COMPILE WITH: FBC -S CONSOLE
Line 1,090 ⟶ 1,617:
PRINT : PRINT "HIT ANY KEY TO END PROGRAM"
SLEEP
END</
{{out}}
<pre> INSERT YOUR SNOOPY PICTURE HERE
Line 1,112 ⟶ 1,639:
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31 </pre>
=={{header|FutureBasic}}==
REAL PROGRAMMERS USE THE COMMAND LINE. (ALL UPPERCASE...UGH! =:^0 )
<syntaxhighlight lang="futurebasic">
INCLUDE "NSLOG.INCL"
LOCAL FN RUNTERMINALCOMMAND( CMD AS CFSTRINGREF ) AS CFSTRINGREF
CFSTRINGREF OUTPUTSTR = NULL
TASKREF TASK = FN TASKINIT
TASKSETEXECUTABLEURL( TASK, FN URLFILEURLWITHPATH( FN STRINGLOWERCASESTRING( @"/BIN/ZSH" ) ) )
CFSTRINGREF CMDSTR = FN STRINGWITHFORMAT( @"%@", FN STRINGLOWERCASESTRING( CMD ) )
CFARRAYREF ARGS = FN ARRAYWITHOBJECTS( FN STRINGLOWERCASESTRING( @"-C" ), CMDSTR, NULL )
TASKSETARGUMENTS( TASK, ARGS )
PIPEREF P = FN PIPEINIT
TASKSETSTANDARDOUTPUT( TASK, P )
TASKSETSTANDARDERROR( TASK, P )
FILEHANDLEREF FH = FN PIPEFILEHANDLEFORREADING( P )
FN TASKLAUNCH( TASK, NULL )
TASKWAITUNTILEXIT( TASK )
ERRORREF ERR
CFDATAREF DTA = FN FILEHANDLEREADDATATOENDOFFILE( FH, @ERR )
IF ERR THEN NSLOG( @"%@", FN ERRORLOCALIZEDDESCRIPTION( ERR ) ) : EXIT FN
OUTPUTSTR = FN STRINGWITHDATA( DTA, NSUTF8STRINGENCODING )
OUTPUTSTR = FN STRINGUPPERCASESTRING( OUTPUTSTR )
END FN = OUTPUTSTR
VOID LOCAL FN BUILDSNOOPYCALENDAR
CFSTRINGREF CALSTR = FN STRINGWITHFORMAT( FN STRINGLOWERCASESTRING( @"\n%37S\n\n%@" ), FN STRINGUTF8STRING( @"[SNOOPY HERE]" ), FN RUNTERMINALCOMMAND( FN STRINGLOWERCASESTRING( @"CAL 1969" ) ) )
NSLOG( @"%@", CALSTR )
END FN
FN BUILDSNOOPYCALENDAR
HANDLEEVENTS
</syntaxhighlight>
{{output}}
<pre style="font-size: 12px">
[SNOOPY HERE]
1969
JANUARY FEBRUARY MARCH
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8
12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15
19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22
26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29
30 31
APRIL MAY JUNE
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
27 28 29 30 25 26 27 28 29 30 31 29 30
JULY AUGUST SEPTEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 1 2 3 4 5 6
6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13
13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30
31
OCTOBER NOVEMBER DECEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1 2 3 4 5 6
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
</pre>
=={{header|Go}}==
Go is case-sensitive: all its keywords and certain other identifiers/verbs are lower case and imported functions etc. are title case. Consequently, it is impossible to run an upper case version of the Calendar task program as it stands. So what I've done instead is to follow the approach of the Kotlin entry:
1. Saved the Calendar program, after conversion to upper case to a text file called realcal_UC.txt.
2. Written another program called realcal.go which takes realcalc_UC.txt as input, outputs a runnable program called realcal_NC.go to disk, runs it and prints the output to the terminal (Ubuntu 16.04 being used). This program only makes the minimum changes to realcal_UC.txt to enable it to run. Everything else is left as upper case even though this is at odds with the usual Go naming conventions.
This is realcal_UC.txt:
<syntaxhighlight lang="go">PACKAGE MAIN
IMPORT (
"FMT"
"TIME"
)
CONST PAGEWIDTH = 80
FUNC MAIN() {
PRINTCAL(1969)
}
FUNC PRINTCAL(YEAR INT) {
THISDATE := TIME.DATE(YEAR, 1, 1, 1, 1, 1, 1, TIME.UTC)
VAR (
DAYARR [12][7][6]INT // MONTH, WEEKDAY, WEEK
MONTH, LASTMONTH TIME.MONTH
WEEKINMONTH, DAYINMONTH INT
)
FOR THISDATE.YEAR() == YEAR {
IF MONTH = THISDATE.MONTH(); MONTH != LASTMONTH {
WEEKINMONTH = 0
DAYINMONTH = 1
}
WEEKDAY := THISDATE.WEEKDAY()
IF WEEKDAY == 0 && DAYINMONTH > 1 {
WEEKINMONTH++
}
DAYARR[INT(MONTH)-1][WEEKDAY][WEEKINMONTH] = THISDATE.DAY()
LASTMONTH = MONTH
DAYINMONTH++
THISDATE = THISDATE.ADD(TIME.HOUR * 24)
}
CENTRE := FMT.SPRINTF("%D", PAGEWIDTH/2)
FMT.PRINTF("%"+CENTRE+"S\N\N", "[SNOOPY]")
CENTRE = FMT.SPRINTF("%D", PAGEWIDTH/2-2)
FMT.PRINTF("%"+CENTRE+"D\N\N", YEAR)
MONTHS := [12]STRING{
" JANUARY ", " FEBRUARY", " MARCH ", " APRIL ",
" MAY ", " JUNE ", " JULY ", " AUGUST ",
"SEPTEMBER", " OCTOBER ", " NOVEMBER", " DECEMBER"}
DAYS := [7]STRING{"SU", "MO", "TU", "WE", "TH", "FR", "SA"}
FOR QTR := 0; QTR < 4; QTR++ {
FOR MONTHINQTR := 0; MONTHINQTR < 3; MONTHINQTR++ { // MONTH NAMES
FMT.PRINTF(" %S ", MONTHS[QTR*3+MONTHINQTR])
}
FMT.PRINTLN()
FOR MONTHINQTR := 0; MONTHINQTR < 3; MONTHINQTR++ { // DAY NAMES
FOR DAY := 0; DAY < 7; DAY++ {
FMT.PRINTF(" %S", DAYS[DAY])
}
FMT.PRINTF(" ")
}
FMT.PRINTLN()
FOR WEEKINMONTH = 0; WEEKINMONTH < 6; WEEKINMONTH++ {
FOR MONTHINQTR := 0; MONTHINQTR < 3; MONTHINQTR++ {
FOR DAY := 0; DAY < 7; DAY++ {
IF DAYARR[QTR*3+MONTHINQTR][DAY][WEEKINMONTH] == 0 {
FMT.PRINTF(" ")
} ELSE {
FMT.PRINTF("%3D", DAYARR[QTR*3+MONTHINQTR][DAY][WEEKINMONTH])
}
}
FMT.PRINTF(" ")
}
FMT.PRINTLN()
}
FMT.PRINTLN()
}
}</syntaxhighlight>
and this is realcal.go:
<syntaxhighlight lang="go">package main
import (
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
)
func check(err error) {
if err != nil {
log.Fatal(err)
}
}
func main() {
lower := []string{
"const ", "else ", "for ", "func ", "if ", "import ", "int ", "package ", "string ", "var ",
" int", "int(", "string{", " main", "main(", "fmt", "time", "%d", "%s", "%3d", `d\n\n`, `s\n\n`,
}
title := []string{
".add", ".date", ".day", ".hour", ".month", ".printf", ".println", ".sprintf", ".weekday", ".year",
}
code, err := ioutil.ReadFile("realcal_UC.txt")
check(err)
text := string(code)
for _, lwr := range lower {
text = strings.Replace(text, strings.ToUpper(lwr), lwr, -1)
}
for _, ttl := range title {
text = strings.Replace(text, strings.ToUpper(ttl), "."+strings.Title(ttl[1:]), -1)
}
err = ioutil.WriteFile("realcal_NC.go", []byte(text), 0666)
check(err)
cmd := exec.Command("go", "run", "realcal_NC.go")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
check(cmd.Run())
}</syntaxhighlight>
which produces (as expected) this output:
<pre>
[SNOOPY]
1969
JANUARY FEBRUARY MARCH
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8
12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15
19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22
26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29
30 31
APRIL MAY JUNE
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
27 28 29 30 25 26 27 28 29 30 31 29 30
JULY AUGUST SEPTEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 1 2 3 4 5 6
6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13
13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30
31
OCTOBER NOVEMBER DECEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1 2 3 4 5 6
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
</pre>
=={{header|GUISS}}==
In Graphical User Interface Support Script, we utilize applications that are already written. So for this task, we shall just display the calendar that sets the system clock.
<syntaxhighlight lang="guiss">RIGHTCLICK:CLOCK,ADJUST DATE AND TIME,BUTTON:CANCEL</syntaxhighlight>
=={{header|Icon}} and {{header|Unicon}}==
Icon and Unicon don't lend themselves to ''REAL'' programming in the sense of this task easily. And initially this task was marked ''omit'' because the primary declarations, reserved words, and the name of the ''main'' procedure are all in lowercase. However, getting in the spirit of the task real programmers do not give up and a number of solutions are possible:
Line 1,133 ⟶ 1,911:
Also it makes me go all nostalgic for my old [[WATFIVE]] compiler. And an IBM 129 keypunch. And 5 hole paper tape.
<
LINK DATETIME
Line 1,140 ⟶ 1,918:
PROCEDURE MAIN(A)
PRINTCALENDAR(\A$<1$>|1969)
END
Line 1,158 ⟶ 1,936:
EVERY I := 1 TO COLS DO {
WRITES(CENTER(MONS$<MON+I$>,24))
M$<I$> := CREATE CALENDARFORMATWEEK(
$)
WRITE()
Line 1,169 ⟶ 1,947:
$)
$)
RETURN
END
PROCEDURE CALENDARFORMATWEEK(YEAR,M)
STATIC D
INITIAL D := $<31,28,31,30,31,30,31,31,30,31,30,31$>
EVERY SUSPEND "SU"|"MO"|"TU"|"WE"|"TH"|"FR"|"SA"
EVERY 1 TO (DAY := (JULIAN(M,1,YEAR)+1)%7) DO SUSPEND ""
EVERY SUSPEND 1 TO D$<M$> DO DAY +:= 1
IF M = 2 & ISLEAPYEAR(YEAR) THEN SUSPEND (DAY +:= 1, 29)
EVERY DAY TO (6*7) DO SUSPEND ""
END</
Where REALIZE.ICN would be something like this (this example is incomplete but sufficient for this program):
<
$define END end
$define WRITE write
Line 1,208 ⟶ 1,987:
$define IF if
$define THEN then
$define BY by
$define DATETIME datetime
$define RETURN return</syntaxhighlight>
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/DATETIME.ICN DATETIME.ICN provides IsLeapYear and julian]
=={{header|J}}==
For added "real"ness, we also only use 1 character names:
<
M=: 28+ 3, (10$5$3 2),~ 0 ~:/@:= 4 100 400 | ]
R=: (7 -@| B+ 0, +/\@}:@M) |."0 1 (0,#\#~41) (]&:>: *"1 >/)~ M
Line 1,225 ⟶ 2,005:
L=: |."0 1~ +/ .(*./\@:=)"1&' '
E=: (|."0 1~ _2 <.@%~ +/ .(*./\.@:=)"1&' ')@:({."1) L
F=: 0 _1 }. 0 1 }. (2+[) E '[INSERT SNOOPY HERE]', ":@], D</
B: given a year returns a number which when added to numeric values indexing days that year, mod 7, index the proper day names within a week. (In other words 7 | 0 + B 1969 gives the day of week index for the first day of 1969.)
Line 1,247 ⟶ 2,027:
Here's an example calendar (the first line <code>132 F 1969</code> being the command that build this calendar):
<syntaxhighlight lang="text"> 132 F 1969
[INSERT SNOOPY HERE]
1969
Line 1,269 ⟶ 2,049:
│ │31 │ │ │30 │ │
└────────────────────┴────────────────────┴────────────────────┴────────────────────┴────────────────────┴────────────────────┘
</syntaxhighlight>
Note that this version of F will work fine with a left argument of 20 (why anyone felt that this was important to mention is perhaps best thought of as an issue lost in history).
=={{header|Julia}}==
Julia code is a valid data type in Julia. Executable code can be created from a String with Meta.parse() and run with eval.
This example does require a small function with Julia's lowercase keywords, perhaps loaded on startup from a separate file.
<syntaxhighlight lang="julia">
# IF THIS SMALL FUNCTION IS PLACED IN THE STARTUP.JL
# FILE, IT WILL BE LOADED ON STARTUP. THE REST OF
# THIS EXAMPLE IS IN ALL UPPERCASE.
function RUNUPPERCASECODE(CO)
COD = replace(lowercase(CO), "date" => "Date")
for E in Meta.parse(COD, 1) eval(E) end
end
CODE = """BEGIN
USING DATES;
CENTEROBJECT(X, N) = BEGIN S = UPPERCASE(STRING(X)); RPAD(LPAD(S, DIV(N + LENGTH(S), 2)), N) END;
FUNCTION FORMATMONTH(YR, MO)
DT = DATE(\"\$YR-\$MO-01\");
DAYOFWEEKFIRST = DAYOFWEEK(DT);
NUMWEEKLINES = 1;
STR = UPPERCASE(CENTEROBJECT(MONTHNAME(DT), 20) * \"\\NMO TU WE TH FR SA SU\\N\");
STR *= \" \" ^ (3 * (DAYOFWEEKFIRST - 1)) * LPAD(STRING(1), 2);
FOR I = 2:DAYSINMONTH(DT)
IF (I + DAYOFWEEKFIRST + 5) % 7 == 0
STR *= \"\\N\" * LPAD(I, 2);
NUMWEEKLINES += 1;
ELSE
STR *= LPAD(STRING(I), 3);
END;
END;
STR *= NUMWEEKLINES < 6 ? \"\\N\\N\\N\" : \"\\N\\N\";
ARR = [];
FOR S IN SPLIT(STR, \"\\N\")
PUSH!(ARR, RPAD(S, 20)[1:20])
END;
JOIN(ARR, \"\\N\");
END;
FUNCTION FORMATYEAR(DISPLAYYEAR)
CALMONTHS = [FORMATMONTH(DISPLAYYEAR, MO) FOR MO IN 1:12];
MONTHSPERLINE = 6;
JOINSPACES = 2;
STR = \"\\N\" * CENTEROBJECT(DISPLAYYEAR, 132) * \"\\N\";
MONTHCAL = [SPLIT(FORMATMONTH(DISPLAYYEAR, I), \"\\N\") FOR I IN 1:12];
FOR I IN 1:MONTHSPERLINE:LENGTH(CALMONTHS) - 1
FOR J IN 1:LENGTH(MONTHCAL[1])
MONTHLINES = MAP(X->MONTHCAL[X][J], I:I + MONTHSPERLINE - 1);
STR *= RPAD(JOIN(MONTHLINES, \" \" ^ JOINSPACES), 132) * \"\\N\";
END;
STR *= \"\\N\";
END;
STR;
END;
PRINTLN(FORMATYEAR(1969));
END;
"""
RUNUPPERCASECODE(CODE)
</syntaxhighlight> {{output}} <pre>
1969
JANUARY FEBRUARY MARCH APRIL MAY JUNE
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2 1 2 3 4 5 6 1 2 3 4 1
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
31 30
JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 1 2 1 2 3 4 5 6 7
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Kotlin}}==
Kotlin is case-sensitive: all its keywords and packages are lower case, all its library classes are mixed case and its library functions are either lower case or mixed case. Consequently, it is impossible to run an upper case version of the Calendar task program as it stands. So what I've done instead (and similar to what several other languages in the same boat have done) is:
1. Saved the Calendar program, after conversion to upper case and a small marked alteration to give upper case output, to a text file called calendar_UC.txt.
2. Written another program called real_calendar.kt which takes calendar_UC.txt as input, outputs a runnable program called calendar_NC.kt to disk, compiles it to a .jar file, runs it, captures the output and prints it to the terminal (Ubuntu 14.04 being used). This program only makes the minimum changes to calendar_UC.txt to enable it to run. Everything else is left as upper case even though almost certainly no Kotlin programmer ("REAL" or not) would write such a program in practice.
This is calendar_UC.txt:
<syntaxhighlight lang="scala">IMPORT JAVA.TEXT.*
IMPORT JAVA.UTIL.*
IMPORT JAVA.IO.PRINTSTREAM
INTERNAL FUN PRINTSTREAM.PRINTCALENDAR(YEAR: INT, NCOLS: BYTE, LOCALE: LOCALE?) {
IF (NCOLS < 1 || NCOLS > 12)
THROW ILLEGALARGUMENTEXCEPTION("ILLEGAL COLUMN WIDTH.")
VAL W = NCOLS * 24
VAL NROWS = MATH.CEIL(12.0 / NCOLS).TOINT()
VAL DATE = GREGORIANCALENDAR(YEAR, 0, 1)
VAR OFFS = DATE.GET(CALENDAR.DAY_OF_WEEK) - 1
VAL DAYS = DATEFORMATSYMBOLS(LOCALE).SHORTWEEKDAYS.SLICE(1..7).MAP { IT.SLICE(0..1) }.JOINTOSTRING(" ", " ")
VAL MONS = ARRAY(12) { ARRAY(8) { "" } }
DATEFORMATSYMBOLS(LOCALE).MONTHS.SLICE(0..11).FOREACHINDEXED { M, NAME ->
VAL LEN = 11 + NAME.LENGTH / 2
VAL FORMAT = MESSAGEFORMAT.FORMAT("%{0}S%{1}S", LEN, 21 - LEN)
MONS[M][0] = STRING.FORMAT(FORMAT, NAME, "")
MONS[M][1] = DAYS
VAL DIM = DATE.GETACTUALMAXIMUM(CALENDAR.DAY_OF_MONTH)
FOR (D IN 1..42) {
VAL ISDAY = D > OFFS && D <= OFFS + DIM
VAL ENTRY = IF (ISDAY) STRING.FORMAT(" %2S", D - OFFS) ELSE " "
IF (D % 7 == 1)
MONS[M][2 + (D - 1) / 7] = ENTRY
ELSE
MONS[M][2 + (D - 1) / 7] += ENTRY
}
OFFS = (OFFS + DIM) % 7
DATE.ADD(CALENDAR.MONTH, 1)
}
PRINTF("%" + (W / 2 + 10) + "S%N", "[SNOOPY PICTURE]")
PRINTF("%" + (W / 2 + 4) + "S%N%N", YEAR)
FOR (R IN 0..NROWS - 1) {
FOR (I IN 0..7) {
VAR C = R * NCOLS
WHILE (C < (R + 1) * NCOLS && C < 12) {
PRINTF(" %S", MONS[C][I].TOUPPERCASE()) // ORIGINAL CHANGED TO PRINT IN UPPER CASE
C++
}
PRINTLN()
}
PRINTLN()
}
}
FUN MAIN(ARGS: ARRAY<STRING>) {
SYSTEM.OUT.PRINTCALENDAR(1969, 3, LOCALE.US)
}</syntaxhighlight>
and this is real_calendar.kt:
<syntaxhighlight lang="scala">// version 1.1.3
import java.io.File
import java.io.BufferedReader
import java.io.InputStreamReader
fun main(args: Array<String>) {
val keywords = listOf(
"import", "internal", "fun", "if", "throw", "val", "var", "for", "in", "while"
)
val singleCase = listOf(
"java.text",
"java.util",
"java.io",
"else", // really a keyword but doesn't have a following space here
"ceil",
"it", // really a keyword but doesn't have a following space here
"get(", // also included in GETACTUALMAXIMUM
"slice",
"map",
"months",
"length",
".format", // also variable called FORMAT
"add",
"printf",
"println",
"out",
"main",
"args",
"s%{1}s",
"%2s",
"s%n%n",
"s%n",
"%s"
)
val mixedCase = listOf(
"PRINTSTREAM" to "PrintStream",
"INT," to "Int,", // also included in PRINTCALENDAR
"BYTE" to "Byte",
"LOCALE?" to "Locale?", // also variable called LOCALE
"LOCALE." to "Locale.",
"ILLEGALARGUMENTEXCEPTION" to "IllegalArgumentException",
"MATH" to "Math",
"GREGORIANCALENDAR" to "GregorianCalendar",
"DATEFORMATSYMBOLS" to "DateFormatSymbols",
"ARRAY" to "Array",
"MESSAGEFORMAT" to "MessageFormat",
"JOINTOSTRING" to "joinToString",
"STRING" to "String",
"CALENDAR." to "Calendar.", // also included in PRINTCALENDAR
"SYSTEM" to "System",
"TOINT" to "toInt",
"SHORTWEEKDAYS" to "shortWeekdays",
"FOREACHINDEXED" to "forEachIndexed",
"GETACTUALMAXIMUM" to "getActualMaximum",
"TOUPPERCASE" to "toUpperCase"
)
var text = File("calendar_UC.txt").readText()
for (k in keywords) text = text.replace("${k.toUpperCase()} ", "$k ") // add a following space to be on safe side
for (s in singleCase) text = text.replace(s.toUpperCase(), s)
for (m in mixedCase) text = text.replace(m.first, m.second)
File("calendar_NC.kt").writeText(text)
val commands = listOf("kotlinc", "calendar_NC.kt", "-include-runtime", "-d", "calendar_X.jar")
val pb = ProcessBuilder(commands)
pb.redirectErrorStream(true)
val process = pb.start()
process.waitFor()
val commands2 = listOf("java", "-jar", "calendar_NC.jar")
val pb2 = ProcessBuilder(commands2)
pb2.redirectErrorStream(true)
val process2 = pb2.start()
val out = StringBuilder()
val br = BufferedReader(InputStreamReader(process2.inputStream))
while (true) {
val line = br.readLine()
if (line == null) break
out.append(line).append('\n')
}
br.close()
println(out.toString())
}</syntaxhighlight>
which generates (on disk) calendar_NC.kt:
<syntaxhighlight lang="scala">import java.text.*
import java.util.*
import java.io.PrintStream
internal fun PrintStream.PRINTCALENDAR(YEAR: Int, NCOLS: Byte, LOCALE: Locale?) {
if (NCOLS < 1 || NCOLS > 12)
throw IllegalArgumentException("ILLEGAL COLUMN WIDTH.")
val W = NCOLS * 24
val NROWS = Math.ceil(12.0 / NCOLS).toInt()
val DATE = GregorianCalendar(YEAR, 0, 1)
var OFFS = DATE.get(Calendar.DAY_OF_WEEK) - 1
val DAYS = DateFormatSymbols(LOCALE).shortWeekdays.slice(1..7).map { it.slice(0..1) }.joinToString(" ", " ")
val MONS = Array(12) { Array(8) { "" } }
DateFormatSymbols(LOCALE).months.slice(0..11).forEachIndexed { M, NAME ->
val LEN = 11 + NAME.length / 2
val FORMAT = MessageFormat.format("%{0}s%{1}s", LEN, 21 - LEN)
MONS[M][0] = String.format(FORMAT, NAME, "")
MONS[M][1] = DAYS
val DIM = DATE.getActualMaximum(Calendar.DAY_OF_MONTH)
for (D in 1..42) {
val ISDAY = D > OFFS && D <= OFFS + DIM
val ENTRY = if (ISDAY) String.format(" %2s", D - OFFS) else " "
if (D % 7 == 1)
MONS[M][2 + (D - 1) / 7] = ENTRY
else
MONS[M][2 + (D - 1) / 7] += ENTRY
}
OFFS = (OFFS + DIM) % 7
DATE.add(Calendar.MONTH, 1)
}
printf("%" + (W / 2 + 10) + "s%n", "[SNOOPY PICTURE]")
printf("%" + (W / 2 + 4) + "s%n%n", YEAR)
for (R in 0..NROWS - 1) {
for (I in 0..7) {
var C = R * NCOLS
while (C < (R + 1) * NCOLS && C < 12) {
printf(" %s", MONS[C][I].toUpperCase()) // ORIGINAL CHANGED TO PRINT in UPPER CASE
C++
}
println()
}
println()
}
}
fun main(args: Array<String>) {
System.out.PRINTCALENDAR(1969, 3, Locale.US)
}</syntaxhighlight>
which when compiled and run produces output of:
<pre>
[SNOOPY PICTURE]
1969
JANUARY FEBRUARY MARCH
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8
12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15
19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22
26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29
30 31
APRIL MAY JUNE
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
27 28 29 30 25 26 27 28 29 30 31 29 30
JULY AUGUST SEPTEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 1 2 3 4 5 6
6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13
13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30
31
OCTOBER NOVEMBER DECEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1 2 3 4 5 6
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
</pre>
=={{header|Lua}}==
Tested with Lua 5.3.2
Line 1,280 ⟶ 2,388:
The upper case Lua source - stored in a file called UCCALENDAR.LUU:
<br>
<
LOCAL MONTHS={"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE",
"JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"}
Line 1,343 ⟶ 2,451:
PRINT_CAL(1969)
</syntaxhighlight>
The following "one-liner" standard Lua source will down-case and run the program in the source file specified as it's parameter (file luu.lua):
<
</syntaxhighlight>
The following command will execute the UCCALENDAR.LUU source (replace lua532 with the appropriate command for your system):
<br>
Line 1,395 ⟶ 2,503:
</pre>
=={{header|M2000 Interpreter}}==
Console 132 characters by 43 lines. Six columns for months.
<syntaxhighlight lang="m2000 interpreter">
\\ Calendar - for "REAL" programmers
\\ All statements in UPPERCASE
\\ Output to 132 characters console - as a line printer
\\ USE COURIER NEW (FONT "COURIER NEW")
\\ CHANGE THE VALUE OF PRINT_IT TO TRUE FOR PRINTING
GLOBAL CONST PRINT_IT AS BOOLEAN=FALSE
MODULE GLOBAL SNOOPY {
IF NOT PRINT_IT THEN CURSOR 0,ROW ELSE IF ROW>0 THEN PAGE 1
PRINT $(,8)
PRINT #-2, {
XXXX
X XX
X *** X XXXXX
X ***** X XXX XX
XXXX ******* XXX XXXX XX
XX X ****** XXXXXXXXX El@ XX XXX
XX X **** X X** X
X XX XX X X***X
X //XXXX X XXXX
X // X XX
X // X XXXXXXXXXXXXXXXXXX/
X XXX// X X
X X X X X
X X X X X
X X X X X XX
X X X X X XXX XX
X XXX X X X X X X
X X X XX X XXXX
X X XXXXXXXX\ XX XX X
XX XX X X @X XX
XX XXXX XXXXXX/ X XXXX
XXX XX*** X X
XXXXXXXXXXXXX * * X X
*---* X X X
*-* * XXX X X
*- * XXX X
*- *X XXX
*- *X X XXX
*- *X X XX
*- *XX X X
* *X* X X X
* *X * X X X
* * X** X XXXX X
* * X** XX X X
* ** X** X XX X
* ** X* XXX X X
* ** XX XXXX XXX
* * * XXXX X X
* * * X X X
=======******* * * X X XXXXXXXX\
* * * /XXXXX XXXXXXXX\ )
=====********** * X ) \ )
====* * X \ \ )XXXXX
=========********** XXXXXXXXXXXXXXXXXXXXXX
}
}
MODULE CALENDAR (YEAR, LOCALEID) {
FUNCTION GETMAX(YEAR, MONTH) {
A=DATE(STR$(YEAR)+"-"+STR$(MONTH)+"-1")
MAX=32
DO {
MAX--
M=VAL(STR$(CDATE(A,0,0,MAX), "M"))
} UNTIL M=MONTH
=MAX+1
}
FUNCTION SKIPMO(YEAR, MONTH) {
A=DATE(STR$(YEAR)+"-"+STR$(MONTH)+"-1")
=(VAL(STR$(A, "W"))-8) MOD 7 +7
}
FUNCTION TITLE$(A$) {
=UCASE$(LEFT$(A$,1))+LCASE$(MID$(A$, 2))
}
LOCALE LOCALEID
IF NOT PRINT_IT THEN CURSOR 0,HEIGHT-1 ' LAST LINE, SO EACH NEW LINE SCROLL ALL LINES UP
SNOOPY
PRINT UNDER ' PRINT UNDERLINE
PRINT OVER $(2), YEAR
PRINT
FOR J=0 TO 1 {
PRINT
FOR I=1 TO 6 {
MONTH=I+J*6
PRINT PART @((I-1)*22+1), $(2,21), UCASE$(LOCALE$(55+MONTH))
}
PRINT
DIM SKIP(1 TO 6), COUNT(1 TO 6), D(1 TO 6)=1
FOR I=1 TO 6 {
MONTH=I+J*6
IF I>1 THEN PRINT " ";
FOR K=42 TO 48 :PRINT " ";UCASE$(LEFT$(LOCALE$(K),2));:NEXT K
SKIP(I)=SKIPMO(YEAR, MONTH)
COUNT(I)=GETMAX(YEAR, MONTH)
}
PRINT
IF PRINT_IT ELSE REFRESH 1000
FOR I=1 TO 6 {
IF I>1 THEN PRINT " ";
FOR K=1 TO 7 {
SKIP(I)--
IF SKIP(I)>0 THEN PRINT " "; :CONTINUE
COUNT(I)--
PRINT FORMAT$(" {0::-2}", D(I));
D(I)++
}
}
PRINT
IF PRINT_IT ELSE REFRESH 1000
PRINT @(0)
FOR M=1 TO 5 {
FOR I=1 TO 6 {
IF I>1 THEN PRINT " ";
FOR K=1 TO 7 {
COUNT(I)--
IF COUNT(I)<0 THEN PRINT " "; : CONTINUE
PRINT FORMAT$(" {0::-2}", D(I));
D(I)++
}
}
PRINT
IF PRINT_IT ELSE REFRESH 1000
}
}
}
WHILE INKEY$<>"" : END WHILE
IF PRINT_IT THEN PRINTING ON ELSE REFRESH 1000
FONT "COURIER NEW"
PEN 0
CLS 15, 0
FORM 132,68
CALENDAR 1966, 1032 ' GREEK
GOSUB WAITKEY_OR_MOUSE
FOR I=2020 TO 2026
CALENDAR I, 1033 ' ENGLISH
GOSUB WAITKEY_OR_MOUSE
NEXT I
IF PRINT_IT THEN PRINTING OFF ELSE REFRESH 50
CLEAR ' CLEAR VARIABLES FROM THIS MODULE
END
WAITKEY_OR_MOUSE:
IF PRINT_IT THEN RETURN
WHILE INKEY$="" AND MOUSE=0
END WHILE
RETURN
</syntaxhighlight>
=={{header|Nim}}==
Nim is a peculiar language regarding case sensitivity. First, keywords are all in lowercase. Second, Nim is case sensitive regarding the first character only. That means that ''Thing'' is different of ''thing'' but identical to ''THING''. There are several conventions regarding the style. For instance, the first character of a type should be in uppercase while the first character of a procedure or a variable should be in lowercase. Nim is also style-insensitive which means that "myvar", "myVar" and "my_var" are equivalent identifiers.
This makes impossible to write a valid program with only uppercase characters. So, we have built a program which reads the text written in uppercase, transforms it to valid Nim code, writes it into a file and includes this file. That means that in only one step, the uppercase text is read, transformed and compiled.
Instead of using the command <code>nim c file.txt</code> which would not work, we use the command <code>nim c file.nim</code> which, in fact, compiles “nim.txt” after is has been transformed.
Here is the helper program:
<syntaxhighlight lang="text">import strutils
const progUpper = staticRead("calendar_upper.txt")
proc transformed(s: string): string {.compileTime.} =
## Return a transformed version (which can compile) of a program in uppercase.
let upper = s.toLower() # Convert all to lowercase.
var inString = false # Text in string should be in uppercase…
var inBraces = false # … except if this is in an expression to interpolate.
for ch in upper:
case ch
of '"':
inString = not inString
of '{':
if inString: inBraces = true
of '}':
if inString: inBraces = false
of 'a'..'z':
if inString and not inBraces:
result.add(ch.toUpperAscii()) # Restore content of strings to uppercase.
continue
else:
discard
result.add(ch)
const prog = progUpper.transformed()
static: writeFile("calendar_transformed.nim", prog)
include "calendar_transformed.nim"</syntaxhighlight>
Here is the actual program in uppercase.
<syntaxhighlight lang="text">IMPORT TIMES
IMPORT STRFORMAT
PROC PRINTCALENDAR(YEAR, NCOLS: INT) =
VAR ROWS = 12 DIV NCOLS
VAR DATE = INITDATETIME(1, MJAN, YEAR, 0, 0, 0, UTC())
IF ROWS MOD NCOLS != 0:
INC ROWS
VAR OFFS = GETDAYOFWEEK(DATE.MONTHDAY, DATE.MONTH, DATE.YEAR).INT
VAR MONS: ARRAY[12, ARRAY[8, STRING]]
FOR M IN 0..11:
MONS[M][0] = &"{$DATE.MONTH:^21}"
MONS[M][1] = " SU MO TU WE TH FR SA"
VAR DIM = GETDAYSINMONTH(DATE.MONTH, DATE.YEAR)
FOR D IN 1..42:
VAR DAY = D > OFFS AND D <= OFFS + DIM
VAR STR = IF DAY: &" {D-OFFS:2}" ELSE: " "
MONS[M][2 + (D - 1) DIV 7] &= STR
OFFS = (OFFS + DIM) MOD 7
DATE = DATE + MONTHS(1)
VAR SNOOPYSTRING, YEARSTRING: STRING
FORMATVALUE(SNOOPYSTRING, "[SNOOPY PICTURE]", "^" & $(NCOLS * 24 + 4))
FORMATVALUE(YEARSTRING, $YEAR, "^" & $(NCOLS * 24 + 4))
ECHO SNOOPYSTRING, "\N" , YEARSTRING, "\N"
FOR R IN 0..<ROWS:
VAR S: ARRAY[8, STRING]
FOR C IN 0..<NCOLS:
IF R * NCOLS + C > 11:
BREAK
FOR I, LINE IN MONS[R * NCOLS + C]:
S[I] &= &" {LINE}"
FOR LINE IN S:
IF LINE == "":
BREAK
ECHO LINE
ECHO ""
PRINTCALENDAR(1969, 5)</syntaxhighlight>
{{out}}
The program allows to choose the number of columns. Five is the maximum which can fit with 132 columns.
<pre> [SNOOPY PICTURE]
1969
January February March April May
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 1 2 1 2 3 4 5 6 1 2 3 4
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31
31
June July August September October
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
2 3 4 5 6 7 8 7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
9 10 11 12 13 14 15 14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
16 17 18 19 20 21 22 21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
23 24 25 26 27 28 29 28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31
30
November December
SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 1 2 3 4 5 6 7
3 4 5 6 7 8 9 8 9 10 11 12 13 14
10 11 12 13 14 15 16 15 16 17 18 19 20 21
17 18 19 20 21 22 23 22 23 24 25 26 27 28
24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Perl}}==
Since we can't use <code>eval</code> or <code>print</code> (or any other keywords)
at the top level, we need to abuse backticks in order to print anything, as in [http://www.perlmonks.org/?node_id=43797 the infamous JAPH with no letters or numbers]. Consequently, the calendar is printed to standard error instead of standard output.
<
MY @START_DOW = (3, 6, 6, 2, 4, 0,
Line 1,443 ⟶ 2,816:
$L = ',' | '@';
`${E}${C}${H}${O} $PROGRAM | ${T}${R} A-Z ${A}-${Z} | ${P}${E}${R}${L}`;</
Although, if we are abusing the backticks and other innocent programs, why not just: <
=={{header|Phix}}==
<syntaxhighlight lang="phix">
--return repeat(' ',left)&s&repeat(' ',right)
</syntaxhighlight>
(That's that done.) Now, Phix is case-sensitive, and many of the keywords and builtins are in lower case, which presents a bit of a challenge - but we can cope. It is too tedious and not particularly helpful to present a completed solution, instead I shall outline the (relatively simple) steps this would require. I have limited my tests to INCLUDE and INTEGER. In psym.e you can find the line
<syntaxhighlight lang="phix">
initialSymEntry("integer", S_Type,"TI",opInt, E_none) -- #01 / 0b0001 integer
</syntaxhighlight>
Immediately after that (it should now be there commented out) add:
<syntaxhighlight lang="phix">
Alias("INTEGER",symlimit)
</syntaxhighlight>
Add similar lines for length, floor, repeat, upper, day_of_week, sequence, string, sprintf, append, printf, join, at the appropriate places. Keywords are handled slightly differently: In pttree.e we need a new alias routine (you should find this one commented out, from when I was testing all this):
<syntaxhighlight lang="phix">
tt_string(text,-2)
tt[pcurr] = alias
end procedure
</syntaxhighlight>
and you can find the line
<syntaxhighlight lang="phix">
global constant T_include = 596 tt_stringF("include",T_include)
</syntaxhighlight>
Sometime after that, in fact after the very last use of tt_stringF, add (likewise you should find this one commented out):
<syntaxhighlight lang="phix">
tt_stringA("INCLUDE",T_include)
</syntaxhighlight>
Add similar lines for function, end, iff, for, to, do, if, or, then, else, return, procedure, but this time all some ways away from the originals. Quickly run "p p" and make sure you get a normal prompt, without any "T_include should be 624(not 596)" or suchlike (which would happen <i>alot</i> if you put the aliases anywhere other than last).
Currently ptok.e recognises <code>\n</code> but not <code>\N</code>. Search for all references to <code>escchar</code> (there should be one definition and two references) and make sure the character being
checked is mapped to lower case, ie change (twice)
<syntaxhighlight lang="phix">
--Ch = find(Ch,escchar)
</syntaxhighlight>
Lastly, the calendar example includes builtins\timedate.e, which contains some lower-case definitions. So copy it to (say) TIMEDATEUPPER.E and change adjust_timedate, timedelta, days (the 2nd param to timedelta), and format_timedate to their uppercase equivalents, and of course change that include to <code>INCLUDE BUILTINS\TIMEDATEUPPER.E</code>.
There
You don't actually have to repackage (p -c p) to test this, just run p p test.exw -
Finally, you can take that copy of [[Calendar#Phix|Calendar]] and make it all uppercase. In Edita (shipped with Phix) that is just <Ctrl A><Alt U>.
Line 1,500 ⟶ 2,868:
While PHP functions are case-sensitive (aside of <code>_()</code>), this isn't the case for language constructs.
<
ECHO <<<REALPROGRAMMERSTHINKINUPPERCASEANDCHEATBYUSINGPRINT
JANUARY FEBRUARY MARCH APRIL MAY JUNE
Line 1,519 ⟶ 2,887:
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
REALPROGRAMMERSTHINKINUPPERCASEANDCHEATBYUSINGPRINT
; // MAGICAL SEMICOLON</
=={{header|PicoLisp}}==
The "CALENDAR.L" source file:
<
(PRINL "====== " YEAR " ======")
(FOR DAT (RANGE (DATE YEAR 1 1) (DATE YEAR 12 31))
Line 1,535 ⟶ 2,903:
(CAL 1969)
(BYE)</
Then it can be executed with this command line:
<pre>$ pil -'load (list "awk" "{print tolower($0)}" "CALENDAR.L")'</pre>
Line 1,563 ⟶ 2,931:
30 Tue
31 Wed</pre>
=={{header|PL/I}}==
<
CALENDAR: PROCEDURE (YEAR) OPTIONS (MAIN);
DECLARE YEAR CHARACTER (4) VARYING;
Line 1,616 ⟶ 2,983:
END PREPARE_MONTH;
END CALENDAR;</
See CALENDAR for result.
=={{header|Racket}}==
<
#CI(MODULE NAME-OF-THIS-FILE RACKET
(REQUIRE RACKET/DATE)
Line 1,665 ⟶ 3,022:
(CALENDAR 1969))
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
Uppercase is no challenge, who needs letters at all?
[Requires the year to be supplied as a command-line argument, and Unixish <i>cal</i> command.]
<syntaxhighlight lang="raku" line>$_="\0".."~";<
115 97 121 32 34 91 73 78 83 69 82 84 32 83 78 79 79 80 89 32 72 69 82 69 93 34
59 114 117 110 32 60 99 97 108 62 44 64 42 65 82 71 83 91 48 93 47 47 49 57 54 57
>."$_[99]$_[104]$_[114]$_[115]"()."$_[69]$_[86]$_[65]$_[76]"()</syntaxhighlight>
=={{header|REXX}}==
This is essentially the same REXX program as for the CALENDAR task, but written entirely in uppercase. Indeed,
Line 1,681 ⟶ 3,045:
(from the command line), and a few simple tricks were used to accomplish this.
<br>[Note: the command line may also be all uppercase.]
This version automatically will use the depth and width of the terminal screen to determine which layout fits best.
<br>However, the depth and width can be overridden with the '''depth''' and '''width''' keywords.
In any case, both versions of the programs' output are identical
(but the second REXX version sure as heck looks
<br>like it was beat with a big ole ugly stick ─── and pardon the strong language).
<
@ABC=
PARSE VALUE SCRSIZE() WITH SD SW .
DO J=0 TO 255;_=D2C(J);IF DATATYPE(_,'L') THEN @ABC=@ABC||_;END
@ABCU=@ABC; UPPER @ABCU
Line 1,701 ⟶ 3,069:
END
CALFILL=' '; MC=12; _='1 3 1234567890' "FB"X
PARSE VAR _ GRID CALSPACES # CHK . CV_ DAYS.1 DAYS.2 DAYS.3 DAYSN
_=0; PARSE VAR _ COLS 1 JD 1 LOWERCASE 1 MAXKALPUTS 1 NARROW 1,
NARROWER 1 NARROWEST 1 SHORT 1 SHORTER 1 SHORTEST 1,
Line 1,744 ⟶ 3,112:
END /*DO WHILE OPTS\== ...*/
IF SD==0 THEN SD= 43; SD= SD-3
IF SW==0 THEN SW= 80; SW= SW-1
MC=INT(MC,'MONTHSCALENDER'); IF MC>0 THEN CAL=1
DAYS=' 'DAYS; MONTHS=' 'MONTHS
CYYYY=RIGHT(DATE(),4); HYY=LEFT(CYYYY,2); LYY=RIGHT(CYYYY,2)
DY.=31; _=30; PARSE VAR _ DY.4 1 DY.6 1 DY.9 1 DY.11; DY.2=28+LY(YYYY)
YY=RIGHT(YYYY,2);
IF SMALL THEN DO; NARROW=1 ; SHORT=1 ; END
IF SMALLER THEN DO; NARROWER=1 ; SHORTER=1 ; END
Line 1,854 ⟶ 3,224:
PUT:_=ARG(1);_=TRANSLATE(_,,'_'CHK);IF \GRID THEN _=UNGRID(_);IF LOWERCASE THEN _=LOWER(_);IF UPPERCASE THEN UPPER _;IF SHORTEST&_=' ' THEN RETURN;CALL TELL _;RETURN
TELL:SAY ARG(1);RETURN
UNGRID:RETURN TRANSLATE(ARG(1),,"│║─═┤┐└┴┬├┼┘┌╔╗╚╝╟╢╞╡╫╪╤╧╥╨╠╣")</
Programming note: This REXX program makes use of '''SCRSIZE''' REXX program (or
BIF) which is used to determine the screen
<br>width and depth of the terminal (console). Some REXXes don't
have this BIF.
The '''SCRSIZE.REX''' REXX program is included
here ───► [[SCRSIZE.REX]].
{{out|output|text= when using the input of: <tt> 1/1/1969 (NOGRID SHORTER NARROWER) </tt>}}
(Shown at <big>'''<sup>2</sup>/<sub>3</sub>'''</big> size.)
<pre style="font-size:67%">
«Snoopy "picture" here»
January 1969 February 1969 March 1969 April 1969
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 1 1 1 2 3 4 5
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8 6 7 8 9 10 11 12
12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15 13 14 15 16 17 18 19
19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22 20 21 22 23 24 25 26
26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29 27 28 29 30
30 31
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17 15 16 17 18 19 20 21
18 19 20 21 22 23 24 22 23 24 25 26 27 28
25 26 27 28 29 30 31 29 30
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
</pre>
{{out|output|text= when using the input of: <tt> 1/1/1969 (SHORTER NARROWER) </tt>}}
(Shown at <big>'''<sup>2</sup>/<sub>3</sub>'''</big> size.)
<pre style="font-size:67%">
«Snoopy "picture" here»
┌──────────────────────────────────┐ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ │ │ │ │ │ │ │
│ January 1969 │ │ February 1969 │ │ March 1969 │ │ April 1969 │
│ │ │ │ │ │ │ │
│ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│
├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤
│ │ │ │ 1 │ 2 │ 3 │ 4 │ │ │ │ │ │ │ │ 1 │ │ │ │ │ │ │ │ 1 │ │ │ │ 1 │ 2 │ 3 │ 4 │ 5 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │ │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ │ │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ │ 27 │ 28 │ 29 │ 30 │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘ └────┴────┴────┴────┴────┴────┴────┘ ├────┼────┼────┼────┼────┼────┼────┤ └────┴────┴────┴────┴────┴────┴────┘
│ 30 │ 31 │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘
┌──────────────────────────────────┐ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ │ │ │ │ │ │ │
│ May 1969 │ │ June 1969 │ │ July 1969 │ │ August 1969 │
│ │ │ │ │ │ │ │
│ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│
├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤
│ │ │ │ │ 1 │ 2 │ 3 │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ │ │ │ 1 │ 2 │ 3 │ 4 │ 5 │ │ │ │ │ │ │ 1 │ 2 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │ │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ 16 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ 23 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │ 29 │ 30 │ │ │ │ │ │ │ 27 │ 28 │ 29 │ 30 │ 31 │ │ │ │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ 30 │
└────┴────┴────┴────┴────┴────┴────┘ └────┴────┴────┴────┴────┴────┴────┘ └────┴────┴────┴────┴────┴────┴────┘ ├────┼────┼────┼────┼────┼────┼────┤
│ 31 │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘
┌──────────────────────────────────┐ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ │ │ │ │ │ │ │
│ September 1969 │ │ October 1969 │ │ November 1969 │ │ December 1969 │
│ │ │ │ │ │ │ │
│ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│ │ Sun Mon Tue Wed Thu Fri Sat│
├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤ ├────┬────┬────┬────┬────┬────┬────┤
│ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ │ │ │ 1 │ 2 │ 3 │ 4 │ │ │ │ │ │ │ │ 1 │ │ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │ │ 12 │ 13 │ 14 │ 15 │ 16 │ 17 │ 18 │ │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │ │ 14 │ 15 │ 16 │ 17 │ 18 │ 19 │ 20 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │ │ 19 │ 20 │ 21 │ 22 │ 23 │ 24 │ 25 │ │ 16 │ 17 │ 18 │ 19 │ 20 │ 21 │ 22 │ │ 21 │ 22 │ 23 │ 24 │ 25 │ 26 │ 27 │
├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤ ├────┼────┼────┼────┼────┼────┼────┤
│ 28 │ 29 │ 30 │ │ │ │ │ │ 26 │ 27 │ 28 │ 29 │ 30 │ 31 │ │ │ 23 │ 24 │ 25 │ 26 │ 27 │ 28 │ 29 │ │ 28 │ 29 │ 30 │ 31 │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘ └────┴────┴────┴────┴────┴────┴────┘ ├────┼────┼────┼────┼────┼────┼────┤ └────┴────┴────┴────┴────┴────┴────┘
│ 30 │ │ │ │ │ │ │
└────┴────┴────┴────┴────┴────┴────┘
</pre>
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# PROJECT : CALENDAR - FOR "REAL" PROGRAMMERS
# DATE : 2018/06/28
# AUTHOR : GAL ZSOLT (~ CALMOSOFT ~)
# EMAIL : <CALMOSOFT@GMAIL.COM>
LOAD "GUILIB.RING"
LOAD "STDLIB.RING"
NEW QAPP
{
WIN1 = NEW QWIDGET() {
DAY = LIST(12)
POS = NEWLIST(12,37)
MONTH = LIST(12)
WEEK = LIST(7)
WEEKDAY = LIST(7)
BUTTON = NEWLIST(7,6)
MONTHSNAMES = LIST(12)
WEEK = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"]
MONTHS = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY",
"AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"]
DAYSNEW = [[5,1], [6,2], [7,3], [1,4], [2,5], [3,6], [4,7]]
MO = [4,0,0,3,5,1,3,6,2,4,0,2]
MON = [31,28,31,30,31,30,31,31,30,31,30,31]
M2 = (((1969-1900)%7) + FLOOR((1969 - 1900)/4) % 7) % 7
FOR N = 1 TO 12
MONTH[N] = (MO[N] + M2) % 7
X = (MONTH[N] + 1) % 7 + 1
FOR M = 1 TO LEN(DAYSNEW)
IF DAYSNEW[M][1] = X
NR = M
OK
NEXT
DAY[N] = DAYSNEW[NR][2]
NEXT
FOR M = 1 TO 12
FOR N = 1 TO DAY[M] - 1
POS[M][N] = " "
NEXT
NEXT
FOR M = 1 TO 12
FOR N = DAY[M] TO 37
IF N < (MON[M] + DAY[M])
POS[M][N] = N - DAY[M] + 1
ELSE
POS[M][N] = " "
OK
NEXT
NEXT
SETWINDOWTITLE("CALENDAR")
SETGEOMETRY(100,100,650,800)
LABEL1 = NEW QLABEL(WIN1) {
SETGEOMETRY(10,10,800,600)
SETTEXT("")
}
YEAR = NEW QPUSHBUTTON(WIN1)
{
SETGEOMETRY(280,20,63,20)
YEAR.SETTEXT("1969")
}
FOR N = 1 TO 4
NR = (N-1)*3+1
SHOWMONTHS(NR)
NEXT
FOR N = 1 TO 12
SHOWWEEKS(N)
NEXT
FOR N = 1 TO 12
SHOWDAYS(N)
NEXT
SHOW()
}
EXEC()
}
FUNC SHOWMONTHS(M)
FOR N = M TO M + 2
MONTHSNAMES[N] = NEW QPUSHBUTTON(WIN1)
{
IF N%3 = 1
COL = 120
ROWNR = FLOOR(N/3)
IF ROWNR = 0
ROWNR = N/3
OK
IF N = 1
ROW = 40
ELSE
ROW = 40+ROWNR*180
OK
ELSE
COLNR = N%3
IF COLNR = 0
COLNR = 3
OK
ROWNR = FLOOR(N/3)
IF N%3 = 0
ROWNR = FLOOR(N/3)-1
OK
COL = 120 + (COLNR-1)*160
ROW = 40 + ROWNR*180
OK
SETGEOMETRY(COL,ROW,63,20)
MONTHSNAMES[N].SETTEXT(MONTHS[N])
}
NEXT
FUNC SHOWWEEKS(N)
FOR M = 1 TO 7
COL = M%7
IF COL = 0 COL = 7 OK
WEEKDAY[M] = NEW QPUSHBUTTON(WIN1)
{
COLNR = N % 3
IF COLNR = 0
COLNR = 3
OK
ROWNR = FLOOR(N/3)
IF N%3 = 0
ROWNR = FLOOR(N/3)-1
OK
COLBEGIN = 60 + (COLNR-1)*160
ROWBEGIN = 60 + (ROWNR)*180
SETGEOMETRY(COLBEGIN+COL*20,ROWBEGIN,25,20)
WEEKDAY[M].SETTEXT(WEEK[M])
}
NEXT
FUNC SHOWDAYS(IND)
ROWNR = FLOOR(IND/3)
IF IND%3 = 0
ROWNR = FLOOR(IND/3)-1
OK
ROWBEGIN = 60+ROWNR*180
FOR M = 1 TO 6
FOR N = 1 TO 7
COL = N%7
IF COL = 0 COL = 7 OK
ROW = M
BUTTON[N][M] = NEW QPUSHBUTTON(WIN1)
{
IF IND%3 = 1
COLBEGIN = 60
ELSEIF IND%3 = 2
COLBEGIN = 220
ELSE
COLBEGIN = 380
OK
SETGEOMETRY(COLBEGIN+COL*20,ROWBEGIN+ROW*20,25,20)
NR = (M-1)*7+N
IF NR <= 37
IF POS[IND][NR] != " "
BUTTON[N][M].SETTEXT(STRING(POS[IND][NR]))
OK
OK
}
NEXT
NEXT
</syntaxhighlight>
Output:
[https://www.dropbox.com/s/lb7rnqdb30a72kc/CalmoSoftRealCalendar.jpg?dl=0 CALENDAR - FOR "REAL" PROGRAMMERS]
=={{header|Ruby}}==
UPPERCASE RUBY is normally impossible, because Ruby is sensitive to case, and most methods and keywords have lowercase letters. To solve this task, we wrote a new program loader for UPPERCASE RUBY programs.
Line 1,898 ⟶ 3,501:
* <code>loadup.rb</code> is the program loader.
<
class Object
Line 1,923 ⟶ 3,526:
_PROGRAM = ARGV.SHIFT
_PROGRAM || ABORT("USAGE: #{$0} PROGRAM.RB ARGS...")
LOAD($0 = _PROGRAM)</
* <code>CAL.RB</code> is an UPPERCASE RUBY translation of [[Calendar#Ruby]].
{{works with|Ruby|1.8.7}}
<
REQUIRE 'DATE'.DOWNCASE
Line 2,010 ⟶ 3,613:
PROC {80}) }) })
PUTS CAL(ARGV[0].TO_I, _COLUMNS)</
* A local variable must start with a lowercase letter or an underscore, so we have many leading underscores (_YEAR, _COLUMN, _DATE and so on).
Line 2,037 ⟶ 3,640:
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
31 30 </pre>
=={{header|Seed7}}==
Seed7 keywords are lower case, so this silly solution uses the whole Calendar Task code, with small changes and all in upper case, in a text file named "CALENDAR.TXT":
Line 2,095 ⟶ 3,697:
Then in another program the file CALENDAR.TXT is [http://seed7.sourceforge.net/libraries/getf.htm#getf%28in_string%29 read], converted, [http://seed7.sourceforge.net/libraries/progs.htm#parseStri%28in_string,in_parseOptions,in_array_string,in_string%29 parsed] and [http://seed7.sourceforge.net/libraries/progs.htm#execute%28in_program,in_array_string,in_parseOptions,in_string%29 executed]:
<
include "getf.s7i";
include "progs.s7i";
Line 2,107 ⟶ 3,709:
source := replace(source, "daysinmonth", "daysInMonth");
execute(parseStri(source));
end func;</
{{out}}
Line 2,148 ⟶ 3,750:
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Sidef}}==
<
-> MONTHS_PER_COL { 6 }
Line 2,187 ⟶ 3,788:
-> FMT_YEAR (YEAR, STR="", MONTH_STRS=[]) {
MONTH_STRS = 12.("\LOF")({|I| FMT_MONTH(YEAR, I+1).("\LLINES") })
STR += (' '*(MONTHS_PER_COL()*10 + 2) + YEAR + "\12")
Line 2,193 ⟶ 3,794:
MONTH_STRS[MONTH] && ->() {
{ |I|
MONTH_STRS[MONTH + I
STR += MONTH_STRS[MONTH + I
STR += ' '*2
)
Line 2,208 ⟶ 3,809:
}
FMT_YEAR(ARGV ? ARGV[0].("\LTO_I") : 1969).("\LPRINT")</
{{out}}
<pre>
Line 2,228 ⟶ 3,829:
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Tcl}}==
The program starts implementing aliases for all built-in commands. This is done without using any letters at all ;).
CALENDER takes arguments of year and optional terminal width to use.
<
\146\157\162\145\141\143\150 42 [\151\156\146\157 \143\157\155\155\141\156\144\163] {
\145\166\141\154 "
Line 2,281 ⟶ 3,881:
CALENDAR
</syntaxhighlight>
{{out}}
<pre>
Line 2,320 ⟶ 3,920:
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|UNIX Shell}}==
===Using Bash Case-Converting Parameter Expansion===
<syntaxhighlight lang="shell">CAL=CAL
TR=TR
A=A
Z=Z
LANG=C ${CAL,,} 1969 | ${TR,,} ${A,}-${Z,} A-Z</syntaxhighlight>
{{out}}
<pre>
1969
JANUARY FEBRUARY MARCH
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2
6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9
13 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16
20 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23
27 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30
31
APRIL MAY JUNE
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 4 1
7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
30
JULY AUGUST SEPTEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 6 1 2 3 1 2 3 4 5 6 7
7 8 9 10 11 12 13 4 5 6 7 8 9 10 8 9 10 11 12 13 14
14 15 16 17 18 19 20 11 12 13 14 15 16 17 15 16 17 18 19 20 21
21 22 23 24 25 26 27 18 19 20 21 22 23 24 22 23 24 25 26 27 28
28 29 30 31 25 26 27 28 29 30 31 29 30
OCTOBER NOVEMBER DECEMBER
MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU
1 2 3 4 5 1 2 1 2 3 4 5 6 7
6 7 8 9 10 11 12 3 4 5 6 7 8 9 8 9 10 11 12 13 14
13 14 15 16 17 18 19 10 11 12 13 14 15 16 15 16 17 18 19 20 21
20 21 22 23 24 25 26 17 18 19 20 21 22 23 22 23 24 25 26 27 28
27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
===HISTORICALLY REAL WAY: INFORM UNIX YOUR TTY ONLY SUPPORTS CAPS===
<pre>sun-go:~$ stty olcuc
SUN-GO:~$ PS AUX | GREP PS
KERNOOPS 1159 0.0 0.0 10240 64 ? SS JUL04 3:59 /USR/SBIN/KERNELOOPS --TEST
KERNOOPS 1161 0.0 0.0 10240 64 ? SS JUL04 3:59 /USR/SBIN/KERNELOOPS
KAZ 2279 0.0 0.2 111724 5340 TTY2 SNL+ JUL04 0:00 /USR/LIB/TRACKER/TRACKER-MINER-APPS
ROOT 9404 0.0 0.3 19092 7600 ? SS 00:09 0:00 /USR/SBIN/CUPSD -L
ROOT 9406 0.0 0.4 44248 9772 ? SSL 00:09 0:00 /USR/SBIN/CUPS-BROWSED
KAZ 30121 4.0 0.1 8760 3072 PTS/3 R+ 09:38 0:00 PS AUX
KAZ 30122 0.0 0.0 6520 788 PTS/3 S+ 09:38 0:00 GREP PS
SUN-GO:~$ GREP ROOT /ETC/PASSWD
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
SUN-GO:~$ CAL 1969
1969
JANUARY FEBRUARY MARCH
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8
12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15
19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22
26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29
30 31
APRIL MAY JUNE
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
27 28 29 30 25 26 27 28 29 30 31 29 30
JULY AUGUST SEPTEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 1 2 3 4 5 6
6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13
13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30
31
OCTOBER NOVEMBER DECEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1 2 3 4 5 6
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
30
SUN-GO:~$ STTY SANE
sun-go:~$</pre>
=={{header|Vedit macro language}}==
Line 2,328 ⟶ 4,025:
Vedit macro language is case insensitive, but it is normal practice to write short commands in upper case.
<
CFT(22)
#3 = 6 // NUMBER OF MONTHS PER LINE
Line 2,392 ⟶ 4,089:
REG_EMPTY(#20)
NUM_POP(4,20)
RETURN </
<pre>
Line 2,418 ⟶ 4,115:
28 29 30 31 25 26 27 28 29 30 31 29 30 27 28 29 30 31 24 25 26 27 28 29 30 29 30 31
</pre>
=={{header|Visual Basic .NET}}==
'''Compiler:''' Roslyn Visual Basic (language version >= 15.8)
{{works with|.NET Core|2.1}}
Copied from [[Calendar#Visual_Basic_.NET]] and converted to uppercase. See entry there for description.
<syntaxhighlight lang="vbnet">OPTION COMPARE BINARY
OPTION EXPLICIT ON
OPTION INFER ON
OPTION STRICT ON
IMPORTS SYSTEM.GLOBALIZATION
IMPORTS SYSTEM.TEXT
IMPORTS SYSTEM.RUNTIME.INTEROPSERVICES
IMPORTS SYSTEM.RUNTIME.COMPILERSERVICES
MODULE ARGHELPER
READONLY _ARGDICT AS NEW DICTIONARY(OF STRING, STRING)()
DELEGATE FUNCTION TRYPARSE(OF T, TRESULT)(VALUE AS T, <OUT> BYREF RESULT AS TRESULT) AS BOOLEAN
SUB INITIALIZEARGUMENTS(ARGS AS STRING())
FOR EACH ITEM IN ARGS
ITEM = ITEM.TOUPPERINVARIANT()
IF ITEM.LENGTH > 0 ANDALSO ITEM(0) <> """"C THEN
DIM COLONPOS = ITEM.INDEXOF(":"C, STRINGCOMPARISON.ORDINAL)
IF COLONPOS <> -1 THEN
' SPLIT ARGUMENTS WITH COLUMNS INTO KEY(PART BEFORE COLON) / VALUE(PART AFTER COLON) PAIRS.
_ARGDICT.ADD(ITEM.SUBSTRING(0, COLONPOS), ITEM.SUBSTRING(COLONPOS + 1, ITEM.LENGTH - COLONPOS - 1))
END IF
END IF
NEXT
END SUB
SUB FROMARGUMENT(OF T)(
KEY AS STRING,
<OUT> BYREF VAR AS T,
GETDEFAULT AS FUNC(OF T),
TRYPARSE AS TRYPARSE(OF STRING, T),
OPTIONAL VALIDATE AS PREDICATE(OF T) = NOTHING)
DIM VALUE AS STRING = NOTHING
IF _ARGDICT.TRYGETVALUE(KEY.TOUPPERINVARIANT(), VALUE) THEN
IF NOT (TRYPARSE(VALUE, VAR) ANDALSO (VALIDATE IS NOTHING ORELSE VALIDATE(VAR))) THEN
CONSOLE.WRITELINE($"INVALID VALUE FOR {KEY}: {VALUE}")
ENVIRONMENT.EXIT(-1)
END IF
ELSE
VAR = GETDEFAULT()
END IF
END SUB
END MODULE
MODULE PROGRAM
SUB MAIN(ARGS AS STRING())
DIM DT AS DATE
DIM COLUMNS, ROWS, MONTHSPERROW AS INTEGER
DIM VERTSTRETCH, HORIZSTRETCH, RESIZEWINDOW AS BOOLEAN
INITIALIZEARGUMENTS(ARGS)
FROMARGUMENT("DATE", DT, FUNCTION() NEW DATE(1969, 1, 1), ADDRESSOF DATE.TRYPARSE)
FROMARGUMENT("COLS", COLUMNS, FUNCTION() 80, ADDRESSOF INTEGER.TRYPARSE, FUNCTION(V) V >= 20)
FROMARGUMENT("ROWS", ROWS, FUNCTION() 43, ADDRESSOF INTEGER.TRYPARSE, FUNCTION(V) V >= 0)
FROMARGUMENT("MS/ROW", MONTHSPERROW, FUNCTION() 0, ADDRESSOF INTEGER.TRYPARSE, FUNCTION(V) V <= 12 ANDALSO V <= COLUMNS \ 20)
FROMARGUMENT("VSTRETCH", VERTSTRETCH, FUNCTION() TRUE, ADDRESSOF BOOLEAN.TRYPARSE)
FROMARGUMENT("HSTRETCH", HORIZSTRETCH, FUNCTION() TRUE, ADDRESSOF BOOLEAN.TRYPARSE)
FROMARGUMENT("WSIZE", RESIZEWINDOW, FUNCTION() TRUE, ADDRESSOF BOOLEAN.TRYPARSE)
' THE SCROLL BAR IN COMMAND PROMPT SEEMS TO TAKE UP PART OF THE LAST COLUMN.
IF RESIZEWINDOW THEN
CONSOLE.WINDOWWIDTH = COLUMNS + 1
CONSOLE.WINDOWHEIGHT = ROWS
END IF
IF MONTHSPERROW < 1 THEN MONTHSPERROW = MATH.MAX(COLUMNS \ 22, 1)
FOR EACH ROW IN GETCALENDARROWS(DT:=DT, WIDTH:=COLUMNS, HEIGHT:=ROWS, MONTHSPERROW:=MONTHSPERROW, VERTSTRETCH:=VERTSTRETCH, HORIZSTRETCH:=HORIZSTRETCH)
CONSOLE.WRITE(ROW)
NEXT
END SUB
ITERATOR FUNCTION GETCALENDARROWS(
DT AS DATE,
WIDTH AS INTEGER,
HEIGHT AS INTEGER,
MONTHSPERROW AS INTEGER,
VERTSTRETCH AS BOOLEAN,
HORIZSTRETCH AS BOOLEAN) AS IENUMERABLE(OF STRING)
DIM YEAR = DT.YEAR
DIM CALENDARROWCOUNT AS INTEGER = CINT(MATH.CEILING(12 / MONTHSPERROW))
' MAKE ROOM FOR THE THREE EMPTY LINES ON TOP.
DIM MONTHGRIDHEIGHT AS INTEGER = HEIGHT - 3
YIELD "[SNOOPY]".PADCENTER(WIDTH) & ENVIRONMENT.NEWLINE
YIELD YEAR.TOSTRING(CULTUREINFO.INVARIANTCULTURE).PADCENTER(WIDTH) & ENVIRONMENT.NEWLINE
YIELD ENVIRONMENT.NEWLINE
DIM MONTH = 0
DO WHILE MONTH < 12
DIM ROWHIGHESTMONTH = MATH.MIN(MONTH + MONTHSPERROW, 12)
DIM CELLWIDTH = WIDTH \ MONTHSPERROW
DIM CELLCONTENTWIDTH = IF(MONTHSPERROW = 1, CELLWIDTH, (CELLWIDTH * 19) \ 20)
DIM CELLHEIGHT = MONTHGRIDHEIGHT \ CALENDARROWCOUNT
DIM CELLCONTENTHEIGHT = (CELLHEIGHT * 19) \ 20
' CREATES A MONTH CELL FOR THE SPECIFIED MONTH (1-12).
DIM GETMONTHFROM =
FUNCTION(M AS INTEGER) BUILDMONTH(
DT:=NEW DATE(DT.YEAR, M, 1),
WIDTH:=CELLCONTENTWIDTH,
HEIGHT:=CELLCONTENTHEIGHT,
VERTSTRETCH:=VERTSTRETCH,
HORIZSTRETCH:=HORIZSTRETCH).SELECT(FUNCTION(X) X.PADCENTER(CELLWIDTH))
' THE MONTHS IN THIS ROW OF THE CALENDAR.
DIM MONTHSTHISROW AS IENUMERABLE(OF IENUMERABLE(OF STRING)) =
ENUMERABLE.SELECT(ENUMERABLE.RANGE(MONTH + 1, ROWHIGHESTMONTH - MONTH), GETMONTHFROM)
DIM CALENDARROW AS IENUMERABLE(OF STRING) =
INTERLEAVED(
MONTHSTHISROW,
USEINNERSEPARATOR:=FALSE,
USEOUTERSEPARATOR:=TRUE,
OUTERSEPARATOR:=ENVIRONMENT.NEWLINE)
DIM EN = CALENDARROW.GETENUMERATOR()
DIM HASNEXT = EN.MOVENEXT()
DO WHILE HASNEXT
DIM CURRENT AS STRING = EN.CURRENT
' TO MAINTAIN THE (NOT STRICTLY NEEDED) CONTRACT OF YIELDING COMPLETE ROWS, KEEP THE NEWLINE AFTER
' THE CALENDAR ROW WITH THE LAST TERMINAL ROW OF THE ROW.
HASNEXT = EN.MOVENEXT()
YIELD IF(HASNEXT, CURRENT, CURRENT & ENVIRONMENT.NEWLINE)
LOOP
MONTH += MONTHSPERROW
LOOP
END FUNCTION
''' <SUMMARY>
''' INTERLEAVES THE ELEMENTS OF THE SPECIFIED SUB-SOURCES BY MAKING SUCCESSIVE PASSES THROUGH THE SOURCE
''' ENUMERABLE, YIELDING A SINGLE ELEMENT FROM EACH SUB-SOURCE IN SEQUENCE IN EACH PASS, OPTIONALLY INSERTING A
''' SEPARATOR BETWEEN ELEMENTS OF ADJACENT SUB-SOURCES AND OPTIONALLY A DIFFERENT SEPARATOR AT THE END OF EACH
''' PASS THROUGH ALL THE SOURCES. (I.E., BETWEEN ELEMENTS OF THE LAST AND FIRST SOURCE)
''' </SUMMARY>
''' <TYPEPARAM NAME="T">THE TYPE OF THE ELEMENTS OF THE SUB-SOURCES.</TYPEPARAM>
''' <PARAM NAME="SOURCES">A SEQUENCE OF THE SEQUENCES WHOSE ELEMENTS ARE TO BE INTERLEAVED.</PARAM>
''' <PARAM NAME="USEINNERSEPARATOR">WHETHER TO INSERT <PARAMREF NAME="USEINNERSEPARATOR"/> BETWEEN THE ELEMENTS OFADJACENT SUB-SOURCES.</PARAM>
''' <PARAM NAME="INNERSEPARATOR">THE SEPARATOR BETWEEN ELEMENTS OF ADJACENT SUB-SOURCES.</PARAM>
''' <PARAM NAME="USEOUTERSEPARATOR">WHETHER TO INSERT <PARAMREF NAME="OUTERSEPARATOR"/> BETWEEN THE ELEMENTS OF THE LAST AND FIRST SUB-SOURCES.</PARAM>
''' <PARAM NAME="OUTERSEPARATOR">THE SEPARATOR BETWEEN ELEMENTS OF THE LAST AND FIRST SUB-SOURCE.</PARAM>
''' <PARAM NAME="WHILEANY">IF <SEE LANGWORD="TRUE"/>, THE ENUMERATION CONTINUES UNTIL EVERY GIVEN SUBSOURCE IS EMPTY;
''' IF <SEE LANGWORD="FALSE"/>, THE ENUMERATION STOPS AS SOON AS ANY ENUMERABLE NO LONGER HAS AN ELEMENT TO SUPPLY FOR THE NEXT PASS.</PARAM>
ITERATOR FUNCTION INTERLEAVED(OF T)(
SOURCES AS IENUMERABLE(OF IENUMERABLE(OF T)),
OPTIONAL USEINNERSEPARATOR AS BOOLEAN = FALSE,
OPTIONAL INNERSEPARATOR AS T = NOTHING,
OPTIONAL USEOUTERSEPARATOR AS BOOLEAN = FALSE,
OPTIONAL OUTERSEPARATOR AS T = NOTHING,
OPTIONAL WHILEANY AS BOOLEAN = TRUE) AS IENUMERABLE(OF T)
DIM SOURCEENUMERATORS AS IENUMERATOR(OF T)() = NOTHING
TRY
SOURCEENUMERATORS = SOURCES.SELECT(FUNCTION(X) X.GETENUMERATOR()).TOARRAY()
DIM NUMSOURCES = SOURCEENUMERATORS.LENGTH
DIM ENUMERATORSTATES(NUMSOURCES - 1) AS BOOLEAN
DIM ANYPREVITERS AS BOOLEAN = FALSE
DO
' INDICES OF FIRST AND LAST SUB-SOURCES THAT HAVE ELEMENTS.
DIM FIRSTACTIVE = -1, LASTACTIVE = -1
' DETERMINE WHETHER EACH SUB-SOURCE THAT STILL HAVE ELEMENTS.
FOR I = 0 TO NUMSOURCES - 1
ENUMERATORSTATES(I) = SOURCEENUMERATORS(I).MOVENEXT()
IF ENUMERATORSTATES(I) THEN
IF FIRSTACTIVE = -1 THEN FIRSTACTIVE = I
LASTACTIVE = I
END IF
NEXT
' DETERMINE WHETHER TO YIELD ANYTHING IN THIS ITERATION BASED ON WHETHER WHILEANY IS TRUE.
' NOT YIELDING ANYTHING THIS ITERATION IMPLIES THAT THE ENUMERATION HAS ENDED.
DIM THISITERHASRESULTS AS BOOLEAN = IF(WHILEANY, FIRSTACTIVE <> -1, FIRSTACTIVE = 0 ANDALSO LASTACTIVE = NUMSOURCES - 1)
IF NOT THISITERHASRESULTS THEN EXIT DO
' DON'T INSERT A SEPARATOR ON THE FIRST PASS.
IF ANYPREVITERS THEN
IF USEOUTERSEPARATOR THEN YIELD OUTERSEPARATOR
ELSE
ANYPREVITERS = TRUE
END IF
' GO THROUGH AND YIELD FROM THE SUB-SOURCES THAT STILL HAVE ELEMENTS.
FOR I = 0 TO NUMSOURCES - 1
IF ENUMERATORSTATES(I) THEN
' DON'T INSERT A SEPARATOR BEFORE THE FIRST ELEMENT.
IF I > FIRSTACTIVE ANDALSO USEINNERSEPARATOR THEN YIELD INNERSEPARATOR
YIELD SOURCEENUMERATORS(I).CURRENT
END IF
NEXT
LOOP
FINALLY
IF SOURCEENUMERATORS ISNOT NOTHING THEN
FOR EACH EN IN SOURCEENUMERATORS
EN.DISPOSE()
NEXT
END IF
END TRY
END FUNCTION
''' <SUMMARY>
''' RETURNS THE ROWS REPRESENTING ONE MONTH CELL WITHOUT TRAILING NEWLINES. APPROPRIATE LEADING AND TRAILING
''' WHITESPACE IS ADDED SO THAT EVERY ROW HAS THE LENGTH OF WIDTH.
''' </SUMMARY>
''' <PARAM NAME="DT">A DATE WITHIN THE MONTH TO REPRESENT.</PARAM>
''' <PARAM NAME="WIDTH">THE WIDTH OF THE CELL.</PARAM>
''' <PARAM NAME="HEIGHT">THE HEIGHT.</PARAM>
''' <PARAM NAME="VERTSTRETCH">IF <SEE LANGWORD="TRUE" />, BLANK ROWS ARE INSERTED TO FIT THE AVAILABLE HEIGHT.
''' OTHERWISE, THE CELL HAS A CONSTANT HEIGHT OF </PARAM>
''' <PARAM NAME="HORIZSTRETCH">IF <SEE LANGWORD="TRUE" />, THE SPACING BETWEEN INDIVIDUAL DAYS IS INCREASED TO
''' FIT THE AVAILABLE WIDTH. OTHERWISE, THE CELL HAS A CONSTANT WIDTH OF 20 CHARACTERS AND IS PADDED TO BE IN
''' THE CENTER OF THE EXPECTED WIDTH.</PARAM>
ITERATOR FUNCTION BUILDMONTH(DT AS DATE, WIDTH AS INTEGER, HEIGHT AS INTEGER, VERTSTRETCH AS BOOLEAN, HORIZSTRETCH AS BOOLEAN) AS IENUMERABLE(OF STRING)
CONST DAY_WDT = 2 ' WIDTH OF A DAY.
CONST ALLDAYS_WDT = DAY_WDT * 7 ' WIDTH OF AL LDAYS COMBINED.
' NORMALIZE THE DATE TO JANUARY 1.
DT = NEW DATE(DT.YEAR, DT.MONTH, 1)
' HORIZONTAL WHITESPACE BETWEEN DAYS OF THE WEEK. CONSTANT OF 6 REPRESENTS 6 SEPARATORS PER LINE.
DIM DAYSEP AS NEW STRING(" "C, MATH.MIN((WIDTH - ALLDAYS_WDT) \ 6, IF(HORIZSTRETCH, INTEGER.MAXVALUE, 1)))
' NUMBER OF BLANK LINES BETWEEN ROWS.
DIM VERTBLANKCOUNT = IF(NOT VERTSTRETCH, 0, (HEIGHT - 8) \ 7)
' WIDTH OF EACH DAY * 7 DAYS IN ONE ROW + DAY SEPARATOR LENGTH * 6 SEPARATORS PER LINE.
DIM BLOCKWIDTH = ALLDAYS_WDT + DAYSEP.LENGTH * 6
' THE WHITESPACE AT THE BEGINNING OF EACH LINE.
DIM LEFTPAD AS NEW STRING(" "C, (WIDTH - BLOCKWIDTH) \ 2)
' THE WHITESPACE FOR BLANK LINES.
DIM FULLPAD AS NEW STRING(" "C, WIDTH)
' LINES ARE "STAGED" IN THE STRINGBUILDER.
DIM SB AS NEW STRINGBUILDER(LEFTPAD)
DIM NUMLINES = 0
' GET THE CURRENT LINE SO FAR FORM THE STRINGBUILDER AND BEGIN A NEW LINE.
' RETURNS THE CURRENT LINE AND TRAILING BLANK LINES USED FOR VERTICAL PADDING (IF ANY).
' RETURNS EMPTY ENUMERABLE IF THE HEIGHT REQUIREMENT HAS BEEN REACHED.
DIM ENDLINE =
FUNCTION() AS IENUMERABLE(OF STRING)
DIM FINISHEDLINE AS STRING = SB.TOSTRING().PADRIGHT(WIDTH)
SB.CLEAR()
SB.APPEND(LEFTPAD)
' USE AN INNER ITERATOR TO PREVENT LAZY EXECUTION OF SIDE EFFECTS OF OUTER FUNCTION.
RETURN IF(NUMLINES >= HEIGHT,
ENUMERABLE.EMPTY(OF STRING)(),
ITERATOR FUNCTION() AS IENUMERABLE(OF STRING)
YIELD FINISHEDLINE
NUMLINES += 1
FOR I = 1 TO VERTBLANKCOUNT
IF NUMLINES >= HEIGHT THEN RETURN
YIELD FULLPAD
NUMLINES += 1
NEXT
END FUNCTION())
END FUNCTION
' YIELD THE MONTH NAME.
SB.APPEND(PADCENTER(DT.TOSTRING("MMMM", CULTUREINFO.INVARIANTCULTURE), BLOCKWIDTH).TOUPPER())
FOR EACH L IN ENDLINE()
YIELD L
NEXT
' YIELD THE HEADER OF WEEKDAY NAMES.
DIM WEEKNMABBREVS = [ENUM].GETNAMES(GETTYPE(DAYOFWEEK)).SELECT(FUNCTION(X) X.SUBSTRING(0, 2).TOUPPER())
SB.APPEND(STRING.JOIN(DAYSEP, WEEKNMABBREVS))
FOR EACH L IN ENDLINE()
YIELD L
NEXT
' DAY OF WEEK OF FIRST DAY OF MONTH.
DIM STARTWKDY = CINT(DT.DAYOFWEEK)
' INITIALIZE WITH EMPTY SPACE FOR THE FIRST LINE.
DIM FIRSTPAD AS NEW STRING(" "C, (DAY_WDT + DAYSEP.LENGTH) * STARTWKDY)
SB.APPEND(FIRSTPAD)
DIM D = DT
DO WHILE D.MONTH = DT.MONTH
SB.APPENDFORMAT(CULTUREINFO.INVARIANTCULTURE, $"{{0,{DAY_WDT}}}", D.DAY)
' EACH ROW ENDS ON SATURDAY.
IF D.DAYOFWEEK = DAYOFWEEK.SATURDAY THEN
FOR EACH L IN ENDLINE()
YIELD L
NEXT
ELSE
SB.APPEND(DAYSEP)
END IF
D = D.ADDDAYS(1)
LOOP
' KEEP ADDING EMPTY LINES UNTIL THE HEIGHT QUOTA IS MET.
DIM NEXTLINES AS IENUMERABLE(OF STRING)
DO
NEXTLINES = ENDLINE()
FOR EACH L IN NEXTLINES
YIELD L
NEXT
LOOP WHILE NEXTLINES.ANY()
END FUNCTION
''' <SUMMARY>
''' RETURNS A NEW STRING THAT CENTER-ALIGNS THE CHARACTERS IN THIS STRING BY PADDING TO THE LEFT AND RIGHT WITH
''' THE SPECIFIED CHARACTER TO A SPECIFIED TOTAL LENGTH.
''' </SUMMARY>
''' <PARAM NAME="S">THE STRING TO CENTER-ALIGN.</PARAM>
''' <PARAM NAME="TOTALWIDTH">THE NUMBER OF CHARACTERS IN THE RESULTING STRING.</PARAM>
''' <PARAM NAME="PADDINGCHAR">THE PADDING CHARACTER.</PARAM>
<EXTENSION()>
PRIVATE FUNCTION PADCENTER(S AS STRING, TOTALWIDTH AS INTEGER, OPTIONAL PADDINGCHAR AS CHAR = " "C) AS STRING
RETURN S.PADLEFT(((TOTALWIDTH - S.LENGTH) \ 2) + S.LENGTH, PADDINGCHAR).PADRIGHT(TOTALWIDTH, PADDINGCHAR)
END FUNCTION
END MODULE</syntaxhighlight>
{{out|input=COLS:132 ROWS:25 MS/ROW:6 HSTRETCH:FALSE VSTRETCH:FALSE}}
<pre> [SNOOPY]
1969
JANUARY FEBRUARY MARCH APRIL MAY JUNE
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 1 1 1 2 3 4 5 1 2 3 1 2 3 4 5 6 7
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14
12 13 14 15 16 17 18 9 10 11 12 13 14 15 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21
19 20 21 22 23 24 25 16 17 18 19 20 21 22 16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28
26 27 28 29 30 31 23 24 25 26 27 28 23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31 29 30
30 31
JULY AUGUST SEPTEMBER OCTOBER NOVEMBER DECEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5 1 2 1 2 3 4 5 6 1 2 3 4 1 1 2 3 4 5 6
6 7 8 9 10 11 12 3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
13 14 15 16 17 18 19 10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
27 28 29 30 31 24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
31 30
</pre>
=={{header|Wren}}==
Strictly speaking, ''real'' programming is impossible in Wren which is case sensitive and keywords, library classes, methods etc. never use all upper case letters.
We therefore do what other languages in a similar predicament have done and begin by creating an all upper case version of the calendar program called ''calendar_real_uc.txt'':
{{libheader|Wren-date}}
{{libheader|Wren-fmt}}
{{libheader|Wren-seq}}
<syntaxhighlight lang="text">IMPORT "./DATE" FOR DATE
IMPORT "./FMT" FOR FMT
IMPORT "./SEQ" FOR LST
VAR CALENDAR = FN.NEW { |YEAR|
VAR SNOOPY = "🐶"
VAR DAYS = "SU MO TU WE TH FR SA"
VAR MONTHS = [
"JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
"JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
]
FMT.PRINT("$70M", SNOOPY)
VAR YEARSTR = "--- %(YEAR) ---"
FMT.PRINT("$70M\N", YEARSTR)
VAR FIRST = LIST.FILLED(3, 0)
VAR MLEN = LIST.FILLED(3, 0)
VAR C = 0
FOR (CHUNK IN LST.CHUNKS(MONTHS, 3)) {
FOR (I IN 0..2) FMT.WRITE("$20M ", CHUNK[I])
SYSTEM.PRINT()
FOR (I IN 0..2) SYSTEM.WRITE("%(DAYS) ")
SYSTEM.PRINT()
FIRST[0] = DATE.NEW(YEAR, C*3 + 1, 1).DAYOFWEEK % 7
FIRST[1] = DATE.NEW(YEAR, C*3 + 2, 1).DAYOFWEEK % 7
FIRST[2] = DATE.NEW(YEAR, C*3 + 3, 1).DAYOFWEEK % 7
MLEN[0] = DATE.MONTHLENGTH(YEAR, C*3 + 1)
MLEN[1] = DATE.MONTHLENGTH(YEAR, C*3 + 2)
MLEN[2] = DATE.MONTHLENGTH(YEAR, C*3 + 3)
FOR (I IN 0..5) {
FOR (J IN 0..2) {
VAR START = 1 + 7 * I - FIRST[J]
FOR (K IN START..START+6) {
IF (K >= 1 && K <= MLEN[J]) {
FMT.WRITE("$2D ", K)
} ELSE {
SYSTEM.WRITE(" ")
}
}
SYSTEM.WRITE(" ")
}
SYSTEM.PRINT()
}
SYSTEM.PRINT()
C = C + 1
}
}
CALENDAR.CALL(1969)</syntaxhighlight>
We then create a script called ''calendar_real.wren'' which takes the above text file as input, changes those items which cannot be upper case into their normal casing and compiles and runs the result:
{{libheader|Wren-str}}
<syntaxhighlight lang="wren">import "io" for File
import "./str" for Str
import "meta" for Meta
var keywords = ["import", "for", "var", "in", "if", "else"]
var modules = ["/date", "/fmt", "/seq"]
var classes = ["Date", "Fmt", "Lst", "Fn", "List", "System"]
var methods = ["print", "filled", "chunks", "write", "new", "dayOfWeek", "monthLength", "call"]
var formats = ["$70m", "\\n", "$20m", "$2d"]
var text = File.read("calendar_real_uc.txt")
for (keyword in keywords) text = text.replace(Str.upper(keyword) + " ", keyword + " ")
for (module in modules) text = text.replace(Str.upper(module), module)
for (clazz in classes) text = text.replace(Str.upper(clazz), clazz)
for (method in methods) text = text.replace("." + Str.upper(method), "." + method)
for (format in formats) text = text.replace(Str.upper(format), format)
Meta.compile(text).call()</syntaxhighlight>
{{out}}
<pre>
🐶
--- 1969 ---
JANUARY FEBRUARY MARCH
SU MO TU WE TH FR
1 2 3 4
26 27 28 29 30 31 23 24
30 31
APRIL MAY JUNE
SU MO TU WE TH FR
1 2 3 4 5
6 7 8 9 10 11 12 4
13 14 15 16 17 18 19 11 12 13
20 21 22 23 24 25 26 18 19 20
27 28 29 30 25 26 27 28 29 30 31 29 30
JULY AUGUST SEPTEMBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4 5
6 7 8 9 10 11 12 3
13 14 15 16 17 18 19 10 11 12 13 14 15
20 21 22 23 24 25 26 17 18 19 20 21 22 23 21 22 23 24 25 26 27
27 28 29 30 31 24 25
31
OCTOBER
SU MO TU WE TH FR SA SU MO TU WE TH FR SA SU MO TU WE TH FR SA
1 2 3 4
5 6 7 8 9 10 11 2 3 4 5 6 7 8 7 8 9 10 11 12 13
12 13 14 15 16 17 18 9 10 11 12 13 14 15 14 15 16 17 18 19 20
19 20 21 22 23 24 25 16 17 18 19 20 21 22 21 22 23 24 25 26 27
26 27 28 29 30 31 23 24 25 26 27 28 29 28 29 30 31
</pre>
=={{header|X86 Assembly}}==
ASSEMBLE WITH: TASM CALENDAR; TLINK /t CALENDAR
<
.CODE
.486
Line 2,738 ⟶ 4,788:
DAYS DB 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
DAY DB ?, ?, ?, ?, ?, ?
END START</
{{Out}}
Line 2,763 ⟶ 4,813:
31 30
</pre>
=={{header|XLISP}}==
XLISP isn't case-sensitive, so in principle it would be possible just to reproduce the solution given in the "ordinary" Calendar task. But that program makes use of recursion, "fancy" data structures, long variable names, pretty-printy indentation, and a whole host of other features that I don't think REAL programmers like any better than they like lower case: so, instead, here is a version using only global variables and "<tt>DO</tt> loops like God meant them to be".
<syntaxhighlight lang="lisp">(SETQ YR 1969)
(SETQ M #("JANUARY" "FEBRUARY" "MARCH" "APRIL" "MAY" "JUNE" "JULY" "AUGUST" "SEPTEMBER" "OCTOBER" "NOVEMBER" "DECEMBER"))
(SETQ ML #(31 28 31 30 31 30 31 31 30 31 30 31))
(SETQ WD #("SU" "MO" "TU" "WE" "TH" "FR" "SA"))
(IF (AND (= (REM YR 4) 0) (OR (/= (REM YR 100) 0) (= (REM YR 400) 0))) (VECTOR-SET! ML 1 29))
(SETQ D (REM (+ 1 (+ (* 5 (REM (- YR 1) 4)) (* 4 (REM (- YR 1) 100)) (* 6 (REM (- YR 1) 400)))) 7))
(TERPRI)
(DO ((I 0 (+ I 1))) ((> I 60))
(PRINC " "))
(PRINC "SNOOPY CALENDAR ")
(PRINC YR)
(TERPRI)
(DO ((I 0 (+ I 1))) ((> I 11))
(TERPRI)
(DO ((J 0 (+ J 1))) ((> J 65))
(PRINC " "))
(PRINC (VECTOR-REF M I))
(TERPRI)
(PRINC " ")
(DO ((J 0 (+ J 1))) ((> J 6))
(DO ((K 0 (+ K 1))) ((> K 14))
(PRINC " "))
(PRINC (VECTOR-REF WD J))
(PRINC " "))
(TERPRI)
(DO ((J 0 (+ J 1))) ((> J 6))
(IF (< J D) (DO ((K 0 (+ K 1))) ((> K 18)) (PRINC " "))))
(DO ((J 1 (+ J 1))) ((> J (VECTOR-REF ML I)))
(PRINC " ")
(IF (< J 10) (PRINC " "))
(DO ((K 0 (+ K 1))) ((> K 14))
(PRINC " "))
(PRINC J)
(SETQ D (+ D 1))
(IF (> D 6) (TERPRI))
(IF (> D 6) (SETQ D 0))))</syntaxhighlight>
{{out}}
<pre> SNOOPY CALENDAR 1969
JANUARY
SU MO TU WE TH FR SA
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
FEBRUARY
SU MO TU WE TH FR SA
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
MARCH
SU MO TU WE TH FR SA
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
APRIL
SU MO TU WE TH FR SA
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
MAY
SU MO TU WE TH FR SA
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
JUNE
SU MO TU WE TH FR SA
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
JULY
SU MO TU WE TH FR SA
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
AUGUST
SU MO TU WE TH FR SA
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
SEPTEMBER
SU MO TU WE TH FR SA
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
OCTOBER
SU MO TU WE TH FR SA
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
NOVEMBER
SU MO TU WE TH FR SA
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
DECEMBER
SU MO TU WE TH FR SA
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31</pre>
=={{header|zkl}}==
{{trans|D}}
Using a large helping of grease, in the form of a pre-processor.
The calendar code, file UPCAL.zkl (upper cased version of [[Calendar#zkl]]):
<syntaxhighlight lang="zkl">VAR [CONST] D=TIME.DATE, DAYS="SU MO TU WE TH FR SA";
FCN CENTER(TEXT,M) { STRING(" "*((M-TEXT.LEN())/2),TEXT) }
FCN ONEMONTH(YEAR,MONTH){
DAY1:=D.ZELLER(YEAR,MONTH,1); //1969-1-1 -->3 (WED, ISO 8601)
DAYZ:=D.DAYSINMONTH(YEAR,MONTH); //1969-1 -->31
LIST(CENTER(D.MONTHNAMES[MONTH],DAYS.LEN()),DAYS).EXTEND(
(1).PUMP(DAYZ,(0).PUMP(DAY1,LIST,T(VOID,""))).APPLY("%2S ".FMT)
.PUMP(LIST,T(VOID.READ,DAYS.LEN()/3,FALSE),STRING.CREATE));
}
...</syntaxhighlight>
And the pre-processor, hand rolled for the above code (file bbb.zkl):
<syntaxhighlight lang="zkl">code:=File(vm.arglist[0]).read();
code=Data(Void,code.text.toLower());
mixed:=T("string","String", "list","List", " t("," T(",",t(",",T(",
".tostring",".toString", "void.read","Void.Read",
"time.date","Time.Date", "utils.","Utils.", "zipwith","zipWith",
"daysinmonth","daysInMonth", "monthnames","monthNames",
"void","Void", "false","False",
"d.october","d.October",
);
mixed.pump(Void,Void.Read,'wrap(up,down){ code.replace(up,down) });
Compiler.Compiler.compileText(code)();</syntaxhighlight>
{{out}}
<pre>
$ zkl bbb UPCAL.zkl
3 days of peace & music
1969
January February March
su mo tu we th fr sa su mo tu we th fr sa su mo tu we th fr sa
1 2 3 4 1 1
5 6 7 8 9 10 11 2 3 4 5 6 7 8 2 3 4 5 6 7 8
...
</pre>
{{omit from|C sharp|keywords are lower case}}
{{omit from|C++}}
{{omit from|Clojure|Clojure's keywords are lower case}}
{{omit from|D|D's keywords are lower case}}
{{omit from|
{{omit from|Haskell|Haskell reserves words starting with uppercase letters for datatypes.}}
{{omit from|Java|Java's keywords are lower case}}
{{omit from|Mathematica}}
{{omit from|Processing|Processing's keywords are lower case}}
{{omit from|Python}}
{{omit from|
{{omit from|zkl|boogers to upper case}}
|