diff --git a/README.md b/README.md index 93722893..264cbd3a 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,7 @@ There's a [DDT cheat sheet](doc/DDT.md) for Unix users. - STY, pseudo-terminal for multiple sessions. - SUPDUP, Supdup client. - SYSMSG, displays system messages. + - TAGS, generate tags table for sources. - TALK/WHO/WHOJ/WHOM/USERS, list users. - TCTYP and CRTSTY, terminal handling. - TECO, editor. diff --git a/build/build.tcl b/build/build.tcl index 0a40babc..5270186a 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -855,6 +855,10 @@ expect ":KILL" respond "*" ":midas sys2;ts msplit_sysen2;msplit\r" expect ":KILL" +# TAGS +respond "*" ":midas sys2;ts tags_sysen2;tags\r" +expect ":KILL" + # ndskdmp tape respond "*" ":link kshack;good ram,.;ram ram\r" respond "*" ":link kshack;ddt bin,.;@ ddt\r" diff --git a/src/sysen2/tags.79 b/src/sysen2/tags.79 new file mode 100644 index 00000000..e7171fb4 --- /dev/null +++ b/src/sysen2/tags.79 @@ -0,0 +1,1339 @@ +; -*-MIDAS-*- + +TITLE TAGS + +.INSRT RMS;MACROS + +CH==,-1 +CHIN==1 ;INPUT CHANNEL +CHOUT==2 ;OUTPUT CHANNEL +CHSRC==3 ;SOURCE FILE INPUT CHANNEL + +TFDEV: 0 ;TAG FILE DEV, ETC. +TFFN1: 0 +TFFN2: 0 +TFSNM: 0 + +SFDEV: 0 ;SOURCE FILE DEV, ETC. +SFFN1: 0 +SFFN2: 0 +SFSNM: 0 +SFLANG: 0 ;SOURCE FILE LANGUAGE IN SIXBIT. + +MSNAME: 0 ;DEFAULT SNAME. + +SWDEF LPDL==40 +PDL: BLOCK LPDL+20 + +FORMF: 0 ;-1 IF REMEMBERING A ^L WHICH WAS AT FRONT OF THIS SOURCE LINE. +FAILP: 0 ;-1 => FAIL CODE, AS OPPOSED TO MIDAS CODE. +PALXP: 0 ;-1 => PALX CODE, AS OPPOSED TO MIDAS CODE. +INFOP: 0 ;-1 => THIS IS A INFO; FILE WHICH CONTAINS TEXT AND ITS OWN TAG TABLE. + +RFNSWP: 0 ;-1 => RFN SHOULD RECOGNIZE SWITCHES. +DEBUG: 0 ;-1 => DON'T COMMIT SUICIDE. + +SRCCPY: 0 ;-1 => COPY OLD BUFFERS OF SOURCE FILE INTO THE OUTPUT FILE +EOFP: 0 ;AT EOF IN SOURCE FILE, RESTORE P FROM HERE +EOFJ: 0 ;AND JUMP INDIRECT THROUGH HERE. + +FILMSG: ASCII / +:/ + ASCII / Processing source file / +PFNBUF: BLOCK 8 + +BEG: MOVE P,[-LPDL,,PDL] + SETZM LINBUF + MOVE A,[LINBUF,,LINBUF+1] + BLT A,LINBFE ;PREPARE TO READ THE COMMAND STRING. + MOVE A,[.BYTE 7 ? ^M] + MOVEM A,LINBFE + .SUSET [.ROPTIO,,A] + TLNN A,OPTCMD + .VALUE [ASCIZ / +:You must give a JCL command string. + + +:kill ¯] + .BREAK 12,[..RJCL,,LINBUF] + SETZM SFTOTC + .SUSET [.RSNAM,,MSNAME] + MOVE A,MSNAME + MOVEM A,TFSNM ;SET UP DEFAULTS FOR TAG TABLE FILE NAME + MOVSI A,'DSK + MOVEM A,TFDEV + MOVE D,[440700,,LINBUF] + MOVEI B,TFDEV + SETOM RFNSWP ;ALLOW SWITCHES. + CALL RFN"RFN ;PARSE JCL FILENAME. + MOVE A,[SIXBIT/TAGS/] + SKIPE INFOP + MOVSI A,(SIXBIT/>/) + SKIPN TFFN2 + MOVEM A,TFFN2 + MOVE A,TFSNM ;ALLOW :TAGS FOO; + SKIPN TFFN1 + MOVEM A,TFFN1 +;OPEN INPUT AND OUTPUT TAG TABLE FILES. + SYSCAL OPEN,[[.UAI,,CHIN] ? TFDEV ? TFFN1 ? TFFN2 ? TFSNM] + .LOSE %LSFIL + SYSCAL OPEN,[[.UAO,,CHOUT] ? TFDEV ? [SIXBIT /_TAGS_/] ? ['OUTPUT] ? TFSNM] + .LOSE %LSFIL + SETZM TFCNT ;INIT BUFFERING OF INPUT TAG TABLE. + MOVE A,[440700,,OUTBUF] + MOVEM A,OUTPNT + SETZM OUTTOT ;AND OUTPUT FILE. + SKIPE INFOP + JRST MINFO ;A /I INFO; FILE IS BOTH SOURCE AND TAG TABLE. +SLOOP: MOVEI N,TFREDC + CALL RLIN ;READ A LINE OFF THE INPUT TAG FILE. + SKIPN LINCNT + JRST DONE + MOVE A,TFSNM ;DEFAULT SOURCE FILE DEV AND SNAME TO TAG FILE'S. + MOVEM A,SFSNM + MOVE A,TFDEV + MOVEM A,SFDEV + MOVE A,[SIXBIT/>/] + MOVEM A,SFFN2 + MOVE D,LINPNT + MOVEI B,SFDEV ;PARSE IT INTO SOURCE FILE NAME. + SETZM RFNSWP ;NO SWITCHES ALLOWED IN FILENAMES IN THE TAG FILE. + CALL RFN"RFN +SLOOP1: CALL TFREDC + CAIE I,^_ + CAIN I,^C + JRST SLOOPL + CAIN I,^M + JRST SLOOPL + CAIE I,", ;SKIP PAST THE SIZE AND COMMA. + JRST SLOOP1 + MOVEI N,TFREDC + CALL RSIX ;READ IN THE LANGUAGE. + JUMPE A,SLOOPL + MOVEM A,SFLANG + CAIA ;RSIX'S TERMINATOR CAN BE THE CR OF THE CRLF BEFORE THE ^_. +SLOOP2: CALL TFREDC ;SKIP THE REST OF THE ENTRY. + CAILE I,^_ + JRST SLOOP2 +SLOOP4: CAIN I,^C ;EOF IS OK - USER PROBABLY LEFT OUT THE ^_ CRLF + JRST SLOOP3 ;WHEN CREATING THE INITIAL LIST OF FILES. + CAIE I,^M ;ASIDE FROM EOF, LOOK FOR A CR LF ^_. + JRST SLOOP2 + CALL TFREDC + CAIE I,^J + JRST SLOOP4 + CALL TFREDC + CAIE I,^_ + JRST SLOOP4 + CALL TFREDC ;SKIP THE CRLF AFTER THE ^_. + CAIE I,^M + JRST BADFRM + CALL TFREDC + CAIE I,^J + JRST BADFRM +SLOOP3: CALL MAKNEW ;NOW WRITE THE NEW ENTRY. + JRST SLOOP ;HACK THE NEXT SOURCE FILE. + +SLOOPL: CALL DELEWO + .VALUE [ASCIZ / +:Language name not found when expected. + + +:kill ¯] + +BADFRM: CALL DELEWO + .VALUE [ASCIZ / +:Bad format input tag table. A ^_ is not followed by a CRLF. + + +:kill ¯] + +;COMMON ROUTINE FOR ERROR MESSAGES. +;SAY WHICH SOURCE FILE WE ARE PROCESSING, AND FLUSH THE OUTPUT FILE. +DELEWO: SKIPN SFDEV + JRST DELEW1 + MOVE D,[440700,,PFNBUF] + MOVEI B,SFDEV + CALL RFN"PFN + IRPC X,,[: + +P] + MOVEI A,"X + IDPB A,D + TERMIN + .VALUE FILMSG +DELEW1: SKIPE DEBUG + .VALUE + SYSCAL DELEWO,[%CLIMM,,CHOUT] + JFCL + RET + +;HERE AFTER READING WHOLE INPUT TAG TABLE AND WRITING ENTRIES FOR ALL SOURCE FILES. +DONE: MOVE A,[440700,,OUTBUF] ;NOW WRITE THE STUFF OUT. + SYSCAL SIOT,[%CLIMM,,CHOUT ? A ? OUTTOT] + .LOSE %LSFIL + SYSCAL RENMWO,[%CLIMM,,CHOUT ? TFFN1 ? TFFN2] + .LOSE %LSFIL + .CLOSE CHOUT, + SKIPE DEBUG + .VALUE + .BREAK 16,140000 + +;READ A LINE FROM THE INPUT PATH IN N, INTO LINBUF. +;CLOBBERS H,I. THE TERMINATION OF THE LINE IS NOT INCLUDED. +;A ^C MARKS THE END, IN LINBUF. +RLIN: MOVE H,[440700,,LINBUF] ;BP -> START OF BUFFER. + MOVEM H,LINPNT + SETZM LINCNT ;0 CHARS READ SO FAR. +RLIN1: CALL (N) ;READ NEXT CHAR. + CAIG I,^M + JRST RLIN2 +RLIN4: CAMN H,[010700,,LINBUF+LINBSZ-1] + JRST RLIN1 ;DON'T STORE IF BUFFER FULL. + IDPB I,H ;ORDINARY CHAR, JUST PUT IN BUFFER. + AOS LINCNT + JRST RLIN1 + +RLIN2: CAIN I,^M ;IGNORE CR. + JRST RLIN1 + CAIE I,^J ;LF ENDS LINE. + CAIN I,^C ;^C ENDS LINE. + JRST RLIN3 + JUMPN I,RLIN4 ;SAME FOR ^@. +RLIN3: MOVEI I,^C ;LINE WAS TERMINATED, PUT ^C AT END OF BUFFER. + IDPB I,H + RET + +SWDEF LINBSZ==100 + +LINPNT: 0 +LINCNT: 0 +LINBUF: BLOCK LINBSZ +LINBFE: -1 + +;; ASSEMBLE IN THE FILENAME READER AND PRINTER. + +RFN"$$RFN==1 +RFN"$$PFN==1 +RFN"$$PFND==1 + +;; ACTIVATE THE "/" CHARACTER FOR READING SWITCHES, DEPENDING ON RFNSWP. +RFN"RSIXTP: + CAIN A,"/ + SKIPN RFNSWP + RET + AOS (P) +RFN"PSIXTP: + RET + +;; WHEN "/" IS ACTIVATED, CALL HERE WITH THE CHAR AFTER THE "/" IN A. +RFN"$$SWITCH==1 +RFN"SWITCH: + CAIN A,"I + SETOM INFOP + CAIN A,"I + RET + SKIPE DEBUG + .VALUE + .VALUE [ASCIZ / +:Illegal switch + + +:kill ¯] + +.INSRT SYSENG;RFN + +;READ SIXBIT WORD INTO A FROM STREAM IN N. CLOBBERS H. +;TERMINATING CHARACTER LEFT IN I. +RSIX: MOVE H,[440600,,A] ;BP FOR STORING THE SIXBIT. + SETZ A, ;NO CHARS SO . +RSIX0: CALL (N) ;GET NEX CHAR, LOWER CASE TO UPPER. + CAIL I,140 + SUBI I,40 + CAIG I,40 ;SPACE OR CTL CHAR => STOP. + RET + SUBI I,40 ;INSERT NORMAL CHAR IN THE 6BIT. + TLNE H,77^4 ;IGNORE CHARS AFTER THE FIRST 6. + IDPB I,H + JRST RSIX0 + +;READ A CHAR INTO I OFF OF CHANNEL CHIN, BUFFERED. +TFREDC: SOSG TFCNT + CALL TFRLD + ILDB I,TFPNT + RET + +TFRLD: SAVE A + SAVE B + MOVE A,[440700,,TFBFR] + MOVEM A,TFPNT + MOVEI B,TFBFSZ*5 + SYSCAL SIOT,[%CLIMM,,CHIN ? A ? B] + .LOSE %LSFIL + MOVNS B + ADDI B,TFBFSZ*5 + MOVEM B,TFCNT + MOVEI B,^C + IDPB B,A +POPBAJ: REST B + REST A + RET + +TFBFSZ==100 + +TFCNT: 0 +TFPNT: 0 +TFBFR: BLOCK TFBFSZ + 0 + +;ROUTINES FOR READING THE SOURCE FILE, AND STORING INTO THE ENTRY (ACCUMULATED IN CORE). + +DEFINE WRITEI CHAR + MOVEI I,CHAR + IDPB I,OUTPNT + AOS OUTCNT +TERMIN + +;SUBROUTINE TO OUTPUT CHAR IN I TO ENTRY. +OUTCHR: IDPB I,OUTPNT + AOS OUTCNT + RET + + +;READ A CHAR INTO I OFF OF CHANNEL CHSRC, BUFFERED. +SFREDC: ILDB I,SFPNT + CAIN I,^C + CALL SFRLD + AOS SFCHRS + RET + +;AFTER READING A ^C FROM SFBFR YOU MUST CALL SFRLD. +;IF THE ^C MEANT EOF, WE GO TO SRCEOF. IF IT MEANT END OF BUFFER, +;WE REFILL THE BUFFER AND REPLACE THE ^C WITH THE REAL NEXT CHARACTER. +;IF SRCCPY IS SET, WHEN WE RELOAD THE BUFFER THE OLD STUFF IS WRITTEN TO CHOUT. +SFRLD: SAVE A + SAVE B + MOVE A,SFPNT + CAME A,SFEPT ;^C WASN'T AT END OF A SIOT => + JRST POPBAJ ;IT WAS REALLY IN THE FILE. + MOVE A,[440700,,SFBFR] ;ELSE BUFFER EMPTY, MUST READ MORE. + SKIPN SRCCPY + JRST SFRLD1 + MOVEI B,SFBFSZ*5 ;IF CALLER SPECIFIES, COPY THE DISCARDED BUFFER + SYSCAL SIOT,[%CLIMM,,CHOUT ? A ? B] ;TO THE OUTPUT FILE. + .LOSE %LSFIL +SFRLD1: MOVE A,[440700,,SFBFR] + MOVEM A,SFPNT + MOVEI B,SFBFSZ*5 + SYSCAL SIOT,[%CLIMM,,CHSRC ? A ? B] + .LOSE %LSFIL + MOVNS B + ADDI B,SFBFSZ*5 ;HOW MUCH DID WE GET? + JUMPE B,[ MOVE P,EOFP ;NOTHING => EOF, GO TO SRCEOF RESTORING P. + JRST @EOFJ] + MOVEI B,^C + IDPB B,A + MOVEM A,SFEPT ;ELSE PUT ^C AFTER AND MAKE SRCEPT -> IT. + ILDB I,SFPNT ;NOW GET THE FIRST CHAR JUST READ + JRST POPBAJ + +SFBFSZ==100 + +SFPNT: 0 +SFEPT: 0 ;-> THE ^C AFTER THE STUFF IN SFBFR. +SFBFR: BLOCK SFBFSZ + 0 +SFCHRS: 0 ;# CHARS READ SO FAR FROM THIS SOURCE FILE. +SFTOTC: 0 ;# CHARS IN ALL PREVIOUS SOURCE FILES. + +;WRITE OUT AN ENTRY FOR ONE SOURCE FILE (NAMES IN SFDEV, ETC.) +MAKNEW: SYSCAL OPEN,[[.UAI,,CHSRC] ? SFDEV ? SFFN1 ? SFFN2 ? SFSNM] + .LOSE %LSFIL + MOVE A,[440700,,SFBFR] + MOVEM A,SFPNT ;MARK BUFFER AS EMPTY (SFPNT ILDBS A ^C + MOVEI B,^C ;WHICH SFEPT POINTS AT). + IDPB B,A + MOVEM A,SFEPT + SETZM SFCHRS ;INIT CHAR POS IN SOURCE FILE TO 0. + SETZM OUTCNT ;INIT SIZE OF ENTRY WRITTEN TO 0. + MOVEI B,SFDEV + MOVE D,[440700,,PFNBUF] + CALL RFN"PFND ;PRINT FILENAMES INTO ENTRY. + MOVEI A,PFNBUF + CALL OUTASC + WRITEI ^M + WRITEI ^J + MOVE A,OUTPNT + MOVEM A,ONUMPT ;HERE IS WHERE SIZE WILL GO. FOR NOW, STORE ZEROS. +REPEAT 5,WRITEI "0 + WRITEI [",] + MOVEM P,EOFP ;SET UP PDL PTR TO RESTORE AT EOF. + MOVEI A,SRCEOF + MOVEM A,EOFJ + SETZM SRCCPY + + MOVE A,SFLANG ;NOW PARSE SOURCE FILE ACCORDING TO ITS LANGUAGE + CAMN A,[SIXBIT /MUDDLE/] + JRST MMUDDL + CAMN A,[SIXBIT /TECO/] + JRST MTECO + CAMN A,[SIXBIT /MIDAS/] ;NOTE: THE FIRST THING EACH LANGUAGE MUST DO IS + JRST MMIDAS ;OUTPUT ITS FULL NAME AND A CRLF. + CAMN A,[SIXBIT /XMIDAS/] + JRST XMIDAS + CAMN A,[SIXBIT /FAIL/] + JRST MFAIL + CAMN A,[SIXBIT /PALX/] + JRST MPALX + CAMN A,[SIXBIT /LISP/] + JRST MLISP + CAMN A,[SIXBIT /SCHEME/] + JRST MSCHEM + CAMN A,[SIXBIT /R/] + JRST MR + CAMN A,[SIXBIT /TJ6/] + JRST MTJ6 + CAMN A,[SIXBIT /TEX/] + JRST MTEX + CAMN A,[SIXBIT /MACSYM/] + JRST MMACSY + CAMN A,[SIXBIT /MICRO/] + JRST MMICRO + CALL DELEWO + .VALUE [ASCIZ / :A language not known to TAGS was specified. +The language must be MIDAS, PALX, FAIL, TECO, LISP, Scheme, MUDDLE, +R, TJ6, TeX or MACSYMA. + + +:kill ¯] + +;HERE AT EOF IN SOURCE FILE, TO FINISH THE ENTRY. +SRCEOF: MOVE A,SFCHRS ;COMPUTE TOTAL # CHARS IN SOURCE FILES. + ADDM A,SFTOTC ;IN CASE SOMEONE IS INTERESTED. + WRITEI ^_ ;FIRST PUT THE ^_ CRLF AT THE END. + WRITEI ^M + WRITEI ^J + MOVE A,OUTCNT ;NOW HACK THE ENTRY SIZE: GET SIZE, + ADDM A,OUTTOT +REPEAT 5,[ + IDIVI A,10. ;COMPUTE ITS DIGITS, + SAVE B +] + MOVE B,ONUMPT ;AND STORE THEM INTO RIGHT PLACE. +REPEAT 5,[ + REST A + ADDI A,"0 + IDPB A,B +] + RET + +;SCAN A FILE OF MACSYMA CODE FOR FUNCTION DEFINITIONS. +MMACSY: +IRPC CH,,MACSYMA + WRITEI "CH +TERMIN + WRITEI ^M + WRITEI ^J +MMACSL: MOVE A,[440700,,LINBUF] + MOVEI D,2 +MMACS0: CALL SFREDC ;MACSYMA TAG LINES MUST START WITH SQUOZE. + SKIPN MACSLP(I) + JRST [ CAIE I,^L ;BUT WE DO ALLOW A ^L AT THE BEGINNING OF A LINE + JRST MMAIGN ;(THAT IS, A PAGE WITH NO CRLF AT THE FRONT). + IDPB I,A + AOJA D,MMACS0] ;SUCH A ^L MUST BE INCLUDED IN THE LINE IN THE TAGS FILE. + IDPB I,A +MMACS1: CALL SFREDC + CAIL D,50. ;IF SYMBOL GETS TOO LONG, IGNORE IT. + JRST MMAIGN + IDPB I,A ;SAVE ALL SQUOZE CHARS AT START OF LINE + SKIPE MACSLP(I) ;IN LINBUF, AND THE FIRST NON-SQUOZE. + AOJA D,MMACS1 ;D ENDS UP WITH # OF CHARS IN LINBUF. + MOVE H,SFCHRS ;H HAS ADDRESS OF NEXT CHARACTER (POSITION OF DEFINITION). + CALL MMACPS ;SKIP OVER SPACES. + CAIN I,": + JRST MMACS3 ;NAME ENDED BY COLON => THIS IS ASSIGNMENT. COUNT IT. + CAIE I,"( + CAIN I,"[ ;] IN ANY MACSYMA FUNCTION DEFINITION, THE FUNCTION NAME + CAIA ;MUST BE FOLLOWED BY A PAREN OR BRACKET. + JRST MMAIGN +MMACS4: CALL SFREDC ;SO SKIP PAST THE MATCHING CLOSE. + CAIN I,^J + JRST MMACSL + CAIE I,"( ;DOUBLE NESTING OF PARENS OF BRACKETS => + CAIN I,"[ ;THIS IS NOT A FUNCTION DEFN, BUT SOMETHING RANDOM, + JRST MMAIGN ;SO IGNORE IT. + CAIE I,") + CAIN I,"] ;WHEN WE REACH THE MATCHING CLOSE, + CAIA + JRST MMACS4 + CALL SFREDC ;IT CAN LEGITIMATELY BE FOLLOWED BY ANOTHER OPEN, + CALL MMACPS + CAIE I,"( ;IN WHICH CASE SKIP TO ITS MACTHING CLOSE. + CAIN I,"[ ;] + JRST MMACS4 + CAIE I,": ;COLON FOLLOWS THE PARENS OR BRACKETS => FUNCTION DEFN. + JRST MMAIGN +MMACS3: SAVE I ;IF IT'S A FUNCTION DEFINITION, OUTPUT IT. + MOVE A,[440700,,LINBUF] ;NOT EVERYTHING UP TO THE COLON, JUST FIRST SYMBOL AND + MOVEM A,LINPNT ;THE FOLLOWING DELIMITER. + CALL OTAG ;TAG => OUTPUT IT. + REST I +MMAIGN: CALL IGNLIN + JRST MMACSL + +;SKIP 0 OR MORE CHARS UNTIL NON-SPACE. +MMACPS: CAIE I,40 + RET + CALL SFREDC + JRST MMACPS + +;MACSLP+CH IS NONZERO IF CH IS AN ALPHANUMERIC CHARACTER. +MACSLP: REPEAT "%,0 + 1 ;% + REPEAT "0-"%-1,0 + REPEAT "9-"0+1,1 ;DIGITS + REPEAT "A-"9-1,0 + REPEAT "Z-"A+1,1 ;U.C. LETTERS + REPEAT "A+40-"Z-1,0 + REPEAT "Z-"A+1,1 ;L.C. LETTERS + REPEAT 200-"Z-40-1,0 +IFN .-MACSLP-200,.ERR TABLE LENGTH + +;SCAN A FILE OF EMACS MACROS FOR TAGS. +MTECO: +IRPC CH,,TECO + WRITEI "CH +TERMIN + WRITEI ^M + WRITEI ^J +MTECO0: CALL SFREDC ;ONLY LINES STARTING WITH AN ! CAN HAVE TAGS. + CAIE I,"! + JRST [ CALL IGNLIN + JRST MTECO0] + MOVEI N,SFREDC + SAVE SFCHRS + CALL RLIN ;READ IN THE REST OF THE LINE (MUST REMEMBER + MOVE A,LINPNT ;TO PUT THE ! IN LATER IF THERE IS A TAG). + SETZB C,D ;C HAS POS SCANNING AT, D HAS POS OF LAST :!. + REST H ;H HAS POS IN FILE OF FRONT OF LINE. +MTECO1: ILDB I,A + AOS C + CAIN I,^C + JRST MTECO3 ;END OF LINE => IF FOUND TAG, STORE IT. +MTECO2: CAIE I,": + JRST MTECO1 + ILDB I,A + AOS C + CAIN I,^C + JRST MTECO3 + CAIE I,"! + JRST MTECO2 + MOVE D,C ;REMEMBER WHERE THE LAST :! ON THE LINE ENDS. + JRST MTECO1 ;KEEP SEARCHING FOR ANOTHER SO FIND THE LAST. + +MTECO3: JUMPE D,MTECO0 ;END OF LINE. IF NO TAG, JUST SCAN NEXT LINE. + ADD H,D ;THIS LINE HAS A TAG. COMPUTE POS. OF TAG IN H. + WRITEI "! ;WRITE THE "!" THAT WAS READ BEFORE CALLING RLIN. + CALL OTAG ;OUTPUT THE REST OF THE LINE, AND THE POS. + JRST MTECO0 + +;SCAN A FILE OF LISP CODE FOR FUNCTIONS, ETC. + +DEFINE LTEST PREFIX,FTAG + SETZ D, ;D HAS HOW MANY CHARS OF LINE WE HAVE READ. + MOVE A,LINPNT +IRPC CH,,[PREFIX] + ILDB I,A ;"(" MUST BE FOLLOWED BY AN ATOM. + CAIE I,"CH + CAIN I,"CH+40 ;WHICH STARTS WITH THE PREFIX. + AOSA D + JRST FTAG +TERMIN TERMIN + +MLISP: +IRPC CH,,LISP + WRITEI "CH +TERMIN + WRITEI ^M + WRITEI ^J +MLISPL: SETZM FORMF +MLISP5: CALL SFREDC ;DOES THIS LINE START WITH A "("? + CAIN I,^L + JRST [ SETOM FORMF + JRST MLISP5] ;ALLOW A ^L BEFORE THE "(". + CAIE I,"( + JRST MLIGN + SAVE SFCHRS + MOVEI N,SFREDC + CALL RLIN ;READ IN REST OF LINE. + REST H ;H HAS POS. IN FILE OF START OF LINE. + LTEST DEF,MLISP7 ;SEE IF FUNCTION CALLED STARTS WITH "DEF". + AOS D + ILDB I,A + CAIE I,"P + CAIN I,"P+40 ;BUT IS NOT "DEFPROP" + JRST MLISP7 + JRST MLISP2 + +MLISP7: LTEST MACRO,MLISP8 ;SEE IF FUNCTION STARTS WITH "MACRO" + JRST MLISP2 + +MLISP8: LTEST ENDF,MLISPL ;SEE IF FUNCTION IS "ENDF" + +;HERE IF FUNCTION BEING CALLED LOOKS GOOD (STARTS "DEF" OR "MACRO" OR "ENDF"). +MLISP2: CAIE I,^I + CAIN I,40 ;NOW FIND THE SPACE ENDING THIS ATOM. + JRST MLISP1 + CAIN I,^C + JRST MLISPL ;(NO TAG HERE IF NOT ONE ON THIS LINE.) + ILDB I,A + AOJA D,MLISP2 + +MLISP1: ILDB I,A ;THERE MUST BE ANOTHER ATOM AFTER THAT. + AOS D + CAIN I,^C + JRST MLISPL + CAIE I,40 + CAIN I,^I + JRST MLISP1 + CAIN I,"( ;ALLOW "(DEFUN (FOO BAR) ..." AND KEEP SCANNING TO ")" THEN. + JRST MLISPO +MLISP3: CAIE I,40 ;NOW FIND THE SPACE, TAB OR CR ENDING THIS ATOM. + CAIN I,^C + JRST MLISP4 + CAIN I,^I + JRST MLISP4 + CAIE I,"( + CAIN I,") + JRST MLISP4 + CAIE I,"" + CAIN I,"| + JRST [ ;STRING OR VBAR'D SYMBOL => SCAN OVER IT AND THEN TAG ENDS. + CALL MLVBAR + JRST MLISP4] + CAIN I,"/ + JRST [ ILDB I,A ;SLASH MAKES FOLLOWING SPACE NOT END ATOM. + AOJA D,.+1] + ILDB I,A + AOJA D,MLISP3 + +;HERE FOR VERTICAL BAR OR DOUBLE-QUOTE SEEN IN FUNCTION BEING DEFINED. +MLVBAR: PUSH P,I +MLVBA1: ILDB I,A + AOS D + CAIN I,^C ;ABORT AT EOL INSIDE VBARS. + JRST MLVBA2 + CAME I,(P) + JRST MLVBA1 +MLVBA2: SUB P,[1,,1] + RET + +;HERE AFTER FINDING THE END OF THE NAME OF THE FUNCTION BEING DEFINED. WE HAVE A TAG! +MLISP4: CAIN I,^C + MOVEI I,^M ;EOL WAS REPRESENTED AS ^C BY RLIN. TURN BACK TO ^M FOR FILE. + DPB I,A + ADD H,D ;COMPUTE IN H THE POS. OF THE TAG IN THE FILE. + SKIPL FORMF + JRST MLISP6 + WRITEI ^L +MLISP6: WRITEI "( ;WRITE THE "(" THAT WAS READ BEFORE RLIN. + CALL OTAG ;WRITE THE REST OF THE TAG'S LINE. + JRST MLISPL + +;COME HERE IF WE FIND A "(" WHERE THE START OF THE FUNCTION NAME IS SUPPOSED TO BE. +MLISPO: CAIE I,") ;SCAN TO MATCHING ")", BUT STOP AT END OF LINE. + CAIN I,^C ;WE ASSUME THAT THERE AREN'T ANY FURTHER PAREN LEVELS + JRST MLISP4 ;INSIDE THE FUNCTION NAME, FOR SIMPLICITY. + CAIE I,"" + CAIN I,"| + JRST [ + CALL MLVBAR + JRST MLISPO] + CAIN I,"/ + JRST [ ILDB I,A ;SLASH MAKES FOLLOWING CHAR NOT SPECIAL. + AOJA D,.+1] + CAIN I,^C ;ONLY END OF LINE STILL COUNTS IF SLASHIFIED. + JRST MLISP4 + ILDB I,A + AOJA D,MLISPO + +MLIGN: CALL IGNLIN ;IGNORE REST OF THIS LINE OF LISP FILE. + JRST MLISPL + +; Scan a file of Scheme code. + +mschem: +irpc ch,,Scheme + writei "ch +termin + writei ^m + writei ^j + jrst mscm0 + +mscm89: movei i,^m + dpb i,a +mscm90: addi h,(d) + call otag +mscm0: save sfchrs + movei n,sfredc + call rlin + rest h + movei d,4 ; Account for "(def" + move a,linpnt +mscm20: ildb i,a + caie i,40 + cain i,^i + aoja d,mscm20 ; First, skip any leading whitespace + caie i,"( + jrst mscm0 + ildb i,a + caie i,"d + cain i,"D + caia + jrst mscm0 + ildb i,a + caie i,"e + cain i,"E + caia + jrst mscm0 + ildb i,a + caie i,"f + cain i,"F + caia + jrst mscm0 +mscm30: ildb i,a ; Find the end of the defmumble + caie i,40 + cain i,^i + aoja d,mscm40 ; found whitespace after the defmumble + cain i,^c + jrst mscm0 ; end of line => no tag + caie i,"( + cain i,"' + aoja d,mscm40 + aoja d,mscm30 ; else keep looking + +mscm40: ildb i,a ; Find thing being defined + caie i,40 + cain i,^i + aoja d,mscm40 ; skip more whitespace + caie i,"( + cain i,"' + aoja d,mscm40 + cain i,^c + jrst mscm0 ; end of line => no tag + aoja d,mscm50 ; go find space or end of line + +mscm50: ildb i,a ; Find space or end of line + caie i,40 + cain i,^i + aoja d,mscm90 + cain i,") + aoja d,mscm90 + cain i,^c + aoja d,mscm89 + caie i,"( + cain i,"' + aoja d,mscm90 + aoja d,mscm50 ; keep looking + +;SCAN A FILE OF R MACROS FOR TAGS. +MR: WRITEI "R + WRITEI ^M + WRITEI ^J +MR0: CALL SFREDC ;ONLY LINES STARTING WITH A . CAN HAVE TAGS. + CAIE I,". + JRST MRIGN + MOVEI N,SFREDC + SAVE SFCHRS + CALL RLIN ;READ IN THE REST OF THE LINE (MUST REMEMBER + REST H ;H HAS POS IN FILE OF FRONT OF LINE. + LTEST [RTAG]MR2 ;LINES STARTING WITH "RTAG" ARE TAGS PUT IN JUST FOR :TAGS. + JRST MR1A + +MR2: LTEST [AM]MR2A + JRST MR1A + +MR2A: LTEST [DE]MR0 ;DOES LINE START WITH "DE "? IF SO, IT'S A TAG. +MR1A: ILDB I,A ;SKIP TO THE NEXT SPACE, PAST THE + AOS D ;TAG-DEFINING OPERATION (".DE" OR ".DEFINE", ETC.) + CAIE I,^I + CAIN I,40 + JRST MR1B + CAIN I,^C ;END OF LINE BEFORE SPACE MEANS THERE'S NO TAG NAME HERE. + JRST MR0 + JRST MR1A + +MR1B: ILDB I,A ;THEN SKIP ALL SPACES, IN CASE THERE ARE SEVERAL. + AOS D + CAIN I,^C + JRST MR0 + CAIE I,^I + CAIN I,40 ;WE LEAVE THIS LOOP ON SEEING THE START OF THE TAG NAME. + JRST MR1B +MR1: ILDB I,A ;FIND END OF TAG NAME, COUNTING CHARS IN D. + CAIE I,^I + CAIN I,40 ;A SPACE ENDS IT, AND IS INCLUDED IN THE COUNT. + AOSA D + CAIN I,^C ;END OF LINE (^C) ENDS NAME AND IS NOT INCLUDED. + CAIA + AOJA D,MR1 + ADDI H,(D) ;THIS LINE HAS A TAG. COMPUTE POS. OF TAG IN H. + WRITEI ". ;WRITE THE "." THAT WAS READ BEFORE CALLING RLIN. + CALL OTAG ;OUTPUT THE REST OF THE LINE, AND THE POS. + JRST MR0 + +MRIGN: CALL IGNLIN + JRST MR0 + +;SCAN A FILE OF TJ6 INPUT FOR TAGS. +MTJ6: WRITEI "T + WRITEI "J + WRITEI "6 + WRITEI ^M + WRITEI ^J +MTJ0: CALL SFREDC ;ONLY LINES STARTING WITH A . CAN HAVE TAGS. + CAIE I,". + JRST MTJIGN + MOVEI N,SFREDC + SAVE SFCHRS + CALL RLIN ;READ IN THE REST OF THE LINE (MUST REMEMBER + REST H ;H HAS POS IN FILE OF FRONT OF LINE. + LTEST [C TAG ]MTJ0 ;A TAG IS A LINE STARTING WITH ".C TAG ". +MTJ1B: ILDB I,A ;THEN SKIP ALL SPACES, IN CASE THERE ARE SEVERAL. + AOS D + CAIN I,^C + JRST MTJ0 + CAIE I,^I + CAIN I,40 ;WE LEAVE THIS LOOP ON SEEING THE START OF THE TAG NAME. + JRST MTJ1B +MTJ1: ILDB I,A ;FIND END OF TAG NAME, COUNTING CHARS IN D. + CAIE I,^I + CAIN I,40 ;A SPACE ENDS IT, AND IS INCLUDED IN THE COUNT. + AOSA D + CAIN I,^C ;END OF LINE (^C) ENDS NAME AND IS NOT INCLUDED. + CAIA + AOJA D,MTJ1 + ADDI H,(D) ;THIS LINE HAS A TAG. COMPUTE POS. OF TAG IN H. + WRITEI ". ;WRITE THE "." THAT WAS READ BEFORE CALLING RLIN. + CALL OTAG ;OUTPUT THE REST OF THE LINE, AND THE POS. + JRST MTJ0 + +MTJIGN: CALL IGNLIN + JRST MTJ0 + +;Scan a file of TeX input for tags. +mtex: writei "T + writei "e + writei "X + writei ^M + writei ^J + jrst mtex0 + +mtxign: call ignlin +mtex0: call sfredc ;only lines starting with a \ can have tags. + caie i,"\ + jrst mtxign + movei n,sfredc + save sfchrs + call rlin + rest h + ltest [TAG{]mtex0 +mtexlp: ildb i,a + cain i,"} ;close brace ends tag and is included. + aoja d,mtextg + caie i,^C ;end of line ends tag and is not included. + aoja d,mtexlp +mtextg: addi h,(d) ;position of tag in H + writei "\ + call otag + jrst mtex0 + +;SCAN A FILE OF MUDDLE CODE FOR DEFINE AND DEFMAC. + +MMUDDL: +IRPC CH,,MUDDLE + WRITEI "CH +TERMIN + WRITEI ^M + WRITEI ^J +MMUDD0: SETZM FORMF +MMUDD5: CALL SFREDC ;DOES THIS LINE START WITH A "<"? + CAIN I,^L + JRST [ SETOM FORMF + JRST MMUDD5] ;ALLOW A ^L BEFORE THE "<". + CAIE I,"< + JRST MMUDIGN + SAVE SFCHRS + MOVEI N,SFREDC + CALL RLIN ;READ IN REST OF LINE. + REST H + MOVE A,LINBUF ;THE "<" MUST BE FOLLOWED BY EITHER + MOVE D,LINBUF+1 ;"DEFINE " OR "DEFMAC ". + AND D,[.BYTE 7 ? 177 ? 177] + CAMN A,[ASCII /DEFIN/] + CAME D,[ASCII /E /] + CAIA + JRST MMUDD2 + CAMN A,[ASCII /DEFMA/] + CAME D,[ASCII /C /] + JRST MMUDD0 ;OTHERWISE, THERE IS NO TAG ON THIS LINE. +MMUDD2: MOVE A,LINPNT + ADDI A,1 ;ADVANCE A PAST THE DEFINE/DEFMAC + REPEAT 2,IBP A ;AND THE SPACE THAT FOLLOWS IT. + MOVEI D,7 ;D HAS HOW MANY CHARS OF LINE WE HAVE READ. +MMUDD1: ILDB I,A ;THERE MUST BE ANOTHER ATOM AFTER THAT. + AOS D + CAIE I,^C + CAIN I,"< + JRST MMUDD0 + CAIE I,". + CAIN I,"( + JRST MMUDD0 + CAIN I,40 + JRST MMUDD1 +MMUDD3: CAIN I,40 ;NOW FIND THE SPACE ENDING THIS ATOM. + JRST MMUDD4 + CAIN I,^C + JRST MMUDD0 ;(NO TAG HERE IF NOT ONE ON THIS LINE.) + ILDB I,A + AOJA D,MMUDD3 + +MMUDD4: ADD H,D ;COMPUTE IN H THE POS. OF THE TAG IN THE FILE. + SKIPL FORMF + JRST MMUDD6 + WRITEI ^L +MMUDD6: WRITEI "< ;WRITE THE "<" THAT WAS READ BEFORE RLIN. + CALL OTAG ;WRITE THE REST OF THE TAG'S LINE. + JRST MMUDD0 + +MMUDIGN: CALL IGNLIN ;IGNORE REST OF THIS LINE OF MUDDLE FILE. + JRST MMUDD0 + +;Scan a file of MICROcode + +mmicro: writei "M + writei "I + writei "C + writei "R + writei "O + writei ^M + writei ^J + jrst mmicgo + +mmiout: move h,sfchrs ;Current position is end of tag. + movei d,(c) ;RH(C) should contain length of tag. + call otag ;Output tag. +mmigno: call ignlin ;Flush rest of line. +mmicgo: move a,[440700,,linbuf] ;A: Byte pointer to LINBUF. + movsi c,-40. ;C: Length counter. + setzi b, ;B: 0 => only digits and trash so far. + ; Else one plus number of first real char. + call sfredc ;Check first character specially: + caie i,40 ;Space + cain i,^I ;or Tab? + jrst mmigno ;Ignore line. + jrst mmic1 + +mmic0: call sfredc +mmic1: cain i,^J ;End of the line. + jrst mmicgo + cain i,"; ;Comment? + jrst mmigno + aobjp c,mmigno ;Line got too long. + idpb i,a + cain i,"" ;Macro definition? + jrst mmimac + cain i,"/ ;Field definition? + jrst mmidef + cain i,": ;Label? + jrst mmilbl + jumpn b,mmic0 ;Already found first real char? + caile i,40 ;Trash? + cain i,177 + jrst mmic0 ;Yes. +;Allow numbers +; cail i,"0 ;Non-digit? +; caile i,"9 + movei b,(c) ;Yes. + jrst mmic0 + +mmidef: call sfredc + caie i,"= ;Really a definition? + jrst mmic1 + idpb i,a + aoja c,mmiout + +mmilbl: jumpn b,mmiout ;Real chars? + jrst mmigno + +mmimac: move a,[440700,,linbuf] + ildb i,a ;Find first real char. + sojg b,.-1 + caie i,". + jrst mmiout + move b,a ;Remember that BP. +irpc ch,,[TOC] + ildb i,a + caie i,"ch + cain i,40+"ch + skipa + jrst mmmac1 +termin + jrst mmigno + +mmmac1: move a,b +irpc ch,,[TITLE] + ildb i,a + caie i,"ch + cain i,40+"ch + skipa + jrst mmiout +termin + jrst mmigno + +;SCAN A MIDAS OR FAIL OR PALX FILE FOR TAGS. + +MFAIL: +IRPC CH,,FAIL + WRITEI "CH +TERMIN + SETOM FAILP + JRST MMIDAF + +MPALX: +IRPC CH,,PALX + WRITEI "CH +TERMIN + SETZM FAILP + SETOM PALXP + JRST MMIDAP + +MMIDAS: +IRPC CH,,MIDAS + WRITEI "CH +TERMIN + SETZM FAILP +MMIDAF: SETZM PALXP +MMIDAP: WRITEI ^M ;MIDAS AND FAIL JOIN HERE. + WRITEI ^J +MMIDAL: MOVE A,[440700,,LINBUF] + MOVEI D,2 +MMIDA0: CALL SFREDC ;MIDAS TAG LINES MUST START WITH SQUOZE. + SKIPN SQUOZP(I) + JRST [ CAIE I,^L ;BUT WE DO ALLOW A ^L AT THE BEGINNING OF A LINE + JRST MMIGN1 ;(THAT IS, A PAGE WITH NO CRLF AT THE FRONT). + IDPB I,A + AOJA D,MMIDA0] ;SUCH A ^L MUST BE INCLUDED IN THE LINE IN THE TAGS FILE. + SETZ B, + IDPB I,A + CAIE I,". ;B GETS 0 IFF FIRST SQUOZE CHAR IS DOT. +MMIDA1: SETO B, ;B GETS -1 WHEN SECOND SQUOZE CHARACTER IS SEEN. + CALL SFREDC + CAIL D,15. ;IF LINE GETS TOO LONG, IGNORE IT. + JRST MMIGN + IDPB I,A ;SAVE ALL SQUOZE CHARS AT START OF LINE + SKIPE SQUOZP(I) ;IN LINBUF, AND THE FIRST NON-SQUOZE. + AOJA D,MMIDA1 ;D ENDS UP WITH # OF CHARS IN LINBUF. + JUMPE B,MMIGN ;IGNORE TAG IF ITS NAME IS ".". ".=" IS NOT A TAG. +MMIDA3: CAIE I,": + CAIN I,"= + CAIA + JRST MMIGN2 ;IF 1ST NONSQUOZE ISN'T : OR =, NO TAG HERE. +MMIDA4: SKIPN PALXP + JRST MMIDA5 ;FOR PALX, DON'T MENTION TAGS SUCH AS "10$" + MOVE B,[440700,,LINBUF] ;SINCE THEY ARE JUST LOCAL TAGS. +MMIDA6: CAMN B,A + JRST MMIDA5 + ILDB C,B ;FIND THE FIRST CHARACTER AFTER THE ^L'S, IF ANY. + CAIN C,^L + JRST MMIDA6 + CAIL C,"0 + CAILE C,"9 ;IF IT IS A DIGIT, THIS IS A LOCAL TAG. + JRST MMIDA5 + JRST MMIGN + +MMIDA5: SAVE I + MOVE H,SFCHRS + MOVE A,[440700,,LINBUF] + MOVEM A,LINPNT + CALL OTAG ;TAG => OUTPUT IT. + REST I +MMIGN: CALL IGNLIN + JRST MMIDAL + +;IN A FAIL PROGRAM, ALLOW ^ AND  AND ^ ^ AND ^A^A AT START OF LINE TO MODIFY A LABEL. +MMIGN1: CAIE I,"^ + CAIN I,^A + SKIPN FAILP + JRST MMIGN + IDPB I,A + AOJA D,MMIDA0 ;IF WE HAVE ONE, IS NEXT CHAR SQUOZE? + +MMIGN2: SKIPN FAILP ;FAIL AND PALX ALLOW SPACES BEFORE COLONS AND ='S. + SKIPE PALXP + CAIA + JRST MMIGN + CAIN I,"_ ;IT ALSO MAKES _ EQUIVALENT TO =. + JRST MMIDA4 + CAIE I,40 + JRST MMIGN + CALL SFREDC + JRST MMIDA3 + +;SQUOZP+CH IS NONZERO IF CH IS A SQUOZE CHARACTER. +; Value is CH in SIXBIT (sic). +SQUOZP: REPEAT "$, 0 + '$ ? '% ;$ AND % + REPEAT ".-"%-1, 0 + '. ;. + REPEAT "0-".-1, 0 + REPEAT "9-"0+1, '0+.RPCNT ;DIGITS + REPEAT "A-"9-1, 0 + REPEAT "Z-"A+1, 'A+.RPCNT ;U.C. LETTERS + REPEAT "A+40-"Z-1, 0 + REPEAT "Z-"A+1, 'A+.RPCNT ;L.C. LETTERS + REPEAT 200-"Z-40-1, 0 +IFN .-SQUOZP-200,.ERR TABLE LENGTH + +; XMIDAS is like MIDAS, except it is smarter. +xmidas: +irpc ch,,XMIDAS + writei "ch +termin + writei ^m + writei ^j + jrst xmidgo + +xmidlb: cain c,[sixbit /./] + jrst xmidig + move h,sfchrs +xmidtg: call otag +xmidig: caie i,^j + call ignlin +xmidgo: move a,[440700,,linbuf] + setzi d, + call sfredc + caie i,40 ; ignore lines starting with whitespace + cain i,^i + jrst xmidig + jsp s,getsq1 +xmidnx: caie i,": + cain i,"= + jrst xmidlb + came c,[sixbit /ENIFED/] ; DEF INE + camn c,[sixbit /OTCEV./] ; .VECTOR + jrst xmiddf + came c,[sixbit /ALACS./] ; .SCALAR + camn c,[sixbit /SLAUQE/] ; EQUALS + jrst xmiddf + camn c,[sixbit /TRSNI./] ; .INSRT + jrst xmidig + jsp s,getsq2 + jrst xmidnx + +xmiddf: jsp s,getsq2 + cain i,"" ; Ignore package prefix + jsp s,getsq + soj d, + move h,sfchrs + soja h,xmidtg + +; JSP S,GETSQ to find next squoze syllable on line. +; C contains reverse sixbit of syllable when you return (SIXBIT /ENIFED/ or +; SIXBIT /OTCEV./ or whatever). Terminating character can be found in I. +getsq2: soja d,getsq8 ; .entry with char in I already in LINBUF + +getsq: call sfredc ; .entry +getsq1: idpb i,a ; .entry with char in I +getsq8: caie i,"; + cain i,^j + jrst xmidig + skipn b,squozp(i) + aoja d,getsq + movei d,3(d) + setzi c, + lshc b,-6 ; 1 + call sfredc + idpb i,a + skipn b,squozp(i) + soja d,(s) + lshc b,-6 ; 2 + call sfredc + idpb i,a + skipn b,squozp(i) + jrst (s) + lshc b,-6 ; 3 + call sfredc + idpb i,a + skipn b,squozp(i) + aoja d,(s) + lshc b,-6 ; 4 + call sfredc + idpb i,a + movei d,3(d) + skipn b,squozp(i) + soja d,(s) + lshc b,-6 ; 5 + call sfredc + idpb i,a + skipn b,squozp(i) + jrst (s) + lshc b,-6 ; 6 +getsq9: call sfredc + idpb i,a + skipe squozp(i) + aoja d,getsq9 + aoja d,(s) + +;Process an INFO file (/I), which contains its own tag table. +;We copy the input file into the output, while sending the tag table +;down outpnt. When we come upon the string "Tag Table:" on the line after +;the end of a node, we write the tag table into the output file, ended by +;a ^_, and flush all of the input file to the next ^_. +;The rest of the input file is copied with no processing. +;The terminator (comma, tab or CR) of a node name is not included +;in its entry in the tag table; the name is terminated directly by the rubout +;before the character address. This is because we look for exact matches +;on a name, when selecting a node in INFO, rather than for substring matches. +;We can do it by searching for the node name and a rubout. +;If the actual terminator were present, since it could be either comma, tab or CR, +;we couldn't include it in the search command. +MINFO: MOVE A,[440700,,SFBFR] + MOVEM A,SFPNT ;MARK BUFFER AS EMPTY (SFPNT ILDBS A ^C + MOVEI B,^C ;WHICH SFEPT POINTS AT). + IDPB B,A + MOVEM A,SFEPT + SETZM SFCHRS ;INIT CHAR POS IN SOURCE FILE TO 0. + SETZM OUTCNT ;INIT SIZE OF ENTRY WRITTEN TO 0. + .IOPUS CHIN, ;MOVE INPUT FILE TO CHSRC SO THAT SFREDC WILL WORK ON IT. + .IOPOP CHSRC, + CALL SFREDC ;LOAD THE SOURCE BUFFER. FROM NOW ON, WHEN WE + MOVEM P,EOFP + MOVEI A,MINFO9 ;PREMATURE EOF IN SOURCE CAUSES AN ERROR. + MOVEM A,EOFJ + SETOM SRCCPY ;RELOAD THE BUFFER, THE OLD STUFF GETS COPIED OUT. + CAIA +MINFOL: CALL SFREDC ;DOES THIS LINE START WITH A "^_" + CAIE I,^_ + JRST [ CALL IGNLIN + JRST MINFOL] + CALL IGNLIN ;SKIP IT; LOOK AT THE NEXT ONE. + MOVEI N,SFREDC + SAVE SFCHRS + CALL RLIN ;READ IN THE LINE THAT FOLLOWS THE ^_. + REST H ;H HAS POS. IN FILE OF THE ^_. + LTEST TAG TABLE,MINFO1 ;IS THIS WHERE THE TAG TABLE GOES INTO THE FILE? +;WRITE THE TAG TABLE INTO THE FILE + MOVE A,[440700,,SFBFR] + SETZM SRCCPY ;STOP COPYING OUT OUR INPUT FILE, BUT FIRST DO COPY +MINFO4: ILDB I,A ;THE REST OF WHAT WE HAVE READ SO FAR + .IOT CHOUT,I + CAME A,SFPNT ;(IE, UP TO END OF THIS LINE). + JRST MINFO4 +MINFO5: CALL SFREDC ;NOW READ IN AND THROW AWAY ALL OF THE FILE TILL THE + CAIE I,^_ ;NEXT LINE THAT STARTS WITH A ^_. + JRST [ CALL IGNLIN + JRST MINFO5] + MOVEI A,MINFOE + MOVEM A,EOFJ + MOVEM P,EOFP +MINFO6: IDPB I,OUTPNT ;COPY THE ^_ AND ALL THE REST OF THE INPUT FILE + AOS OUTCNT ;ONTO THE END OF THE TAG TABLE, WHICH WILL THEN + CALL SFREDC ;BE OUTPUT, SO THAT THE TAG TABLE IS STUCK INTO + JRST MINFO6 ;THE INPUT FILE AT THIS POINT. + +MINFOE: MOVE A,OUTCNT ;AT EOF, COME HERE. WRITE OUT TAG TABLE AND + MOVEM A,OUTTOT ;TAIL OF SOURCE FILE, AND RENAME AND CLOSE. + JRST DONE + +;HERE ON A LINE WHICH IS A TAG. THE TAG NAME IS PRECEDED BY "NODE: ". FIND IT. +MINFO1: SETZ D, ;D HAS HOW MANY CHARS OF LINE WE HAVE READ. + MOVE A,LINPNT +MINFON: +IRPC CH,,[NODE: ] + ILDB I,A + AOS D + CAIE I,"CH + CAIN I,"CH+40 + CAIA + JRST MINFON +TERMIN +MINFO2: ILDB I,A ;NOW FIND THE END OF THE TAG NAME, + AOS D ;WHICH IS THE NEXT COMMA, TAB OR CR. + CAIE I,", + CAIN I,^I + JRST MINFO3 + CAIE I,^M + JRST MINFO2 +MINFO3: SOS D ;DON'T INCLUDE TERMINATOR IN NAME OF TAG! + ADD H,D ;NOW GET POS IN FILE OF TAG END IN H, + CALL OTAG ;AND OUTPUT THE TAG. + JRST MINFOL + +MINFO9: CALL DELEWO + .VALUE [ASCIZ / :Source file does not give a place to insert Tag Table + + +:kill ¯] + +;READ PAST THE NEXT ^J IN THE SOURCE FILE. +IGNLIN: ILDB I,SFPNT + AOS SFCHRS + CAILE I,^J + JRST IGNLIN + CAIN I,^C + CALL SFRLD + CAIE I,^J + JRST IGNLIN + RET + +;OUTPUT THE FIRST C(D) NUMBERS IN LINBUF, THEN A RUBOUT, AND THE +;DECIMAL NUMBER IN H, THEN A CR. + +OTAG: MOVE B,LINPNT ;OUTPUT REST OF LINE UP TO END OF TAG. +OTAG1: ILDB I,B + IDPB I,OUTPNT + AOS OUTCNT + SOJG D,OTAG1 + WRITEI 177 ;AND A RUBOUT + CALL OUTDEC ;AND THE POSITION OF THE TAG. + WRITEI ^M + WRITEI ^J + RET + +;OUTPUT SIXBIT WORD IN A TO ENTRY BEING CONSTRUCTED. +OUTSIX: JUMPE A,CPOPJ ;STOP IF ALL THE REST ARE SPACES. + ROT A,6 ;NEXT CHAR INTO LOW BYTE, + LDB I,[600,,A] ;COPY JUST THAT CHAR INTO I, + XORI A,(I) ;REMOVE IT FROM A. + WRITEI 40(I) + JRST OUTSIX + +;OUTPUT DECIMAL NUMBER IN A TO ENTRY BEING GROWN. +OUTDEC: IDIVI H,10. + HRLM I,(P) + SKIPE H + CALL OUTDEC + HLRZ I,(P) +OUTDGT: WRITEI "0(I) +CPOPJ: RET + +;OUTPUT ASCIZ STRING WHOSE ADDRESS IS IN A. +OUTASC: HRLI A,440700 +OUTAS1: ILDB I,A + JUMPE I,CPOPJ + CALL OUTCHR + JRST OUTAS1 + +PAT: PATCH: BLOCK 100 + +SWDEF OUTBSZ==50.*2000 + +ONUMPT: 0 ;BP TO PLACE IN OUTBUF TO STORE THE ENTRY SIZE IN CHARS, AS 5-DIGIT NUMBER. +OUTCNT: 0 ;# CHARS WRITTEN IN THIS ENTRY. +OUTTOT: 0 ;# CHARS WRITTEN IN ALL. +OUTPNT: 0 ;BP FOR STORING IN OUTBUF. +OUTBUF: BLOCK OUTBSZ + 1 ;MAKE SURE DUMPING KNOWS THIS CORE MUST EXIST. + END BEG