.MACRO MARGOT ;CALLING THIS MACRO DEFINES THE MARGOT ;MACROS .MCALL EQCON$ EQCON$ .MCALL EQVAR$ EQVAR$ .MCALL STORE$ .MCALL FETCH$ .MCALL ATLAB$ .MCALL GNSUC$ .MCALL GNFAI$ .MCALL GNBEG$ .MCALL GNLUP$ .MCALL ATSUC$ .MCALL ATFAI$ .MCALL ATBEG$ .MCALL ATGEN$ .MCALL ATLUP$ .MCALL GTSUC$ .MCALL GTLUP$ .MCALL PSHST$ .MCALL POPST$ .MCALL CKSTA$ .MCALL CKMOS$ .MCALL CKNON$ .MCALL ARGCK$ .MCALL EMITL$ .MCALL EMITX$ .MCALL EMITW$ .MCALL ENTER$ .MCALL DEFSY$ .MCALL DEFAC$ .MCALL CHARAC .MCALL STRING .MCALL KEYWOR .MCALL ALLOW .MCALL REQUIR .MCALL FAIL .MCALL ACTION .MCALL ENDACT .MCALL SYNTAX .MCALL ENDSYN .MCALL OR .MCALL OPTION .MCALL ENDOPT .MCALL REP0$ .MCALL REP2$ .MCALL REPEAT .MCALL ENDREP .MCALL ALTERN .MCALL ENDALT .MCALL LIS0$ .MCALL LIS2$ .MCALL LIST .MCALL OF .MCALL ENDLIS .ENDM ; ; ; .MACRO EQCON$ ; ; VERSION ; ; MATHEW MYSZEWSKI 31-JAN-76 ; ; MODIFIED BY: ; PAUL CASHMAN 4-MAR-76 ; ; ; FUNCTION: ; ; MARGOT - MACRO ARGOT. ; ARGOT - A SPECIAL VOCABULARY AND IDIOM USED BY A PAR- ; TICULAR UNDERWORLD GROUP, ESPECIALLY AS A ; MEANS OF PRIVATE COMMUNICATION. ; THE LANGUAGE OF A PARTICULAR SOCIAL GROUP ; OR CLASS. ; DIALECT, VERNACULAR, LINGO, JARGON, CANT, ; OR SLANG. ; MARGOT MACROS - A SET OF MACROS USED TO DEFINE A LANGUAGE ; DIALECT. ; MARGOT TABLES - THE DRIVING TABLES FOR THE MARGOT INTERPRETER ; WHICH RESULT FROM EXPANDING CALLS TO THE ; MARGOT MACROS. ; MARGOT INTERPRETER - THE PROGRAM WHICH, GIVEN AN INPUT SOURCE ; AND MARGOT TABLES, INTERPRETS A LANGUAGE ; DIALECT. ; MARGOT SYSTEM - THE MARGOT MACROS AND THE MARGOT INTERPRETER. ; EQUATED SYMBOLS: ; ; THE SYMBOLS ARE OF THREE FORMS: ; XX.XXX - LOCAL BIT PATTERNS ; X.XXXX - LOCAL OFFSETS ; .XXXXX - OTHER LOCAL SYMBOLS ; ; 1. LOCAL BIT PATTERNS - OF THESE SYMBOLS, ONLY THOSE ; IN SECTIONS 1.1 AND 1.2 REMAIN CONSTANT THROUGHOUT ; THE ASSEMBLY. ; ; 1.1 MARGOT OPCODES - THE FOLLOWING SYMBOLS REPRESENT OPERATOR ; VALUES IN THE MARGOT DRIVING TABLES AND OFFSETS IN THE ; MARGOT INTERPRETTER BRANCH TABLE. ; OP.ALL=0 ; ALLOW (BLANKS) OP.ALT=2 ; ALTERN[ATIVES] OP.CAA=4 ; CALL ACTION (WITH ARGUMENTS) OP.CH0=6 ; CHARAC[TER] (0 ARGS, IE ANY CHAR.) OP.CH1=10 ; CHARAC[TER] (1 ARG, IE SPECIF CHAR) OP.CH2=12 ; CHARAC[TER] (2 ARGS, IE RANGE) OP.CLA=14 ; CALL ACTION OP.CLS=16 ; CALL SYNTAX OP.EAF=20 ; ENDALT FAIL OP.EAS=22 ; ENDALT SUCCEED OP.EOF=24 ; ENDOPT FAIL OP.EOS=26 ; ENDOPT SUCCEED OP.ERF=30 ; ENDREP FAIL OP.ERS=32 ; ENDREP SUCCEED OP.ESF=34 ; ENDSYN FAIL OP.ESS=36 ; ENDSYN SUCCEED OP.FAO=40 ; FAIL OPTION..ENDOPT OP.FAR=42 ; FAIL REPEAT..ENDREP OP.KEY=44 ; KEYWOR[D] OP.LS0=46 ; LIST (NO ARGUMENTS) OP.LS2=50 ; LIST (WITH ARGUMENTS) OP.NOP=52 ; NO OPERATION OP.OPT=54 ; OPTION[AL] OP.ORF=56 ; OR FAIL OP.ORS=60 ; OR SUCCEED OP.RP0=62 ; REPEAT (NO ARGUMENTS) OP.RP2=64 ; REPEAT (WITH ARGUMENTS) OP.REQ=66 ; REQUIR[E] (BLANKS) OP.STG=70 ; STRING OP.SYN=72 ; SYNTAX ; ; 1.2 MARGOT STATES - THE FOLLOWING SYMBOLS REPRESENT VALUES FOR ; THE STATE VARIABLE SYMBOL ST.ATE, WHICH SEE. ; IN.ACT=1 ; IN ACTION ... ENDACT IN.ALT=2 ; IN ALTERN ... ENDALT IN.LIS=3 ; IN LIST ... OF IN.NON=4 ; IN NO STRUCTURE WHATEVER IN.OPT=5 ; IN OPTION ... ENDOPT IN.REP=6 ; IN REPEAT ... ENDREP IN.SYN=7 ; IN SYNTAX ... ENDSYN .MACRO EQCON$ ;SELF-DESTRUCT ON FIRST CALL .ENDM .ENDM ; ; .MACRO EQVAR$ ;VARIABLE EQUIVALENCING ; ; 1.3 MARGOT STATE VARIABLES ; ST.ATE=IN.NON ; VALUE REFLECTS THE CURRENT STATE - SEE 1.2 ABOVE. ; ; THE FOLLOWING HAVE NO INITIAL DEFINITION BUT ARE DEFINED DURING ; MACRO EXPANSION. ; ; ST.AT TEMPORARY - HAS SAME VALUES AS ST.ATE ; ST.NNN STATE AT NEST DEPTH NNN - SEE N.EST ; ; 1.4 ERROR FLAG ; ; THE ERROR FLAG HAS NO INITIAL VALUE, BUT IS DEFINED AS MACROS ; ARE EXPANDED. ; ; ER.FLG =0 NO ERROR ; =1 ERROR ; ER.FLG IS USED AS THE RESULT OF ARGCK$, CKMOS$, ; AND CKSTA$ TO SIGNAL WHETHER AN ERROR WAS ; DISCOVERED. ; ; 2. LOCAL OFFSETS - ALL OF THE FOLLOWING SYMBOLS VARY DURING ; ASSEMBLY. ; ; 2.1 NEST DEPTH ; N.EST=0 ; THE NUMBER OF UNTERMINATED STRUCTURES ; (ACTION, ALTERN, LIST, OPTION, REPEAT, ; AND SYNTAX). ; N.EST SERVES AS A STACK POINTER FOR THE ; SYMBOLS ST.NNN, L.1NNN, L.2NNN, AND L.3NNN. ; ; 2.2 GENERATED LABELS ; L.ABEL=0 ; THE NUMBER OF LABELS SO FAR GENERATED ; ALSO, THE NUMBER OF THE NEXT GENERATED LABEL - ; SEE .LNNNN. ; ; THE FOLLOWING HAVE NO INITIAL DEFINITION BUT ARE DEFINED AS MACROS ; ARE EXPANDED ; ; L.1NNN SUCCESS LABEL AT NEST DEPTH NNN - SEE N.EST ; L.2NNN FAIL LABEL AT NEST DEPTH NNN - SEE N.EST ; L.3NNN BEGIN LABEL AT NEST DEPTH NNN - SEE N.EST ; L.4NNN LOOP LABEL AT NEST DEPTH NNN - SEE N.EST ; ; 2.3 BRANCH TABLE OFFSETS ; ; THESE OFFSETS ARE A COUNT OF THE NUMBER OF WORDS IN THE ; CORRESPONDING BRANCH TABLE AND MUST BE MULTIPLIED BY TWO ; TO GET THE PROPER BYTE OFFSET. ; A.BTOF=0 ; ACTION BRANCH TABLE OFFSET S.BTOF=0 ; SYNTAX BRANCH TABLE OFFSET ; ; 3. OTHER LOCAL SYMBOLS ; ; 3.1 LABELS ; ; THE FOLLOWING SYMBOLS HAVE NO INITIAL DEFINITION BUT ARE ; DEFINED AS MACROS ARE EXPANDED. ; ; .LNNNN THE NAME OF GENERATED LABEL NNNN ; THE FIRST GENERATED LABEL IS .L0 ; SEE L.ABEL ; .LB1 TEMPORARY - SUCCESS LABEL ; .LB2 TEMPORARY - FAIL LABEL ; .LB3 TEMPORARY - BEGIN LABEL ; .LB4 TEMPORARY - LOOP LABEL ; ; 3.2 MISCELLANEOUS TEMPORARY SYMBOLS ; ; NONE OF THE FOLLOWING SYMBOLS HAVE INITIAL DEFINITIONS. ; THEY ARE DEFINED AS MACROS EXPANSION PROCEEDS. ; ; .N NUMBER OF MACRO ARGUMENTS ; .LEN NUMBER OF CHARACTERS IN A STRING ; .CHR A CHARACTER ; .TYPE TYPE OF CHARACTER: ; =1 DIGIT ; =2 LETTER ; =3 DOT ; =4 DOLLAR SIGN ; =0 OTHER CHARACTER ; .ARG A SINGLE ARGUMENT FROM AN ACTION ARGUMENT LIST ; .LOW LIST/REPEAT LOW BOUND ; .HIGH LIST/REPEAT HIGH BOUND ; ; LOCAL DATA - NONE ; ; GLOBAL SYMBOLS: ; ; THE FOLLOWING TWO SYMBOLS ARE PROGRAM SECTION NAMES AND ARE ; DEFINED AS THE RESULT OF MACRO EXPANSION. ; ; $ACTBT ACTION BRANCH TABLE PROGRAM SECTION NAME ; $SYNBT SYNTAX BRANCH TABLE PROGRAM SECTION ; ; ; TABLE OF CONTENTS FOR MACROS DEFINED WITHIN MARGOT ; ; SERIAL NAME(ARGUMENTS) ABSTRACT ; ; 10 STORE$(PRE,NUM,VAL) PRE'NUM=VAL ; 20 FETCH$(VAR,PRE,NUM) VAR=PRE'NUM ; 30 ATLAB$(LAB) ATTACH LABEL .L'LAB ; 40 GNSUC$(LAB) GENERATE SUCCESS LABEL ; 50 GNFAI$(LAB) GENERATE FAIL LABEL ; 60 GNBEG$(LAB) GENERATE BEGIN LABEL ; 65 GNLUP$(LAB) GENERATE LOOP LABEL ; 70 ATSUC$ ATTACH SUCCESS LABEL ; 80 ATFAI$ ATTACH FAIL LABEL ; 90 ATBEG$ ATTACH BEGIN LABEL ; 100 ATGEN$ ATTACH GENERATED LABEL ; 105 ATLUP$ ATTACH LOOP LABEL ; 110 GTSUC$ GET SUCCESS LABEL ; 115 GTLUP$ GET LOOP LABEL ; 120 PSHST$(STATE) PUSH STATE ONTO STATE STACK ; 130 POPST$ POP STATE STACK ; 140 CKSTA$(STATES) CHECK THAT CURREN STATE IS ONE OF STATES ; 150 CKMOS$ CHECK STATE (MOST STATES ARE OK) ; 160 CKNON$ CHECK THAT ST.ATE=IN.NON (IN NO STRUCTURE) ; 170 ARGCK$(NAME NUM) CHECK NUMBER AND TYPE OF ARGUMENTS ; 180 EMITL$(OP,LAB) EMIT OPERATOR AND LABEL ; 185 EMITX$(OP,LAB,ANDEXP,ADDEXP) EMIT OP AND LABEL EXPRESSION ; 190 EMITW$(LAB) EMIT .WORD .L'LAB ; 200 ENTER$(SECT,OFF,LAB) ENTER LABEL IN BRANCH TABLE ; 210 DEFSY$(NAME,OP,OFFSET) DEFINE NAME AS A MACRO (SYNTAX) ; 215 DEFAC$(NAME,OP1,OP2,OFFSET) DEFINE NAME AS A MACRO (ACTION) ; 220 CHARAC(C1,C2) SCAN CHARACTER ; 230 STRING(STG) SCAN STRING ; 240 KEYWOR(MIN,STG) SCAN KEYWORD ; 250 ALLOW SCAN ZERO OR MORE BLANKS ; 260 REQUIR SCAN ONE OR MORE BLANKS ; 270 FAIL FAIL THE CURRENT STRUCTURE ; 280 ACTION(NAME) DEFINE ACTION ; 290 ENDACT END OF ACTION DEFINITION ; 300 SYNTAX(NAME) DEFINE SYNTAX ; 310 ENDSYN END OF SYNTAX DEFINITION ; 320 OR SEPARATE ALTERNATIVES ; 330 OPTION DEFINE OPTIONAL ITEM ; 340 ENDOPT END OPTIONAL ITEM DEFINITION ; 350 REP0$ REPEAT(ZERO ARGS) IE REPEAT ZERO OR MORE TIMES ; 355 REP2$(N1,N2) REPEAT (WITH ARGS)IE REPEAT N1 TO N2 TIMES ; 360 REPEAT(N1,N2) REPEAT N1 TO N2 TIMES ; 370 ENDREP END REPEAT ; 380 ALTERN DEFINE ALTERNATIVES ; 390 ENDALT END DEFINITION OF ALTERNATIVES ; 400 LIS0$ LIST(ZERO ARGS) IE LIST OF ZERO OR MORE ITEMS ; 405 LIS2$(N1,N2) LIST (WITH ARGS) IE LIST OF N1 TO N2 ITEMS ; 410 LIST(N1,N2) DEFINE LIST OF N1 TO N2 ITEMS ; WITH SEPARATORS ; 420 OF SEPARATES LIST SEPARATORS FROM LIST ITEMS ; 430 ENDLIS END OF LIST DEFIITION .ENDM ; ; 10 STORE$ ; .MACRO STORE$,PRE,NUM,VAL ;STOREVAL IN PRE'NUM PRE'NUM=VAL .ENDM ; ; 20 FETCH$ ; .MACRO FETCH$,VAR,PRE,NUM ;PUT PRE'NUM INTO VAR VAR=PRE'NUM .ENDM ; ; 30 ATLAB$ ; .MACRO ATLAB$,LAB ;ATTACH GIVEN LABEL .L'LAB: .ENDM ; ; 40 GNSUC$ ; .MACRO GNSUC$,LAB ;GENERATE, STACK, AND RETURN SUCCESS LABEL STORE$ L.1,\N.EST,L.ABEL ;STACK LABEL LAB=L.ABEL ;RETURN LABEL L.ABEL=L.ABEL+1 .ENDM ; ; 50 GNFAI$ ; .MACRO GNFAI$,LAB ;GENERATE, STACK, AND RETURN LABEL STORE$ L.2,\N.EST,L.ABEL ;STACK LABEL LAB=L.ABEL L.ABEL=L.ABEL+1 .ENDM ; ; 60 GNBEG$ ; .MACRO GNBEG$,LAB ;GENERATE, STACK, AND RETURN LABEL STORE$ L.3,\N.EST,L.ABEL LAB=L.ABEL L.ABEL=L.ABEL+1 .ENDM ; ; 65 GNLUP$ ; .MACRO GNLUP$,LAB ;GENERATE,STACK, AND RETURN LOOP LABEL STORE$ L.4,\N.EST,L.ABEL L.ABEL=L.ABEL+1 .ENDM ; ; 70 ATSUC$ ; .MACRO ATSUC$ ;ATTACH SUCCESS LABEL FETCH$ LAB,L.1,\N.EST ;GET LABEL ATLAB$ \LAB ;ATTACH IT .ENDM ; ; 80 ATFAI$ ; .MACRO ATFAI$ ;ATTACH FAIL LABEL FETCH$ LAB,L.2,\N.EST ;GET IT ATLAB$ \LAB ;ATTACH IT .ENDM ; ; 90 ATBEG$ ; .MACRO ATBEG$ ;ATTACH BEGIN LABEL FETCH$ LAB,L.3,\N.EST ;GET IT ATLAB$ \LAB ;ATTACH IT .ENDM ; ; 100 ATGEN$ ; .MACRO ATGEN$ ;ATTACH GENERATED LABEL ATLAB$ \L.ABEL ;ATTACH L.ABEL=L.ABEL+1 ;INCREMENT .ENDM ; ; 105 ATLUP$ ; .MACRO ATLUP$ ;ATTACH LOOP LABEL FETCH$ LAB,L.4,\N.EST ;GET IT ATLAB$ \LAB ;ATTACH IT .ENDM ; ; 110 GTSUC$ ; .MACRO GTSUC$,LAB ;GET SUCCESS LABEL FETCH$ LAB,L.1,\N.EST .ENDM ; ; 115 GTLUP$ ; .MACRO GTLUP$,LAB ;GET LOOP LABEL FETCH$ LAB,L.4,\N.EST .ENDM ; ; 120 PSHST$ ; .MACRO PSHST$,STATE ;PUSH GIVEN STATE ONTO STACK STORE$ ST.,\N.EST,ST.ATE ;PUSH CURRENT STATE N.EST=N.EST+1 ;INCREMENT STACK DEPTH ST.ATE=STATE ;SET NEW STATE .ENDM ; ; 130 POPST$ ; .MACRO POPST$ ;POP STATE STACK .IF LE,N.EST .ERROR ;MARGOT AWRY - STACK UNDERFLOW; .MEXIT .ENDC N.EST=N.EST-1 ;DECREMENT STACK DEPTH FETCH$ ST.ATE,ST.,\N.EST ;RESTORE STATE .ENDM ; ; 140 CKSTA$ ; .MACRO CKSTA$,STATES ;CHECK THAT STATE IS AS SPECIFIED ER.FLG=1 ;SET ERROR FLAG .IRP ST.AT, ;REPEAT FOR ALL STATES .IF EQ,ST.AT-ST.ATE ER.FLG=0 .ENDC .ENDM .IF NE,ER.FLG .ERROR ;NOT ALLOWED IN THIS CONTEXT; .ENDC .ENDM ; ; 150 CKMOS$ ; .MACRO CKMOS$ ;CHECK THAT WE ARE IN SOME LEVEL ;OF SYNTAX DEFINITION ER.FLG=1 ;SET ERROR FLAG - ASSUME ERROR .IF EQ,N.EST-1 .IF EQ,ST.ATE-IN.SYN ER.FLG=0 ;RESET ERROR FLAG - WE'RE IMMEDIATELY ;WITHIN SYNTAX STRUCTURE .ENDC .ENDC .IF GT,N.EST-1 .IF EQ,ST.1-IN.SYN ER.FLG=0 ;RESET ERROR FLAG - WE'RE DEEPLY NESTED, ;BUT STILL IN SYNTAX STRUCTURE. .ENDC .ENDC .IF NE,ER.FLG .ERROR ;NOT ALLOWED EXCEPT WITHIN SYNTAX DEFINITION; .ENDC .ENDM ; ; 160 CKNON$ ; .MACRO CKNON$ ;CHECK THAT WE'RE NOT IN A STRUCTURE .IF NE,ST.ATE-IN.NON .ERROR ;UNTERMINATED STRUCTURES - BAD NESTING; ST.ATE=IN.NON .ENDC N.EST=0 .ENDM ; ; 170 ARGCK$ ; .MACRO ARGCK$,NAME,NUM ;CHECK NUMBER AND TYPE OF ARGUMENT ER.FLG=0 ;RESET ERROR FLAG .IF NE,NUM-1 .ERROR NUM ;WRONG NUMBER OF ARGUMENTS - SHOULD BE ONE; ER.FLG=1 .MEXIT .ENDC .LEN=0 .IRPC .CHR, .TYPE=0 .IF GE,''.CHR'-'0 .IF LE,''.CHR'-'9 .TYPE=1 .ENDC .ENDC .IF GE,''.CHR'-'A .IF LE,''.CHR'-'Z .TYPE=2 .ENDC .ENDC .IF EQ,''.CHR'-'. .TYPE=3 .ENDC .IF EQ,''.CHR'-'$ .TYPE=4 .ENDC .IF EQ,.TYPE ER.FLG=1 ;BAD CHARACTER IN MACRO NAME .ENDC .LEN=.LEN+1 .ENDM .IF NE,ER.FLG .ERROR ;ILLEGAL CHARACTER IN NAME; .MEXIT .ENDC .IF GT,.LEN-6 .ERROR .LEN;OVER 6 CHARS IN NAME - EXCESS IGNORED; .MEXIT .ENDC .ENDM ; ; 180 EMITL$ ; .MACRO EMITL$,OP,LAB ;OUTPUT OP AND LABEL .BYTE OP .EVEN .WORD .L'LAB .ENDM ; ; 185 EMITX$ ; .MACRO EMITX$,OP,LAB,ANDEXP,ADDEXP ;EMIT OP AND LABEL EXPRESSION .BYTE OP .EVEN .WORD <<.L'LAB>&ANDEXP>+ADDEXP ;USED BY FAIL MACRO .ENDM ; ; 190 EMITW$ ; .MACRO EMITW$,LAB ;OUTPUT LABEL .WORD .L'LAB .ENDM ; ; 200 ENTER$ ; .MACRO ENTER$,SECT,OFF,LAB ;PUT ENTRY IN BRANCH TABLE .PSECT SECT OFF=OFF+1 .WORD .L'LAB .PSECT ;TO RETURN TO UNNAMED PSECT .ENDM ; ; 210 DEFSY$ ; .MACRO DEFSY$,NAME,OP,OFFSET ;DEFINE NAME AS MACRO WHICH EXPANDS TO ;.BYTE OP + .BYTE OFFSET .MACRO NAME CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;EXIT IF IN BAD STATE .ENDC .BYTE OP .BYTE OFFSET .ENDM .ENDM ; ; 215 DEFAC$ ; .MACRO DEFAC$,NAME,OPNA,OPARG,OFFSET ;DEFINE NAME AS A MACRO WHICH ;CAN TAKE ARGUMENTS (POSSIBLY NULL ONES) .MACRO NAME,DUMARG ;DUMARG IS A LIST OF ARGS CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;EXIT IF IN BAD STATE .ENDC .N=0 .IRP .ARG, ;COUNT ARGUMENTS .N=.N+1 .ENDM .IF EQ,.N ;OUTPUT 'NO ARGS' OP CODE .BYTE OPNA .IFF .BYTE OPARG ;ELSE OUTPUT 'ARGS' OP CODE .IFTF .BYTE OFFSET ;EMIT OFFSET IN BOTH CASES .IFF .EVEN .WORD .N ;EMIT NUMBER OF ARGUMENTS .IRP .ARG, ;AND THE ARGUMENT LIST .WORD .ARG .ENDM .ENDC .ENDM .ENDM ; ; 220 CHARAC[TER] ; .MACRO CHARAC,C1,C2 ;MARGOT MACRO - SCAN SINGLE CHARACTER .NARG .N .IF GT,.N-2 .ERROR .N;TOO MANY ARGUMENTS; .MEXIT .ENDC CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC .IF EQ,.N .BYTE OP.CH0 ;SCAN ANY CHARACTER .ENDC .IF EQ,.N-1 .BYTE OP.CH1 ;SCAN A GIVEN CHARACTER .BYTE C1 .ENDC .IF EQ,.N-2 .BYTE OP.CH2 ;SCAN A RANGE OF CHARACTERS .BYTE C1 .BYTE C2 .ENDC .ENDM ; ; 230 STRING ; .MACRO STRING,STG ;MARGOT MACRO - SCAN GIVEN STRING .NARG .N .IF NE,.N-1 .ERROR .N;WRONG NUMBER OF ARGUMENTS - SHOULD BE ONE; .MEXIT .ENDC CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT .ENDC .NCHR .LEN, ;COMPUTE STRING LENGTH .IF GT,.LEN-255. .ERROR .LEN;STRING TOO LONG - MUST BE UNDER 256. CHARS; .MEXIT .ENDC .BYTE OP.STG .N=0 .IRPC .CHR, .IF GT,.N .IF LT,.N-.LEN+1 .BYTE ''.CHR .IFF .BYTE 0 ;TO CREATE AN .ASCIZ STRING .ENDC .ENDC .N=.N+1 .ENDM .ENDM ; ; 240 KEYWOR[D] ; .MACRO KEYWOR,MIN,STG ;MARGOT MACRO - SCAN KEYWORD .NARG .N .IF NE,.N-2 .ERROR .N;WRONG NUMBER OF ARGUMENTS - SHOULD BE TWO; .MEXIT .ENDC CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXY .ENDC .NCHR .LEN, ;COMPUTE STRING LENGTH .IF GT,MIN-255. .ERROR MIN;MINIMUM NO. OF CHARS MUST BE LESS THAN 256.; .MEXIT .ENDC .IF GT,.LEN-255. .ERROR .LEN;STRING LENGTH MUST BE LESS THAN 256. CHARS; .MEXIT .ENDC .IF GT,MIN-.LEN .ERROR MIN;MINIMUM GREATER THAN STRING LENGTH; .MEXIT .ENDC .BYTE OP.KEY .BYTE MIN .BYTE .LEN-MIN-1 .N=0 .IRPC .CHR, .IF GT,.N .IF LT,.N-.LEN+1 .BYTE ''.CHR .IFF .BYTE 0 ;TO CREATE AN .ASCIZ STRING .ENDC .ENDC .N=.N+1 .ENDM .ENDM ; ; 250 ALLOW ; .MACRO ALLOW ;MARGOT MACRO - SCAN ZERO OR MORE BLANKS CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC .BYTE OP.ALL .ENDM ; ; 260 REQUIR[E] ; .MACRO REQUIR ;MARGOT MACRO - SCAN ONE OR MORE BLANKS CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC .BYTE OP.REQ .ENDM ; ; 270 FAIL ; .MACRO FAIL ;MARGOT MACRO - FORCE FAILURE CKMOS$ .IF NE,ER.FLG .MEXIT .ENDC .IF EQ,ST.ATE-IN.SYN ;IN SYNTAX..ENDSYN? .BYTE OP.ESF .MEXIT .ENDC .IF EQ,ST.ATE-IN.OPT ;IN OPTION..ENDOPT? GTSUC$ .LB1 ;GET SUCCESS LABEL EMITX$ OP.FAO,\.LB1,177777,1 .MEXIT .ENDC .IF EQ,ST.ATE-IN.ALT ;IN ALTERN..ENDALT? .BYTE OP.EAF .MEXIT .ENDC .IRP ST.AT, ;THREE CASES HANDLED ALIKE .IF EQ,ST.ATE-ST.AT GTSUC$ .LB1 ;GET SUCCESS LABEL EMITX$ OP.FAR,\.LB1,177776,4 .MEXIT .ENDC .ENDM .ENDM ; ; 280 ACTION ; .MACRO ACTION,NAME ;MARGOT MACRO - DEFINE ACTION .NARG .N ARGCK$ NAME,.N .IF NE,ER.FLG .MEXIT ;QUIT IF BAD ARGUMENTS .ENDC CKNON$ ;CHECK FOR UNTERMINATED STRUCTURES PSHST$ IN.ACT ;PUSH STATE DEFAC$ NAME,OP.CLA,OP.CAA,\A.BTOF ;DEFINE THE NAME AS A MACRO ENTER$ $ACTBT,A.BTOF,\L.ABEL ;ADD ENTRY TO ACTION BRANCH TABLE .EVEN ATGEN$ ;ATTACH GENERATED LABEL ; NO CODE IS NEEDED AS PROLOGUE TO AN ACTION. SHOULD IT BE NEEDED AT SOME ; TIME, IT WOULD BE ADDED HERE. ; .ENDM ; ; 290 ENDACT[ION] ; .MACRO ENDACT ;MARGOT MACRO - END ACTION CKSTA$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC POPST$ ;POP STATE RTS PC ;RETURN FROM ACTION .ENDM ; ; 300 SYNTAX ; .MACRO SYNTAX,NAME ;MARGOT MACRO - DEFINE SYNTAX .NARG .N ARGCK$ NAME,.N ;CHECK ARGUMENT NUMBER AND TYPE .IF NE,ER.FLG .MEXIT ;QUIT IF BAD ARGUMENT .ENDC CKNON$ ;CHECK FOR UNTERMINATED STRUCTURES PSHST$ IN.SYN ;PUSH STATE DEFSY$ NAME,OP.CLS,\S.BTOF ;DEFINE NAME AS MACRO ENTER$ $SYNBT,S.BTOF,\L.ABEL ;ADD ENTRY TO SYNTAX BRANCH TABLE ATGEN$ ;ATTACH GENERATED LABEL GNSUC$ .LB1 ;GENERATE AND STACK SUCCESS LABEL GNFAI$ .LB2 ;GENERATE AND STACK FAILURE LABEL EMITL$ OP.SYN,\.LB2 ;EMIT SYNTAX OP AND FAIL LOCATION .ENDM ; ; 310 ENDSYN[TAX] ; .MACRO ENDSYN ;MARGOT MACRO - END SYNTAX DEFINITION CKSTA$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC ATSUC$ ;ATTACH SUCCESS LABEL .BYTE OP.ESS ;ENDSYN SUCCESS OP ATFAI$ ;ATTACH FAIL LABEL .BYTE OP.ESF ;ENDSYN FAIL OP POPST$ ;POP STATE .ENDM ; ; 320 OR ; .MACRO OR ;MARGOT MACRO - OR CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC GTSUC$ .LB1 ;GET SUCCESS LABEL EMITL$ OP.ORS,\.LB1 ;EMIT OR SUCCESS AND SUCCESS LABEL ATFAI$ ;ATTACH FAIL LABEL GNFAI$ .LB2 ;GENERATE NEW FAIL LABEL EMITL$ OP.ORF,\.LB2 ;EMIT OR FAIL AND FAIL LABEL .ENDM ; ; 330 OPTION[AL] ; .MACRO OPTION ;MARGOT MACRO - OPTIONAL CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC PSHST$ IN.OPT ;PUSH NEW STATE GNSUC$ .LB1 ;GENERATE SUCCESS LABEL GNFAI$ .LB2 ;GENERATE FAIL LABEL EMITL$ OP.OPT,\.LB2 ;EMIT OPTION OP AND FAIL LOCATION .ENDM ; ; 340 ENDOPT[IONAL] ; .MACRO ENDOPT ;MARGOT MACRO - END OPTIONAL CKSTA$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC ATSUC$ ;ATTACH SUCCESS LABEL .BYTE OP.EOS ;ENDOPT SUCCESS OP ATFAI$ ;ATTACH FAIL LABEL .BYTE OP.EOF ;ENDOPT FAIL OP POPST$ ;POP STATE .ENDM ; ; 350 REP0$ ; .MACRO REP0$ ;INDEFINITE REPETITION PSHST$ IN.REP ;PUSH STATE GNSUC$ .LB1 ;GENERATE SUCCESS LABEL GNFAI$ .LB2 ;GENERATE FAIL LABEL GNLUP$ .LB4 ;GENERATE LOOP LABEL EMITL$ OP.RP0,\.LB2 ;EMIT REPEAT OP AND FAIL LOCATION ATLUP$ ;ATTACH LOOP LABEL .ENDM ; ; 355 REP2$ ; .MACRO REP2$,N1,N2 ;REPEAT N1 TO N2 TIMES .IF B,N1 ;LOW BOUND NULL => LOW BOUND ZERO .LOW=0 .IFF .IF LT,N1 ;NEGATIVE LOW BOUND DEFAULTS TO ZERO .ERROR N1;NEGATIVE LOW BOUND DEFAULTS TO ZERO; .LOW=0 .IFF .LOW=N1 .ENDC .ENDC .IF B,N2 ;NIGH BOUND NULL => INFINITY .HIGH=255. .IFF .IF GE,N2-256. .ERROR N2;HIGH BOUND > 255. DEFAULTS TO 255.; .HIGH=255. .IFF .HIGH=N2 .ENDC .ENDC .IF LT,.HIGH-.LOW .ERROR ;LOW BOUND EXCEEDS HIGH BOUND; .MEXIT .ENDC PSHST$ IN.REP ;ARGS OK, SO PUSH STATE GNSUC$ .LB1 ;GENERATE SUCCESS LABEL GNFAI$ .LB2 ;GENERATE FAIL LABEL GNLUP$ .LB4 ;GENERATE LOOP LABEL .BYTE OP.RP2 ;EMIT REPEAT OP .BYTE .LOW .BYTE .HIGH .EVEN EMITW$ \.LB2 ;AND FAIL LABEL ATLUP$ ;ATTACH LOOP LABEL .ENDM ; ; 360 REPEAT ; .MACRO REPEAT,N1,N2 ;MARGOT MACRO - REPEAT CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC .NARG .N .IF EQ,.N REP0$ ;REPEAT INDEFINITELY .IFF .IF LE,.N-2 ;ELSE IF .N IS 1 OR 2 REP2$ N1,N2 ;REPEAT WITH BOUNDS .IFF .ERROR .N;TOO MANY ARGS - MAX IS TWO; .ENDC .ENDC .ENDM ; ; 370 ENDREP[EAT] ; .MACRO ENDREP ;MARGOT MACRO - END REPEAT CKSTA$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD CONTEXT .ENDC ATSUC$ ;ATTACH SUCCESS LABEL GTLUP$ .LB4 ;GET LOOP LABEL EMITL$ OP.ERS,\.LB4 ;EMIT ENDREP SUCCESS AND LOOP LABEL ATFAI$ ;ATTACH FAIL LABEL .BYTE OP.ERF ;OUTPUT ENDREP FAIL OP POPST$ .ENDM ; ; 380 ALTERN[ATIVE] ; .MACRO ALTERN ;MARGOT MACRO - ALTERNATIVE CKMOS$ ;CHECK STATE .IF NE,ER.FLG .MEXIT ;QUIT IF IN BAD STATE .ENDC PSHST$ IN.ALT ;PUSH STATE GNSUC$ .LB1 ;GENERATE SUCCESS LABEL GNFAI$ .LB2 ;GENERATE FAIL LABEL EMITL$ OP.ALT,\.LB2 ;EMIT ALTERNATIVE OP AND FAIL LOCATION .ENDM ; ; 390 ENDALT[ERNATIVES] ; .MACRO ENDALT ;MARGOT MACRO - END ALTERNATIVES CKSTA$ .IF NE,ER.FLG .MEXIT .ENDC ATSUC$ ;ATTACH SUCCESS LABEL .BYTE OP.EAS ;ENDALT SUCCESS OP ATFAI$ ;ATTACH FAIL LABEL .BYTE OP.EAF ;ENDALT FAIL OP POPST$ .ENDM ; ; 400 LIS0$ ; .MACRO LIS0$ ;LIST WITH ZEO OR MORE ITEMS PSHST$ IN.LIS ;PUSH STATE GNSUC$ .LB1 ;GENERATE SUCCESS LABEL GNFAI$ .LB2 ;GENERATE FAIL LABEL GNBEG$ .LB3 ;GENERATE BEGIN LABEL GNLUP$ .LB4 ;GENERATE LOOP LABEL EMITL$ OP.LS0,\.LB3 ;EMIT LIST OP AND BEGIN LOCATION EMITW$ \.LB2 ;AND FAIL LOCATION ATLUP$ ;ATTACH LOOP LABEL PSHST$ IN.ALT ;NOW PRETEND WE'RE DOING 'ALTERN' GNSUC$ .LB1 GNFAI$ .LB2 EMITL$ OP.ALT,\.LB2 ;EMIT OP.ALT AND FAIL LABEL .ENDM ; ; 405 LIS2$ ; .MACRO LIS2$,N1,N2 ;LIST OF N1 TO N2 ITEMS .IF B,N1 ;LOW BOUND NULL => LOW BOUND ZERO .LOW=0 .IFF .IF LT,N1 .ERROR N1;NEGATIVE LOW BOUND DEFAULTS TO ZERO; .LOW=0 .IFF .LOW=N1 .ENDC .ENDC .IF B,N2 .HIGH=255. .IFF .IF GE,N2-256. .ERROR N2;HIGH BOUND > 255.DEFAULTS TO 255.; .HIGH=255. .IFF .HIGH=N2 .ENDC .ENDC .IF LT,.HIGH-.LOW .ERROR ;LOW BOUND EQUALS OR EXCEEDS HIGH BOUND; .ENDC PSHST$ IN.LIS ;PUSH STATE GNSUC$ .LB1 ;GENERATE SUCCESS LABEL GNFAI$ .LB2 ;GENERATE FAIL LABEL GNBEG$ .LB3 ;GENERATE BEGIN LABEL GNLUP$ .LB4 ;GENERATE LOOP LABEL .BYTE OP.LS2 ;EMIT LIST OP .BYTE .LOW .BYTE .HIGH .EVEN EMITW$ \.LB3 ;BEGIN LOCATION EMITW$ \.LB2 ;FAIL LOCATION ATLUP$ ;ATTACH LOOP LABEL PSHST$ IN.ALT ;NOW PRETEND WE'RE IN 'ALTERN' GNSUC$ .LB1 GNFAI$ .LB2 EMITL$ OP.ALT,\.LB2 .ENDM ; ;410 LIST ; .MACRO LIST,N1,N2 ;MARGOT MACRO - LIST SEPARATORS CKMOS$ .IF NE,ER.FLG .MEXIT .ENDC .NARG .N .IF EQ,.N LIS0$ ;LIST WITH INDEFINITE NUMBER OF ITEMS .IFF .IF LE,.N-2 LIS2$ N1,N2 ;LIST WITH N1 TO N2 ITEMS .IFF .ERROR .N;TOO MANY ARGS - MAX IS TWO; .ENDC .ENDC .ENDM ; ; 420 OF ; .MACRO OF ;MARGOT MACRO - BEGIN LIST ITEMS CKSTA$ ;CHECK STATE .IF NE,ER.FLG .MEXIT .ENDC ATSUC$ ;ATTACH 'ALTERN' SUCCESS LABEL .BYTE OP.EAS ;ENDALT SUCCESS ATFAI$ .BYTE OP.EAF ;ENDALT FAIL POPST$ ;POP 'ALTERN' STATE SO WE CAN PICK ;UP THE BEGIN LABEL CKSTA$ ;INSURE WE ARE IN LIST STRUCTURE .IF NE,ER.FLG .MEXIT .ENDC ATBEG$ ;ATTACH LIST BEGIN LABEL PSHST$ IN.ALT ;GO BACK TO 'ALTERN' STATE GNSUC$ .LB1 GNFAI$ .LB2 EMITL$ OP.ALT,\.LB2 ;EMIT OP.ALT AND FAIL LABEL .ENDM ; ; 430 ENDLIS[T] ; .MACRO ENDLIS ;MARGOT MACRO - END LIST CKSTA$ ;CHECK STATE .IF NE,ER.FLG .MEXIT .ENDC ATSUC$ ;ATTACH SUCCESS LABEL .BYTE OP.EAS ;ENDALT SUCCESS ATFAI$ .BYTE OP.EAF ;ENDALT FAIL POPST$ ;LEAVE 'ALTERN' STATE CKSTA$ .IF NE,ER.FLG .MEXIT .ENDC ATSUC$ ;LOOP SUCCESS LABEL GTLUP$ .LB4 ;GET LOOP LABEL EMITL$ OP.ERS,\.LB4 ;EMIT ENDREP SUCCESS OP AND LOOP LABEL ATFAI$ ;ATTACH FAIL LABEL .BYTE OP.ERF ;EMIT ENDREP FAIL OP POPST$ .ENDM .ENDM