c-intercal 28.0Version of implementation C-INTERCAL of programming language INTERCAL
A version of C-INTERCAL interpreter, released on April 1st, 2008.
INTERCAL is one of the languages in which even writing “Hello, World!” is a torture. The trick is, C-INTERCAL’s command
READ OUT implements character output on Turing Tape method. To use it, the output argument must be an array, which we have stored in
, means that the variable is an array of 16-bit integers). The values of the array produce output one by one, from left to right. To figure out what character to output based on i-th element of the array, the compiler performs the following actions:
Bit-reverse ASCII-code of previous printed character (assuming it’s 8-bit) to get
rev(i-1). When outputting first element of the array, this is assumed to be 0.
Get the i-th element of the array
rev(i)to get ASCII-code of the character to be printed i-th.
Another thing to note is the usage of
PLEASE modifier. This program must contain 4 or 5
PLEASE, the lines where they are located don’t really matter. 3 or less
PLEASE result in “ICL079I PROGRAMMER IS INSUFFICIENTLY POLITE” error, while 6 or more yield “ICL099I PROGRAMMER IS OVERLY POLITE” error.
Other commands and expressions are trivial (at least compared to previous ones):
# is a constant prefix,
<- is assignment,
SUB is subscript of an array. The first line of the example states that
,1 is an array of 16-bit integers, and it will have 13 elements.
DO ,1 <- #13 PLEASE DO ,1 SUB #1 <- #238 DO ,1 SUB #2 <- #108 DO ,1 SUB #3 <- #112 DO ,1 SUB #4 <- #0 DO ,1 SUB #5 <- #64 DO ,1 SUB #6 <- #194 PLEASE DO ,1 SUB #7 <- #48 DO ,1 SUB #8 <- #26 DO ,1 SUB #9 <- #244 PLEASE DO ,1 SUB #10 <- #168 DO ,1 SUB #11 <- #24 DO ,1 SUB #12 <- #16 DO ,1 SUB #13 <- #162 PLEASE READ OUT ,1 PLEASE GIVE UP
This example uses iterative definition of Fibonacci numbers. Variables .10 and .11 store previous and current calculated numbers, and .9 stores the number of iterations left.
Loop body is quite simple: print current number .11, copy .10 and .11 to .1 and .2, add them (
(1009) NEXT calls addition from standard library and puts sum to .3) and update the values. The trickiest part of the program is the code that implements looping behavior. Here is what it does.
(3) NEXT and
(4) NEXT move execution to label (4). At this line the loop counter .9 is updated by subtracting 1 from it (call of
(1010)). After this, .1 is calculated in a rather complicated way that makes it 1 if .9 is non-zero, and 0 otherwise. After this, .1 is incremented to be 1 if the loop has to stop (loop counter is zero) and 2 otherwise. Finally,
RESUME .1 is performed to return to one of the
NEXTs applied. If
.1 is 2, the program returns two
NEXTs back, and continues with
DO (1) NEXT which brings it to the start of the loop again. However, if
.1 is 1, the program returns one
NEXT back, continues with
PLEASE GIVE UP and halts.
Note that numbers are printed in Roman notation (this language lets not a single thing be easy!), one number per two lines (line which is empty in this example is for modifiers), so the output looks like this:
DO .9 <- #16 DO .10 <- #0 DO .11 <- #1 (1) PLEASE READ OUT .11 DO .1 <- .10 DO .2 <- .11 PLEASE (1009) NEXT DO .10 <- .11 DO .11 <- .3 DO (3) NEXT DO (1) NEXT (3) DO (4) NEXT PLEASE GIVE UP (4) DO .1 <- .9 DO .2 <- #1 PLEASE (1010) NEXT DO .9 <- .3 DO .1 <- '.9~.9'~#1 PLEASE (1020) NEXT DO RESUME .1
This example uses iterative factorial definition. The looping part is similar to Fibonacci example, the body differs, but only a little bit. Note usage of
: prefix for variables instead of
. — the former means 32-bit variables, and the latter — 16-bit ones. The output looks as follows (numbers go in pairs, n and n!, and each number takes two lines to be written):
_ I I I II II III VI IV XXIV V CXX VI DCCXX VII _ VXL VIII __ XLCCCXX IX _____ CCCLXMMDCCCLXXX X ___________ MMMDCXXVIIIDCCC XI _____ xxxixCMXVIDCCC XII cdlxxixMDC XIII ___ mcmxxxMMLMMMDIV XIV _____ mcclxxviiiCMXLVCCLXXX XV ____ mmivCCCXXVI XVI _______ mmivCLXXXIXCLXXXIV
C-INTERCAL uses Roman notation, in which a bar over a numeral multiplies its value by 1000, and writing a letter in lowercase multiplies its value by 1000000.
DO .9 <- #17 DO :10 <- #0 DO :11 <- #1 DO :2 <- :10 (1) PLEASE READ OUT :10 PLEASE READ OUT :11 DO :1 <- #1 PLEASE (1509) NEXT DO :10 <- :3 DO :2 <- :10 DO :1 <- :11 PLEASE (1549) NEXT DO :11 <- :3 DO (3) NEXT DO (1) NEXT (3) DO (4) NEXT PLEASE GIVE UP (4) DO .1 <- .9 DO .2 <- #1 PLEASE (1010) NEXT DO .9 <- .3 DO .1 <- '.9~.9'~#1 PLEASE (1020) NEXT DO RESUME .1