The Atlas Autocode language is documented in several places:
We have here two sources for the Atlas Autocode compiler on the KDF9 - Version 4F (with latest date 20 April 1965) uses the Flexowriter character set, and Version 4G (with earliest date 4 May 1965) has been converted to use the ISO character set (effectively the same as ASCII).
Version 4F only exists as a scan of a listing that appears to have been made on some device similar to a Roneo thermal stencil duplicator; however the newer version was recovered as text from a paper tape file at the ERCC.
Although there is a note by the person who scanned the 4F listing that suggests that the listing is incomplete, comparing it against the 4G listing strongly suggests that it is indeed all there, and mostly readable to the extent that a re-keying exercise could be considered.
The listing above, which is using the Flexowriter character set, can be read in conjunction with the 4G source below which was recovered from paper tape and which uses the 7-bit ISO character set — this side-by-side comparison solves some of the unanswered questions as to what some of the characters in the paper tape source actually represented, such as $ turned out to be π, and ` was actually α.
Version 4G was found on a paper tape at the E.R.C.C. labelled 'imp9', but the code is clearly the
Atlas Autocode compiler. This may have come from the time when Edinburgh was
about to make changes to the language and rename it as Imp. The '9' most likely
refers to the "KDF9" rather than the similarly-named "Imp9" which was
Version 9 of the Imp compiler that came much later.
Note that the file above is actually the concatenation of these three
separate paper tapes:
'IMP9 compiler tape 1 imp.txt'
'IMP9 compiler tape 2 imp.txt'
'IMP9 compiler tape 3 imp.txt'
We believe that 'IMP9 perm tape 1 imp.txt' and 'IMP9 perm tape 2 imp.txt' are actually the "perms" material for the above Version 4G compiler. Note that some of these files contain binary characters such as NUL runoff bytes, which causes them to be downloaded by your browser rather than being viewed in a web page. We'll supply browsable versions soon.
Confirmation of the version numbers and dates comes from the listings:
4G:
SW(13): M10=0; M13=0; ![*][*][*][A][S] 10/12/65 FOR ISO VERSION %ROUTINE CSEXP(%INTEGER Z) %COMMENT DATED 5/8/65 - FOR VER 4G WITH NEW PHRASE STUCTURE %ROUTINE CCOND %COMMENT DATED 4/6/65 - FOR VER 4G WITH NEW PHRASE STRUCTURE
vs 4F:
501: comment [*] [*] [*] [A] [ S] routine cSEXP(integer Z) ; comment dated 20/4/65 - FOR VER 4F routine cCOND ; comment DATED 17/3/65 - FOR VER 2F
As an aside, there was some confusion over the use of "**`" and "**@" in the 4G listing. Comparing parts of it to the 4F equivalent seems to clear up the confusion:
EE(1): %COMMENT [*] [`] [NAME] [APP] P = P +1 CNAME(3) -> 9 EE(2): %COMMENT [*] ['] [NAME] [APP] P = P + 2 CNAME (A(P-1)) -> 9
Vs 4F:
e(1): %comment [*] [α] [NAME] [APP] p = p +3 cNAME(3) -> 9 e(2): %comment [*] [='] [NAME] [APP] p = p +4 cNAME (A(p-2)) -> 9
It looks like ` was the transliteration of α that happened when the original files were automatically converted from Flexowriter code, but @ was used as a more convenient and mnemonic substitute for α when new code was entered manually, subsequent to the conversion to the ISO character set. This is suggested by the fact that the code fragments in 4G containing **@ have no equivalent in 4F.
NOTE: This was later confirmed when the grammar to table conversion program for the "IMP50" grammar was compiled with the current Imp compiler. Running it on the original grammar file gave an error until an entry C"`" was corrected to C"@". Clearly "`" was the earlier form or the result of an early transliteration program, and "@" was the desired character to be used in future. That experiment can be seen in the imp50/ subdirectory.
In 1965 Version I of Atlas Autocode for the KDF9 was in production at Edinburgh
on their local machine. User documentation was supplied in
Computer Unit Report No. 1 (Programming in Atlas Autocode) (Version of 3rd March 1964;
Revised Version of 28th June 1965)
and Computer Unit Report No. 4 (Atlas Autocode Compiler for KDF9). (C. U. Report No. 4, pp. 11-12, includes the original pre-ISO grammar of which later versions are reproduced below.)
Version I was written entirely in Imp(AA) rather than containing embedded KDF9 assembly code. This was the first stage
in porting IMP(AA) from the KDF9 to the ICL 4/75. The Version I compiler is documented in these three files:
Vol. 1
Vol. 2
Vol. 3 - these files contain documentation, flow charts, and some source code. The Version I compiler would have been built using the existing Version F or version G compiler. The "perms" material is in a separate file.
The general algorithm and design of the grammar is explained in A General Translation Program for Phrase Structure Languages by Brooker & Morris.
By the following year I believe we were up to Version K of the KDF9 Atlas Autocode compiler. We don't have the source code but we do have the grammar that describes the language. The Version K grammar below came to us from Harry Whitfield, who I believe re-keyed it from a paper listing. (One typo has been corrected: "ADN" was typed in place of "AND" at one point. There may be other undetected errors.) We also have this line-printer listing of a pre-4F grammar although I haven't identified the version yet. (The line-printer listing is interesting in that it shows the transliteration of the Flexowriter character set into the more restricted character set which is a subset of ASCII.) The use of accept m/c instructions as opposed to mcode suggests it is quite an early version. Incidentally, the use of the data type complex described in the manual appears to be a feature that was only supported on the original Atlas implementation. It is missing from all of the KDF9 references we can find.
Atlas Autocode Compiler for KDF9 - Version K - Syntax ----------------------------------------------------- Version K was the (first) ISO code version and was produced sometime in the middle of 1966. In the following the C statements introduce the terminal symbols, the D statements introduce the non-terminal symbols, the P statements define the syntax, and the E statement marks the end of the syntax. A large part of the syntax is concerned with the definition of KDF9 machine code (user code) which could be placed in-line. Perhaps the most important semantic difference between Atlas Autocode and (later versions of) IMP was the wordlength. In Atlas Autocde on KDF9, both integers and reals were 48 bit. IMP was designed to have 32 bit integers to imitate System 4. Harry Whitfield (26/02/2002). C"+" C"-" C"*" C"/" C"^" C"(" C")" C"," C"?" C"!" C":" C"=" C">=" C">" C"#" C"<" C"<=" C"->" C"%IF" C"%UNLESS" C"%INTEGER" C"%REAL" C"%FN" C"%MAP" C"%NAME" C"%ROUTINE" C"%ARRAY" C"%AND" C"%OR" C"%CAPTION" C"%RESULT=" C"%RETURN" C"%STOP" C"%THEN" C"%CYCLE" C"%REPEAT" C"%SPEC" C"%BEGIN" C"%COMMENT" C"%END" C"%PROGRAM" C"%IGNORE" C"%SWITCH" C"%UPPER" C"%DELIMITERS" C"%NORMAL" C"%CASE" C"%COMPILE" C"%QUERIES" C"%ADDR" C"%DEFINE" C"%R" C"%PERM" C"T" C"%MCODE" C"%OF" C"%STRINGS" C"%FAULT" C"%MONITOR" C"@" C"J" C"SET" C"JS" C"EXIT" C"M" C"SH" C"Q" C"TOQ" C"C" C"I" C"IM" C"CM" C"CI" C"NC" C"DC" C"LINK" C"HF" C"F" C"H" C"ROUND" C"D" C"FLOAT" C"ERASE" C"REV" C"ZERO" C"DUP" C"DF" C"NEG" C"ABS" C"MAX" C"SIGN" C"CAB" C"FRB" C"STAND" C"/R" C"/I" C"/X" C"=TR" C"BITS" C"DUMMY" C"PERM" C"TOP" C"OR" C"VR" C"NEV" C"NOT" C"FIX" C"STR" C"CONT" C"AND" C"OUT" C"S" C"NZ" C"Z" C"V" C"NV" C"EN" C"NEN" C"EJ" C"NEJ" C"TR" C"NTR" C"QHN" C"QH" C"QN" C"HN" C"N" C"A" C"AD" C"L" C"LD" C"AC" C"ADC" C"LC" C"LDC" C"CC" C"RC" C"RI" C"RM" C"+Q" C"+C" C"+I" C"+M" C"P" C"B" C"O" C"E" C"TLOQ" C"INTQ" C"PARQ" C"BUSYQ" C"MANUALQ" C"CTQ" C"CLOQ" C"ADVCA" D[NAME] D[CONST] D[N] D[S] D[TEXT] D[CAPTIONTEXT] D[OCTAL] D[SETMARKER1] D[SETMARKER2] D[+'] D[OPERAND] D[APP] D[OP] D[QUERY'] D[,'] D[%IU] D[%REAL'] D[TYPE] D[TYPE'] D[RESTOFARRAYLIST] D[RESTOFFP-LIST] D[RESTOFEXPR-LIST] D[RESTOFUI] D[RESTOFNAMELIST] D[%SPEC'] D[RESTOFSWITCHLIST] D[RESTOFPP-LIST] D[RESTOFEXPR] D[RESTOFCOND] D[RESTOFAND-C] D[RESTOFOR-C] D[RESTOFSC] D[RT] D[FPP] D[FP-DELIMITER] D[SC] D[COMP] D[RESTOFSS1] D[RESTOFN-LIST] D[RESTOFFAULTLIST] D[UCI] D[J-INSTR] D[MS-INSTR] D[SH-INSTR] D[QS-INSTR] D[+] D[='] D[P'] D[IOM] D[ATOF] D[E-INSTR] D[UI] D[SS] P[+']= "+","-",0; P[OPERAND]= [NAME][APP],[CONST],"("[+'][OPERAND][RESTOFEXPR]")","!"[+'][OPERAND][RESTOFEXPR]"!"; P[RESTOFEXPR]= [OP][OPERAND][RESTOFEXPR],0; P[APP]= "("[+'][OPERAND][RESTOFEXPR][RESTOFEXPR-LIST]")",0; P[RESTOFEXPR-LIST]= ","[+'][OPERAND][RESTOFEXPR][RESTOFEXPR-LIST],0; P[OP]= "+","-","*","/","^",0; P[QUERY']= "?",0; P[,']= ",",0; P[%IU]= "%IF","%UNLESS"; P[%REAL']= "%REAL",0; P[TYPE]= "%INTEGER","%REAL"; P[TYPE']= "%INTEGER","%REAL",0; P[RT]= "%ROUTINE","%REAL""%FN","%INTEGER""%FN","%REAL""%MAP","%INTEGER""%MAP"; P[FP-DELIMITER]= [RT],"%INTEGER""%ARRAY""%NAME","%INTEGER""%NAME","%INTEGER", [%REAL']"%ARRAY""%NAME","%REAL""%NAME","%REAL","%ADDR"; P[FPP]= "("[FP-DELIMITER][NAME][RESTOFNAMELIST][RESTOFFP-LIST]")",0; P[RESTOFFP-LIST]= [,'][FP-DELIMITER][NAME]RESTOFNAMELIST][RESTOFFP-LIST],0; P[RESTOFNAMELIST]= ","[NAME][RESTOFNAMELIST],0; P[SC]= [+'][OPERAND][RESTOFEXPR][COMP][+'][OPERAND][RESTOFEXPR][RESTOFSC],"("[SC][RESTOFCOND]")"; P[RESTOFSC]= [COMP][+'][OPERAND][RESTOFEXPR],0; P[RESTOFCOND]= "%AND"[SC][RESTOFAND-C],"%OR"[SC][RESTOFOR-C],0; P[RESTOFAND-C]= "%AND"[SC][RESTOFAND-C],0; P[RESTOFOR-C]= "%OR"[SC][RESTOFOR-C],0; P[RESTOFUI]= "="[+'][OPERAND][RESTOFEXPR][QUERY'],0; P[%SPEC']= "%SPEC",0; P[RESTOFFPP-LIST]= ","[+'][OPERAND][RESTOFEXPR]":"[+'][OPERAND][RESTOFEXPR][RESTOFFPP-LIST],0; P[RESTOFARRAYLIST]= ","[NAME][RESTOFNAMELIST]"("[+'][OPERAND][RESTOFEXPR] ":" [+'][OPERAND][RESTOFEXPR][RESTOFFPP-LIST]")"[RESTOFARRAYLIST],0; P[RESTOFSWITCHLIST]= ","[NAME][RESTOFNAMELIST]"("[+'][CONST]":"[+'][CONST]")"[RESTOFSWITCHLIST],0; P[COMP]= "=",">=",">","#","<=","<"; P[RESTOFSS1]= [S],[%IU][SC][RESTOFCOND][S]; P[RESTOFFN-LIST]= ","[N][RESTOFFN-LIST],0; P[RESTOFFAULTLIST]= ","[N][RESTOFFN-LIST]"->"[N][RESTOFFAULTLIST],0; P[UCI]= "*""@"[NAME][APP],"*"[='][NAME][APP],"J"[N][P'][J-INSTR], "SET""B"[OCTAL]."SET"[N]"P"":","JS"[N][P'],"EXIT"[N], [=']"M"[N]"M"[N][MS-INSTR],"SH"[SH-INSTR],"="[QS-INSTR], "Q"[N]"TOQ"[N],"C"[N]"TOQ"[N],"I"[N]"TOQ"[N],"M"[N]"TOQ"[N], "IM"[N]"TOQ"[N],"CM"[N]"TOQ"[N],"CI"[N]"TOQ"[N]."I"[N]"="[+'][N], "Q"[N],"C"[N],"I"[N],"M"[N],"NC"[N],"DC"[N],"LINK","M"[+]"I"[N], "X""+"[+'][N],"X""+""C"[N],"ROUND""H""F","ROUND""F","ROUND""H","ROUND","FLOAT""D", "FLOAT","ERASE","REV""D","REV","ZERO","DUP""D","DUP","NEG""DF","NEG""F", "NEG""D","NEG","ABS""F","ABS","MAX""F","MAX","SIGN""F","SIGN","CAB","FRB", "STAND","/""DF","/""D","/""F","/R","/I","/","+""DF","+""D","+""F","+", "-""DF","-""D","-""F","-","X""DF","X""D","X""F","X""+""F","X""+","=TR","BITS", "DUMMY","PERM","TOP","OR","VR","NEV","NOT","FIX","STR","CONT", "AND","EXIT","OUT","X","P"[IOM][ATOF]"Q"[N],"TLOG"[N], "INTQ"[N],"PARQ"[N],"BUSYQ"[N],"MANUALQ"[N],"CTQ"[N],"CLOQ"[N], "SET"[+'][N],"ADVCA"[N],[OCTAL]"/"[OCTAL]"/"[OCTAL],[=']"F"[N][E-INSTR], "JS""E"[N],"J""E"[N],0; P[J-INSTR]= "C"[N]"NZ""S","C"[N]"NZ","C"[N]"Z","=""Z","=","#""Z","#",">""Z",">=""Z", "<""Z","<=""Z","V","NV","EN","NEN","FJ","NFJ","TR","NTR",0; P[MS-INSTR]= "QHN","QH","QN","Q","HN","H","N",0; P[SH-INSTR]= "A"[+'][N],"AD"[+'][N],"L"[+'][N],"LD"[+'][N], "C"[+'][N],"AC"[N],"ADC"[N],"LC"[N],"LDC"[N],"CC"[N]; P[QS-INSTR]= "LINK","Q"[N],"C"[N],"I"[N],"M"[N],"RC"[N],"RI"[N],"RM"[N], "+Q"[N],"+C+[N],"=I"[N],"+M"[N]; P[+]="+","-"; P[=']="=",0; P[P']="P",0; P[IOM]="I","O","M"; P[ATOF]="A","B","C","D","E","F"; P[E-INSTR]="M"[N]"Q","M"[N],0; P[UI]= [NAME][APP][SETMARKER1][RESTOFUI], "->"[N], "%CAPTION"[CAPTIONTEXT], "%RETURN", "%RESULT="[+'][OPERAND][RESTOFEXPR], "%STOP", "->"[NAME]"("[+'][OPERAND][RESTOFEXPR]")", "%MONITOR"[N]; P[SS]= [UI][SETMARKER2][RESTOFSS1], "%CYCLE"[NAME][APP]"="[+'][OPERAND][RESTOFEXPR]","[+'][OPERAND][RESTOFEXPR] ","[+'][OPERAND][RESTOFEXPR][S], "%REPEAT"[S], [N]":", [%IU][SC][RESTOFCAND]"%THEN"[UI][S], "!"[TEXT], [TYPE][NAME][RESTOFNAMELIST][S], "%END"[S], [RT][%SPEC'][NAME][FPP][S], "%SPEC"[NAME][FPP][S], "%COMMENT"[TEXT], [TYPE']"%ARRAY"[NAME][RESTOFNAMELIST]"("[+'][OPERAND][RESTOFEXPR]":" [+'][OPERAND][RESTOFEXPR][RESTOFFPP-LIST]")"[RESTOFARRAYLIST][S], "*""*""*""A"[S], "%BEGIN"[S], "%END""%OF""%PROGRAM", "%UPPER""%CASE""%DELIMITERS"[S], [NAME]"("[+'][CONST]")"":", "%SWITCH"[NAME][RESTOFNAMELIST]"("[+'][CONST]":"[CONST]")"[RESTOFSWITCHLIST][S], "%COMPILE""%QUERIES"[S], "%IGNORE""%QUERIES"[S], "%MCODE"[S], [N]"P"":", "*"[UCI][S], "%FAULT"[N][RESTOFN-LIST]"->"[N][RESTOFFAULTLIST][S], "%NORMAL""%DELIMITERS"[S], "%STRINGS"[S], "%END""%OF""%PERM"[S], "%END""%OF""%MCODE"[S], "%DEFINE""%COMPILE""%R"[S], [S]; ELater versions of the grammar, presumably for Version 6 and Version 7 of this compiler, can be seen in 'IMP PS structures 6.txt' and 'IMP PS structures 7.txt'. The differences between V6 and V7 are only:
45c45 < C"%RESULT=" --- > C"%RESULT" 316c316 < --- > 355c355 < P[CMARK]="!","%COMMENT"; --- > P[CMARK]="!","%COMMENT","%SHORT""%ROUTINE"; 361c361 < --- > 420,421c420,421 < "%RESULT=""ADDR("[NAME][APP][ENAME']")", < "%RESULT="[+'][OPERAND][RESTOFEXPR], --- > "%RESULT""=""ADDR("[NAME][APP][ENAME']")", > "%RESULT"[ASSOP][+'][OPERAND][RESTOFEXPR],
***A JOB MAC022 PS PREPARATION MK3 CC->650, SYMBOL ->2400 OUTPUT 0 LINE PRINTER 5000 LINES COMPILER IMP %BEGIN %INTEGER I,J,K,SS,NIDFLAG %INTEGERARRAY CLETT(1:650),SYMBOL(1300:3000),CC(0:300) %SHORTINTEGERARRAY DUMMY(0:64),CL(0:650),SY(1300:2400),DUM(0:64) %INTEGER CNEXT,DNEXT,CNUM,DNUM,ALT,DEF,ASL,PFLAG %INTEGERARRAY KK,DWORD(1001:1100),DLETT(1:750),CWORD(1:200) %ROUTINESPEC READ STRING %ROUTINE %SPEC RECORD(%INTEGERARRAYNAME WORD,LETT, %INTEGER %C %NAME NUM,NEXT) %ROUTINESPEC LOOK UP(%INTEGERARRAYNAME WORD,LETT, %INTEGER FI%C RST,LAST) ASL=1300 CNEXT=1 DNEXT=1 CNUM=0 DNUM=1000 PFLAG=0 NIDFLAG=0 1:READ SYMBOL(I) %IF I=67 %THEN ->2 ; ! 'C' %IF I=68 %THEN ->3 ; ! 'D' %IF I=80 %THEN ->4 ; ! 'P' %IF I=69 %THEN ->5 ; ! 'D' ->1 2:READ SYMBOL(I) READ STRING RECORD(CWORD,CLETT,CNUM,CNEXT) ->1 3:->33 %IF PFLAG=1 PFLAG=1 %CYCLE I=1,1,CNEXT-1 CL(I)=CLETT(I) %REPEAT %MCODE **@CL(0); *SHL-1 **@CL(650); *NOT; *NEG; *SHL-1 *=M15; *=I15; *E338; *=C15 *C15; *J34>Z; *SET1; *SET5; *OUT *DUP; *=C15; *=E338 34:*POAQ15 %ENDOFMCODE 33:READ SYMBOL(I) READ STRING RECORD(DWORD,DLETT,DNUM,DNEXT) ->1 4:READ SYMBOL(I) READ STRING LOOK UP(DWORD,DLETT,1012,DNUM) KK(I)=ASL DEF=ASL ALT=ASL+1 ASL=ASL+2 6:READ SYMBOL(I) %IF I=91 %THEN ->7 ; ! '[' %IF I=34 %THEN ->8 ; !'"' OR EQUIVALENT %IF I=44 %THEN ->9 ; ! ',' %IF I=59 %THEN ->10 ; ! ; %IF I=48 %THEN ->11 ; ! '0' ->6 7:READ STRING LOOK UP(DWORD,DLETT,1001,DNUM) 12:SYMBOL(ASL)=I ASL=ASL+1 ->6 8:READ STRING LOOK UP(CWORD,CLETT,1,CNUM) ->12 9:SYMBOL(ALT)=ASL ALT=ASL ASL=ASL+1 ->6 10:SYMBOL(ALT)=ASL SYMBOL(DEF)=ASL ->1 11:I=1000 ->12 5:%CYCLE I=1300,1,ASL-1 %IF 1<=SYMBOL(I)<=CNUM %THEN SYMBOL(I) =CWORD(SYMBOL(I)) %IF 1012<=SYMBOL(I)<=DNUM %THEN SYMBOL(I)=KK(SYMBOL(I)) %REPEAT SS=KK(DNUM) ->FLOP %UNLESS NIDFLAG=0 %MCODE *E338; *=RC15 *SET25; *=M15 *ZERO; *=TR *BUSYQ15; *J55NTR %PRINTTEXT' PUNCH BUSY ' 55:*POEQ15 %ENDOFMCODE %CYCLE I=1300,1,ASL-1 SY(I)=SYMBOL(I) %REPEAT SY(2400)=SS %MCODE **@SY(1300) *SHL-1 **@SY(2400) *NOT *NEG *SHL-1 *E338; *=RC15; *=M15; *=I15 *POAQ15 %ENDOFMCODE NEWLINES(2) WRITE(CNEXT-1,1) NEWLINE %CYCLE I=1,1,CNEXT-1 WRITE(CLETT(I),5) %REPEAT NEWLINES(2) WRITE(ASL-1,1) NEWLINE %CYCLE I=1300,1,ASL-1 WRITE(SYMBOL(I),5) %REPEAT NEWLINES(2) WRITE(SS,1) SELECT PUNCH;RUNOUT(50);NEWLINE %PRINTTEXT'***A MAG ' RUNOUT(50);NEWLINE; %PRINTTEXT'***A CARDS ' RUNOUT(200); SELECTPRINTER NEWLINES(2) %STOP FLOP: NEWLINE WRITE (NIDFLAG, 4) %PRINTTEXT' WRONG PHRASES' %MONITORSTOP %ROUTINE READ STRING %INTEGER UNDER ; UNDER = 0 J=0 1:READ SYMBOL(I) -> 12 %UNLESS I=37 ; !PERCENT UNDER =128 -> 1 12: -> 13 %UNLESS 65<= I <= 90 I=I+UNDER -> 14 13: UNDER =0 14:%IF I=32 %THEN ->1 ; ! '_' %IF ( I=34 %OR I=93) %AND J#0 %THEN ->2; ! '"' OR EQUIVALENT AND ']' J=J+1 CC(J)=I ->1 2:CC(0)=J %END %ROUTINE RECORD(%INTEGER %ARRAY %NAME WORD,LETT, %INTEGER %NAME NUM%C ,NEXT) NUM=NUM+1 WORD(NUM)=NEXT %MCODE **@LETT(NEXT) *=RM9 **@CC(0) *=RM8 *M0M8;*SHL-16; *NOT;*NEG *=C9;* 1: *M0M8Q;*=M0M9Q;*;*J1C9NZS NEXT=NEXT+CC(0)+1 %END %ROUTINE LOOK UP(%INTEGERARRAYNAME WORD,LETT,%INTEGER FIRST,LAST) %MCODE %INTEGER K **@ CC(0); *=RM7 **@LETT(1); *=RM9; *M-I9 **@WORD(FIRST);*=RM8 K=LAST-FIRST+1 **K;*SHL-16; *=C8 10:*M0M8Q; *DUP; **=J *SHL-16; *=RM15 *Q7TOQ14 *M15M9; !**LETT(J) *SHL-16; *NOT; *NEG; *=C15 * 5: *M9M15Q; *M0M14Q *-; *J1#Z *J5C15NZS *C8; *SHL16; **=K I=LAST-K %RETURN 1: *J10C8NZ %ENDOFMCODE %PRINTTEXT' PHRASE NOT IN DICTIONARY ' %CYCLE K=1,1,CC(0) PRINT SYMBOL(CC(K)) %REPEAT NIDFLAG=NIDFLAG+1 %END %ENDOFPROGRAM