!!CS,N/CS,==1;%BEGIN; !EDIT15: COMPATIBLE CONTEXT EDITOR FOR PDP9/15 %OWNINTEGER IN=1; !CURRENT INPUT STREAM %OWNINTEGER MIN = 1; !MAIN FILE INPUT STREAM %OWNINTEGER MOUT = 1; !MAIN FILE OUTPUT STREAM %OWNINTEGER SIN = 2; !SECONDARY INPUT STREAM %OWNINTEGER ECHO=3; !CONTROL STREAM ECHO %OWNINTEGER MON; !MONITOR SWITCH %OWNINTEGER UPPER = 1; !UPPER/LOWER CASE INDIC %OWNINTEGER PRINTED; !PRINT INDICATOR %OWNINTEGER STOP = -5000; !LOOP STOP %OWNINTEGER INV = -5001; !INVERSION INDICATOR %INTEGER I,J,K,PP1,SYM,TERM %INTEGER CI; !COMMAND INDEX (AD) %INTEGER TI; !TEXT INDEX (AD) %INTEGER CODELIM; !LIM/CODE %INTEGER CODE; !COMMAND CODE LETTER %INTEGER TEXT; !TEXT POINTER (AD) %INTEGER NUM; !REPETITION NUMBER %INTEGER LAST; !LAST COMMAND CODE %INTEGER TOP; !TOP OF BUFF %INTEGER PE; !PREVIOUS LINE END %INTEGER PP; !PREVIOUS POINTER %OWNINTEGER FP; !FILE POINTER %OWNINTEGER END; !END OF BUFF INF %INTEGER LIM; !BUFF LIMIT ! SIGNIFICANCE OF FILE POINTERS: ! [NL] O N E NL T W . . . O NL L A S T NL . . ! ! ! ! ! ! ! T P P F E ! O E P P N ! P D ! %OWNINTEGER SEXTRA; !EXTRA BUFF FOR SIN %OWNINTEGERNAME CFP; ! == FP OR MFP %OWNINTEGER MS; !MATCH START AD %OWNINTEGER ML; !MATCH LIMIT AD %INTEGER TBASE; !TEXT STRING BASE AD %INTEGER CMAX; !COMMAND MAX AD %SWITCH S('A':'Z') %INTEGERARRAY C(1:120); !TEXT -> <- C0MMAND ! EACH COMMAND UNIT -- LETTER, PARENTHESIS OR COMMA -- IS ! REPRESENTED BY THREE ELEMENTS: ! CODE(+LIM) TEXT NUM ! IN THE CASE OF PARENTHESES AND COMMAS 'TEXT' IS A POINTER ! TO ANOTHER COMMAND UNIT (NOT A TEXT STRING) %INTEGER AMAX !WORK OUT AVAILABLE SPACE AMAX = FREESTORE-10 %CYCLE I = 3,-1,0 SELECT INPUT(I); SELECT OUTPUT(I) SEXTRA = 122 %IF I = SIN %AND INDEV # 0 AMAX = AMAX-256 %IF INDEV&(\1) # 0 AMAX = AMAX-256 %IF OUTDEV&(\1) # 0 %REPEAT %INTEGERARRAY A(0:AMAX) %ROUTINE LOAD PP(%INTEGER K); !!!ALSO INCREMENTS PP %INTEGER P %LAC PP; %OPR 2064;!RCR; %DAC P %OPR 768;!SZL; %JMP L1 %LAC K; %OPR 1032;!RTL; %OPR 1032 %OPR 1032; %OPR 1032; %DAC K %LAC #-256; %OPR 513;!SKP!CMA L1: %LAC #-256; %AND* P; %XOR K; %DAC* P %ISZ PP %END %ROUTINE LOAD FP(%INTEGER K) %INTEGER P %LAC FP; %OPR 2064;!RCR; %DAC P %OPR 768;!SZL; %JMP L1 %LAC K; %OPR 1032;!RTL; %OPR 1032 %OPR 1032; %OPR 1032; %DAC K %LAC #-256; %OPR 513;!SKP!CMA L1: %LAC #-256; %AND* P; %XOR K; %DAC* P %END %INTEGERFN BYTE(%INTEGER P) %OPR 2064;!RCR; %DAC P %LAC* P; %OPR 768;!SZL; %JMP L1 %OPR 1040;!RTR; %OPR 1040 %OPR 1040; %OPR 1040 L1: %AND #255; %JMP* BYTE %STOP %END %ROUTINE MAKE SPACE %INTEGER K,P1,P2 %RETURN %IF CFP-PP-240 > 0 SELECT OUTPUT(MOUT) P1 = TOP; P2 = (P1+PE)>>1; !OUTPUT ABOUT HALF P2 = PE %IF CODE = 'C'; !BUT ALL IF CLOSING %MONITOR 20 %IF P2 = TOP; !!!LOGICAL ERROR 1: K = BYTE(P1); PRINT SYMBOL(K); %ISZ P1 ->1 %UNLESS K = NL %AND P1-P2 >= 0 SELECT OUTPUT(0) PE = TOP+PE-P1; P2 = PP; PP = TOP 2: %RETURN %IF P1 = P2 LOAD PP(BYTE(P1)); %ISZ P1 ->2 %END %ROUTINE READ SYM READ SYMBOL(SYM) SELECT OUTPUT(3) PRINT SYMBOL(SYM) SELECT OUTPUT(0) SYM = SYM-32 %IF SYM >= 96 %AND UPPER # 0; !LOWER TO UPPER %END %ROUTINE READ COMMAND %OWNINTEGER CLIM %INTEGER I,J,TYPE,QUOTE,CHAIN %SWITCH T(2:10) %INTEGERFN NEXT ITEM TYPE %SWITCH S(32:95) S(' '): READ SYM; SYM = SYM-32 %IF SYM >= 96 ->S(SYM) %IF SYM >= 32 S(';'): %RESULT = 1 S('('): %RESULT = 2 S(','): SKIP SYMBOL %IF NEXT SYMBOL = NL %RESULT = 3 S(')'): %RESULT = 4 S('I'):S('S'): %RESULT = 5 S('D'): %RESULT = 6 S('F'):S('T'):S('U'): %RESULT = 7 S('V'): %RESULT = 8 S('E'):S('M'): %IF NEXT SYMBOL = '-' %THEN %START J = SYM; READ SYM; SYM = J+10; !E-:O, M-:Y %FINISH S('B'):S('G'):S('J'):S('K'):S('L'):S('P'):S('R'): %RESULT = 9 S('A'):S('C'):S('H'):S('O'):S('Q'):S('-'): S('W'):S('X'):S('Y'):S('Z'): %RESULT = 10 S('0'):S('1'):S('2'):S('3'):S('4'):S('5'):S('6'):S('7'):S('8'):S('9'): J = SYM; NUM = J-'0' 1: SYM = NEXT SYMBOL-'0' ->2 %UNLESS SYM-9 <= 0 %AND SYM >=0 NUM = (NUM<<2+NUM)<<1+SYM; !(MULT AVOIDED TO SAVE SPACE) READ SYM ->1 2: SYM = J %RESULT = 0 S('*'): NUM = 0; %RESULT = 0 S('?'): NUM = STOP+1; %RESULT = 0 S(92): NUM = INV+1; %RESULT = 0 S('N'): TEXT = -1; !FOR OLD FORMS OF B,J S('!'):S(34):S('#'):S('$'):S('%'):S('&'):S(''''): S('+'):S('.'):S('/'):S(':'):S('<'): S('='):S('>'):S('@'):S(91):S(93):S(94):S('_'): %RESULT = -1 %END %ROUTINE UNCHAIN 1: TEXT = CHAIN; %RETURN %IF TEXT = 0 CHAIN = INTEGER(TEXT); INTEGER(TEXT) = CI ->1 %IF INTEGER(TEXT+1) # 'Y' %END %ROUTINE STACK(%INTEGER V) CI = CI-1; INTEGER(CI) = V %END %OWNINTEGER PR 1: %IF PR # 0 %THEN %START PROMPT(PR); PROMPT(0) %FINISH PR = '>' TYPE = NEXT ITEM TYPE ->1 %IF TYPE = 1 CI = CMAX; TI = TBASE; CHAIN = 0 %IF TYPE = 0 %AND CLIM # 0 %THEN %START INTEGER(CLIM) = NUM; !REPETITION NUMBER ->ER1 %UNLESS NEXT ITEM TYPE = 1 %RETURN %FINISH %IF SYM = '%' %THEN %START READ SYM; CODE = SYM&95; CODE = 'X' %IF CODE = 'S' TYPE = NEXT ITEM TYPE; ->ER1 %UNLESS TYPE = 1 ->6 %IF CODE='C' %OR CODE='X' UPPER = CODE-'L' %AND ->1 %IF CODE='U' %OR CODE='L' ->ER1 %UNLESS CODE='Q' %OR CODE='M' %OR CODE='F' MON = 'M'-CODE ->1 %FINISH 2: ->ER1 %UNLESS TYPE > 0; ->ER6 %IF CI-4 <= TI CODE = SYM; TEXT = 0 NUM = 1; NUM = 0 %IF CODE = 'F' I = TYPE; TYPE = NEXT ITEM TYPE ->T(I) T(2): !LEFT BRACKET CODE = 'Y' ->20 T(3): !COMMA NUM = INV; CODE = 'Z' 20: TEXT = CHAIN; CHAIN = CI-2 ->6 T(4): !RIGHT BRACKET UNCHAIN; ->ER5 %IF TEXT = 0 INTEGER(TEXT) = CI-3 TEXT = TEXT-1; INTEGER(TEXT) = NUM CODE = 'Z' ->5 T(5): !INSERT,SUBSTITUTE ->4 %IF TEXT < 0 ->25 T(6): !DELETE ->4 %IF TEXT < 0 T(7): !+FIND,TRAVERSE,UNCOVER CODE = NUM<<7+CODE; NUM = 1 TYPE = NEXT ITEM TYPE %IF TYPE = 0 T(8): !+VERIFY 25: ->ER3 %UNLESS TYPE < 0 %AND TEXT = 0 QUOTE = SYM; TEXT = TI 3: %IF NEXT SYMBOL = NL %THEN %START ->ER3 %UNLESS CODE = 'I' %OR CODE = 'S' ->35 %FINISH READ SYM %IF SYM # QUOTE %THEN %START INTEGER(TI) = SYM; TI = TI+1 ->ER6 %IF TI = CI ->3 %FINISH 35: ->ER3 %IF TI = TEXT %AND CODE # 'S' INTEGER(TI) = 0; TI = TI+1 4: TYPE = NEXT ITEM TYPE ->5 T(9): ->ER0 %IF TYPE < 0 5: TYPE = NEXT ITEM TYPE %IF TYPE = 0 6: STACK(CODE); STACK(TEXT); STACK(NUM) ->2 %UNLESS TYPE = 1 UNCHAIN; ->ER2 %UNLESS TEXT = 0 STACK('Z'); STACK(CMAX); STACK(1) CLIM = CI; STACK(0) %RETURN ER0:SPACE; PRINT SYMBOL(CODE) ER1:CODE = SYM ->ER5 ER2:CODE = '(' ->ER5 ER3:%PRINTTEXT ' TEXT FOR' T(10): ER5:SPACE; PRINT SYMBOL(CODE&127) PRINT SYMBOL('?') ->9 ER6:%PRINTTEXT ' TOO LONG' 9: NEWLINE; CLIM = 0 %IF CI # CMAX 10: ->1 %IF SYM = NL %AND INPUT = 0; READ SYM ->10 %END %ROUTINE PRINT LINE %INTEGER P PRINTED = 1 ->3 %IF FP = END P = PE ->2 %IF P # PP 1: P = FP 2: PRINT SYMBOL(BYTE(P)); %RETURN %IF BYTE(P) = NL P = P+1 ->2 %UNLESS P = PP PRINT SYMBOL(94) %IF NUM = 0 ->1 3: %PRINTTEXT '**END**'; NEWLINE %END %ROUTINE READ LINE %INTEGER K PRINTED = 0 %RETURN %UNLESS FP = END SELECT INPUT(IN) FP = LIM-121; MS = 0 1: %UNLESS FP = LIM %AND NEXT SYMBOL # NL %THEN %START READ SYMBOL(K) LOAD FP(K); %ISZ FP ->1 %UNLESS K = NL %FINISH %ELSE %START LOAD FP(NL); %ISZ FP %FINISH END = FP; FP = LIM-121 SELECT INPUT(0) %END %ROUTINE LEFT TAB 1: %RETURN %IF PP = PE FP = FP-1; PP = PP-1; LOAD FP(BYTE(PP)) ->1 %END %ROUTINE SWITCH INPUTS %OWNINTEGER MFP,MEND,SEND %IF IN = MIN %THEN %START LEFT TAB IN = SIN MFP = FP; MEND = END; CFP == MFP LIM = LIM+SEXTRA; END = SEND %IF END = 0 %THEN %START FP = 0; READ LINE %FINISH %ELSE FP = LIM-121 %FINISH %ELSE %START PP = PE IN = MIN LIM = LIM-SEXTRA; SEND = END FP = MFP; END = MEND; CFP == FP %FINISH %END %ROUTINE MOVE BACK %INTEGER K 1: K = BYTE(PP-1) ->2 %IF K = NL %AND PP # PE FP = FP-1; PP = PP-1; LOAD FP(K) ->1 2: PE = PP; MS = 0; PRINTED = 0 %END %ROUTINE MOVE %INTEGER K MAKE SPACE 1: K = BYTE(FP); LOAD PP(K); %ISZ FP ->1 %UNLESS K = NL PE = PP READ LINE %END %INTEGERFN MATCHED %INTEGER I,K,L,T1,FP1,IND PP1 = PP; FP1 = FP; IND = CODELIM&(\127) T1 = INTEGER(TEXT) ->2 %UNLESS FP = MS %AND (CODE='F' %OR CODE='U') K = BYTE(FP) 1: LOAD PP(K); %ISZ FP 2: K = BYTE(FP) ->5 %IF K = T1 ->1 %UNLESS K = NL ->10 5: L = 1 6: I = INTEGER(TEXT+L); ->7 %IF I = 0 ->1 %IF BYTE(FP+L) # I L = L+1 ->6 7: MS = FP; ML = FP+L %RESULT = 1 10: IND = IND-128 ->15 %IF IND = 0; ->16 %IF FP = END %IF CODE # 'U' %THEN %START LOAD PP(K); PE = PP %FINISH %ELSE PP = PP1 FP = FP+1 MAKE SPACE; READ LINE PP1 = PP; FP1 = FP ->2 15: PP = PP1; FP = FP1 16: %RESULT = 0 %END !INITIALISE %FAULT 9 ->EOF TBASE = ADDR(C(1)); CMAX = TBASE+120 TOP = ADDR(A(0))<<1+1; LIM = TOP+AMAX+AMAX-SEXTRA PP = TOP-1; LOAD PP(NL); !FOR BOUNCING OFF PE = PP; CFP == FP PROMPT('E'); PROMPT('D'); PROMPT('I'); PROMPT('T') PROMPT(NL); PROMPT('>'); PROMPT(0) READ LINE 2: READ COMMAND; TERM = SYM CI = CMAX; LAST = 0 3: CODELIM = INTEGER(CI-1); ->9 %IF CODELIM = 0 CODE = CODELIM&127 TEXT = INTEGER(CI-2) NUM = INTEGER(CI-3) CI = CI-3 4: NUM = NUM-1 ->S(CODE) OK: LAST = CODE ->5 %IF NUM = INV ->4 %UNLESS NUM = 0 %OR NUM = STOP ->3 NO: ->3 %IF NUM < 0 5: I = INTEGER(CI-1); CI = CI-3; CI = INTEGER(CI+1) %IF I = 'Y' ->5 %UNLESS I = 0 %OR (I='Z' %AND INTEGER(CI)<=0) ->3 %IF I # 0 %PRINTTEXT 'FAILURE: ' %IF CODE='O' %OR CODE='W' %THEN %START PRINT SYMBOL(CODE-10); CODE = '-' %FINISH %IF CODE # 'Z' %THEN %START PRINT SYMBOL(CODE) %IF TEXT > 0 %THEN %START PRINT SYMBOL('''') 6: ->7 %IF INTEGER(TEXT) = 0 PRINT SYMBOL(INTEGER(TEXT)); TEXT = TEXT+1 ->6 7: PRINT SYMBOL('''') %FINISH %FINISH PRINT SYMBOL('\') %IF NUM = INV; NEWLINE 8: ->9 %IF INPUT = 0; READ SYM; ->8 9: ->2 %IF TERM # NL %OR INPUT # 0 NUM = 0 PRINT LINE %IF (MON=0 %AND PRINTED=0) %OR (MON>0 %AND LAST#'P') ->2 EOF:I = INSTREAM; SELECT INPUT(0) %IF I # 0 %THEN %START FP = LIM; END = FP; LOAD FP(NL) %JMP* READ LINE; !!!EXIT FROM READ LINE %FINISH CLOSE INPUT ->2 %IF INDEV = 1 CODE = 'C' ->FIN !EXECUTE COMMANDS S('Y'): !OPEN BRACKET INTEGER(TEXT) = NUM+1 ->3 S('Z'): !CLOSE BRACKET ->5 %IF NUM = INV %IF NUM # 0 %AND NUM # STOP %THEN %START INTEGER(CI) = NUM; CI = TEXT %FINISH ->3 S('R'): !RIGHT SHIFT K = BYTE(FP) ->NO %IF K = NL LOAD PP(K); FP = FP+1 ->OK S('L'): !LEFT SHIFT ->NO %IF IN = SIN %OR PP = PE FP = FP-1; PP = PP-1; LOAD FP(BYTE(PP)) MS = 0 ->OK S('E'): !ERASE ->NO %IF BYTE(FP) = NL FP = FP+1 ->OK S('O'): !ERASE BACK ->NO %IF PP = PE PP = PP-1 ->OK S('V'): !VERIFY I = FP; J = TEXT V1: K = INTEGER(J) ->V2 %IF K = 0 ->NO %IF BYTE(I) # K I = I+1; J = J+1 ->V1 V2: MS = FP; ML = I ->OK S('F'): !FIND ->NO %IF MATCHED = 0 ->OK S('U'): !UNCOVER ->NO %IF MATCHED = 0; PP = PP1 ->OK S('T'): !TRAVERSE ->NO %IF MATCHED = 0 ->S1 S('D'): !DELETE ->D5 %IF TEXT < 0; !OLD FORM OF J (DN) ->NO %IF MATCHED = 0; FP = ML ->OK S('J'): !JOIN (DELETE NEWLINE) D5: ->NO %IF FP = END D6: K = BYTE(FP) LOAD PP(K); FP = FP+1 ->D6 %UNLESS K = NL READ LINE; PP = PP-1 ->OK %UNLESS PP-PE > 80 %OR (FP=END %AND PP#PE) PP = PP+1; PE = PP ->NO S('S'): !SUBSTITUTE ->NO %IF FP # MS S1: FP = ML S('I'): !INSERT MAKE SPACE ->I5 %IF TEXT < 0; !OLD FORM OF B (IN) ->NO %IF PP-PE > 80 %OR FP = END I1: I = TEXT; !INSERT TEXT I2: ->OK %IF INTEGER(I) = 0 LOAD PP(INTEGER(I)); I = I+1 ->I2 S('B'): !BREAK (INSERT NEWLINE) I5: LOAD PP(NL); PE = PP ->OK S('K'): !KILL (LINE) ->NO %IF FP = END PP = PE K1: FP = FP+1; ->K1 %UNLESS BYTE(FP-1) = NL READ LINE ->OK S('G'): !GET (LINE FROM TT) PROMPT(':'); PROMPT(0) MAKE SPACE READ SYM ->NO %IF SYM = ':' LEFT TAB G1: LOAD PP(SYM); PE = PP ->OK %IF SYM = NL READ SYM ->G1 S('M'): !MOVE ->NO %IF FP = END MOVE ->OK S('W'): !MOVE BACK ->NO %IF IN = SIN MAKE SPACE ->NO %IF PE = TOP MOVE BACK ->OK S('P'): !PRINT %IF LAST = 'P' %THEN %START ->NO %IF FP = END; MOVE %FINISH PRINT LINE ->OK S('X'): !SWITCH INPUTS SWITCH INPUTS PRINTED = 0 ->9 S('C'): !CLOSE FIN:SWITCH INPUTS %IF IN = SIN 90: ->91 %IF FP = END; MOVE; ->90 91: SELECT OUTPUT(MOUT) 92: %IF TOP # PP %THEN %START PRINT SYMBOL(BYTE(TOP)); TOP = TOP+1 ->92 %FINISH %ENDOFPROGRAM