.MCALL .MODULE .MODULE TPARS,VERSION=03,COMMENT=,IDENT=NO,GLOBAL=.TPAR ; Copyright (c) 1998 by Mentec, Inc., Nashua, NH. ; All rights reserved ; ; This software is furnished under a license for use only on a ; single computer system and may be copied only with the ; inclusion of the above copyright notice. This software, or ; any other copies thereof, may not be provided or otherwise ; made available to any other person except for use on such ; system and to one who agrees to these license terms. Title ; to and ownership of the software shall at all times remain ; in Mentec, Inc. ; ; The information in this document is subject to change without ; notice and should not be construed as a commitment by Digital ; Equipment Corporation, or Mentec, Inc. ; ; Digital and Mentec assume no responsibility for the use or ; reliability of its software on equipment which is not supplied ; by Digital or Mentec, and listed in the Software Product ; Description. .SBTTL Post Release Edit History ;+ ; ; (02/01) 23-Sep-93 Don Bridgewater ; Corrected byte comparison ; 03 13-Jan-1998 TDS Bump version for 5.7 release ; ;- .SBTTL TITLE PAGE ;- ; ; ANDREW C. GOLDSTEIN 8 OCT 76 13:46 ; ; R$$EIS = 0 ; USE EIS .ENABL GBL .SBTTL MACRO DEFINITIONS ; .MCALL CALL,RETURN ; ; INTERNAL MACROS ; .MACRO PUSH LIST .IRP RX, MOV RX,-(SP) .ENDM .ENDM PUSH .MACRO POP LIST .IRP RX, MOV (SP)+,RX .ENDM .ENDM POP ; ; MACRO TO DO SOB'S ON SMALL MACHINES ; .IF NDF R$$EIS .MACRO SOB RX,LABEL DEC RX BNE LABEL .ENDM SOB .ENDC ; ; RANDOM CHARACTERS ; TAB= 11 CR= 15 AM= 33 SPA= 40 .SBTTL IMPURE DATA .PSECT IMPURE,D ; ; ***** DO NOT CHANGE THE ORDER OF THE FOLLOWING VARIABLES! ; ; ITEMS OF INTEREST TO ACTION ROUTINES AND THE OUTSIDE WORLD ; IN GENERAL. ; .PFLAG::.BLKW 1 ; SAVED FLAG WORD .PSTCN::.BLKW 1 ; CHARACTER COUNT OF FOUND STRING .PSTPT::.BLKW 1 ; POINTER TO FOUND STRING .PCHAR::.BLKW 1 ; FOUND CHARACTER .PNUMH::.BLKW 1 ; HIGH ORDER VALUE AND .... .PNUMB::.BLKW 1 ; LOW ORDER VALUE OF FOUND NUMBER ; ; ***** DO NOT CHANGE THE ORDER OF THE PRECEDING VARIABLES! ; .PSECT .SBTTL MAIN ROUTINE BODY ;+ ; ; *** - .TPARS ; ; ENTRY: CALL .TPARS ; ; INPUTS: ; ; R1 = CONTROL WORD ; LOW BYTE: ; = 0 IGNORE ALL SPACES BETWEEN SYNTACTIC ELEMENTS ; >< 0 TREAT SPACES AS SIGNIFICANT CHARACTERS ; HIGH BYTE: ; = 0 REQUIRE EXACT MATCH ON KEYWORDS ; = N REQUIRE AT LEAST N CHARACTERS FOR KEYWORD MATCH ; R2 = POINTER TO KEYWORD TABLE ; R3 = LENGTH OF COMMAND STRING ; R4 = ADDRESS OF COMMAND STRING ; R5 = INITIAL STATE POINTER ; ; OUTPUTS: ; ; C = 0 SUCCESSFUL PARSE ; C = 1 SYNTAX OR STATE TABLE ERROR ; R3 = NUMBER OF CHARACTERS NOT SCANNED ; R4 = POINTER TO UNSCANNED PART OF COMMAND STRING ; ; ALL OTHER REGISTERS ARE PRESERVED. ; ; .TPARS PARSES THE COMMAND STRING ACCORDING TO THE FINITE ; STATE MACHINE REPRESENTED IN THE STATE AND KEYWORD TABLES ; SUPPLIED BY THE CALLER. USER SUPPLIED ACTION ROUTINES ARE ; CALLED AS SPECIFIED. ; ;- .ENABL LSB .TPARS:: PUSH ; SAVE REGISTERS MOV R1,.PFLAG ; SAVE FLAG WORD ; ; ENTER THE STATE SPECIFIED IN R5 AND ; EVALUATE POSSIBLE STATE TRANSITIONS ; TSTAT: TSTB .PFLAG ; CHECK SPACE FLUSH FLAG BNE 10$ CALL GETSP ; EAT SPACES IF FLAG IS ZERO 10$: CLR .PSTCN ; KILL ANY OLD STRING MOV R4,.PSTPT ; INIT STRING POINTER MOVB (R5)+,R0 ; GET TYPE BYTE BPL TSCHAR ; BIT 7 = 0 - MATCH SPECIFIED CHAR SUB #177700,R0 ; TEST AGAINST 300 BLT DOKEY ; 200 - 277 - MATCH KEYWORD CMP R0,#MAXTYP ; CHECK TYPE CODE FOR LEGALITY BGT SYNERR ; TOO HIGH - OUT MOV R0,R1 ; GARBAGE R1 FOR USE AS A FLAG ADD R0,PC ; AND DISPATCH ON IT BR DOLAMB ; $LAMDA = 300 - MATCH EMPTY BR DONUMB ; $NUMBR = 302 - MATCH NUMBER BR DOSTRG ; $STRNG = 304 - MATCH ANY STRING BR DOBLNK ; $BLANK = 306 - MATCH ANY SET OF BLANKS BR DOSUBR ; $SUBXP = 310 - MATCH A SUBEXPRESSION BR DOENDS ; $EOS = 312 - MATCH END OF STRING BR DODNMB ; $DNUMB = 314 - MATCH DECIMAL NUMBER BR DORD50 ; $RAD50 = 316 - MATCH RAD-50 STRING BR DOCHAR ; $ANY = 320 - MATCH ANY CHARACTER BR DOALPH ; $ALPHA = 322 - MATCH SINGLE ALPHABETIC BR DODIGT ; $DIGIT = 324 - MATCH SINGLE DIGIT ; ; NOTE - IT IS CRITICAL THAT R0 AND R1 BE NON-ZERO AND POSITIVE AT THE DISPATCH ; MAXTYP = 24 ; ; CHECK FOR END OF STRING ; DOENDS: TST R3 ; CHECK CHAR COUNT BEQ DOTRAN ; YES ; ; TYPE MATCH FAILED - TRY NEXT ENTRY IN TRANSITION TABLE ; NXTRAN: ADD .PSTCN,R3 ; RETURN ANY STRING SUB .PSTCN,R4 ; TO THE COMMAND LINE MOVB (R5)+,R0 ; GET FLAGS BYTE BLT SYNERR ; THIS WAS LAST TRANSITION - YOU LOSE MOV #5,R1 ; COUNT OF FLAG BITS TO TEST 20$: ROR R0 ; CHECK FLAG BIT BCC 30$ TST (R5)+ ; SKIP POINTER WORD 30$: SOB R1,20$ ; COUNT BITS BR TSTAT ; TRY NEXT TRANSITION ; ; OUT OF TRANSITION TABLE ENTRIES, OR SOME OTHER ANOMALY, ; LIKE A BAD TYPE CODE. ALL ARE SYNTAX ERRORS. ; SYNERR: SEC ; SAY SO BR EXIT ; AND QUIT ; ; TEST FOR SINGLE ALPHABETIC ; DOALPH: CALL GETALP ; PICK UP CHAR IF PRESENT BR 40$ ; ; TEST FOR SINGLE DIGIT ; DODIGT: CALL GETDIG ; PICK UP DIGIT IF PRESENT 40$: BCC DOCHAR ; ACCEPT THE CHAR BR NXTRAN ; NO - TRY ANOTHER ; ; TEST FOR SPECIFIED CHARACTER ; TSCHAR: CMPB R0,(R4) ; CHECK CHAR IN COMMAND STRING BNE NXTRAN ; IF NO MATCH, TRY ANOTHER TRANSITION ; ; GOBBLE A CHARACTER AND DO THE TRANSITION ; DOCHAR: TST R3 ; CHECK FOR END OF STRING BLE NXTRAN ; IF YES, DON'T TRY THIS MOV #1,.PSTCN ; STRING COUNT = 1 MOVB (R4)+,.PCHAR ; SAVE CHAR FOR ACTION ROUTINE DEC R3 ; COUNT IT ; ; DO THE STATE TRANSITION ; DOLAMB: DOTRAN: PUSH R5 ; SAVE STATE TABLE ADDRESS MOVB (R5)+,R0 ; GET FLAGS BYTE ROR R0 ; CHECK EXTENSION BIT BCC 50$ TST (R5)+ ; SKIP EXTENSION WORD 50$: ROR R0 ; CHECK ACTION BIT BCC 70$ PUSH R0 ; SAVE R0 FOR USER CALL @(R5)+ ; CALL ACTION ROUTINE BR 60$ ; NORMAL RETURN FROM ACTION ROUTINE ; ACTION ROUTINE RETURNS AT CALL+4 POP ; TO REJECT THE TRANSITION BR NXTRAN ; TRY NEXT TRANSITION IN STATE 60$: POP R0 ; RESTORE R0 70$: TST (SP)+ ; CLEAN THE STACK BIT #2,R0 ; CHECK FOR BITMASK BEQ 80$ ; BRANCH IF NONE BIS (R5)+,@(R5)+ ; SET MASK IN DESIGNATED WORD 80$: ROR R0 ; CHECK EXPLICIT TRANSITION BIT BCC TSTAT MOV (R5)+,R5 ; POINT TO NEXT STATE 90$: BNE TSTAT ; PROCESS NEXT STATE CCC ; STATE NUMBER OF ZERO MEANS STOP EXIT: POP ; RESTORE ALL THE REGISTERS MOV .PFLAG,R1 ; RESTORE FLAG WORD RETURN .DSABL LSB .SBTTL COMPLEX TYPE ROUTINES .ENABL LSB ; ; MATCH ANY NUMBER ; DODNMB: CLR R1 ; SET DECIMAL MODE DONUMB: NEG R0 ; SET UP FOR NUMERIC STRING BR NUMCOM ; REST OF ROUTINE BELOW BECAUSE ; OF BRANCH RANGE PROBLEMS ; ; SUB EXPRESSION TYPE - CALL ONESELF RECURSIVELY ; DOSUBR: MOV .PFLAG,R1 ; SET SPACE FLUSH FLAG MOV (SP),R2 ; SET KEYWORD TABLE POINTER PUSH ; SAVE STRING POINTERS FOR UNWIND MOV R5,R0 ; SAVE STATE TABLE POINTER MOV 1(R5),R5 ; GET STARTING STATE CALL .TPARS ; AND TRY TO PARSE SUBEXPRESSION ROL R1 ; SAVE THE C BIT MOV R0,R5 ; RESTORE STATE POINTER MOV (SP)+,.PSTPT ; OLD R4 = START OF STRING SUB R3,(SP) ; OLD R3 - NEW R3 = LENGTH MOV (SP)+,.PSTCN ; SAVE IT ROR R1 ; RESTORE C BIT 10$: BCC DOTRAN ; TAKE THE TRANSITION IF SUCCESSFUL BR NXTRAN ; ELSE TRY SOMETHING ELSE ; ; MATCH ANY ALPHANUMERIC STRING ; DORD50: CLR R0 ; SET RAD-50 FLAG DOSTRG: CALL GETSTR ; JUST DRAG IN THE STRING BR 20$ ; ; MATCH ANY NON-EMPTY STRING OF SPACES OF TABS ; DOBLNK: CALL GETSP ; LOOK FOR SPACES TST R2 ; CHECK NUMBER FOUND 20$: BEQ NXTRAN ; NOTHING - TRY SOMETHING ELSE BR DOTRAN ; YES - DO IT ; ; MATCH SPECIFIED KEYWORD ; DOKEY: BIC #^C377,R0 ; SET FOR ALPHA-NUMERIC CALL GETSTR ; GET ALPHA-NUMERIC STRING BEQ NXTRAN ; DON'T TRY TO MATCH NULL STRING BIC #^C77,R0 ; GET KEYWORD INDEX ASL R0 ; CONVERT TO OFFSET ADD (SP),R0 ; INDEX INTO KEYWORD TABLE MOV (R0),R0 ; FOLLOW THE STRING POINTER MOV .PSTCN,R1 ; GET STRING DESCRIPTOR MOV .PSTPT,R2 30$: CMPB (R0)+,(R2)+ ; COMPARE TO KEYWORD BNE NXTRAN ; OUT ON MISMATCH SOB R1,30$ ; COUNT CHARS AND LOOP CMPB (R0),#377 ; CHECK FOR KEYWORD TERMINATOR BEQ DOTRAN ; EXACT MATCH - OK TSTB .PFLAG+1 ; SEE IF SUBSTRINGS ALLOWED BEQ NXTRAN ; BRANCH IF NO CMPB .PSTCN,.PFLAG+1 ; CHECK BYTE COUNT AGAINST MINIMUM BHIS DOTRAN ; GREATER OR EQUAL - OK BR NXTRAN ; LESS - NO ; ; REST OF NUMBER PROCESSING ROUTINE ; NUMCOM: CALL GETSTR ; GET A STRING BEQ NXTRAN ; COME ON, AT LEAST ONE DIGIT TST R1 ; CHECK MODE BEQ 40$ ; DECIMAL - DON'T LOOK FOR TRAILING DOT TST R3 ; SEE IF WE'RE AT END OF STRING BLE 40$ ; YES CMPB (R4),#'. ; CHECK FOR TRAILING DECIMAL BNE 40$ ; NO INC R4 ; YES - INCLUDE IN NUMBER STRING DEC R3 INC .PSTCN ; BUMP STRING COUNT 40$: PUSH ; SAVE REGISTERS MOV .PSTPT,R5 ; GET STRING POINTER MOV .PSTCN,R4 ; AND STRING COUNT MOV #.PNUMH,R3 ; POINT TO DOUBLE WORD FOR NUMBER TST R1 ; CHECK IF OCTAL OR DECIMAL BNE 50$ ; OCTAL CALL .DD2CT ; DECIMAL BR 60$ 50$: CALL .OD2CT ; DO OCTAL/DECIMAL CONVERT 60$: POP ; RESTORE REGISTERS BR 10$ .DSABL LSB .SBTTL GET STRING ROUTINE ; ; THIS ROUTINE POINTS THE STRING DESCRIPTOR AT THE ALPHA-NUMERIC ; STRING AT THE CURRENT POSITION IN THE COMMAND LINE. ; ; INPUTS: R0 = MODE FLAG ; - IS NUMERIC ONLY ; + IS ALPHANUMERIC ; 0 IS RAD-50 SET ; .PSTCN = 0 ; .PSTPT = START OF STRING = R4 ; GETSTR: TST R3 ; CHECK FOR END OF STRING BLE 30$ ; IF YES, DON'T TRY THIS 10$: CALL GETDIG ; TRY A DIGIT BCC 20$ ; OK TST R0 ; CHECK MODE BLT 30$ ; BRANCH IF NUMERIC ONLY CALL GETALP ; CHECK FOR AN ALPHABETIC BCC 20$ ; OK TST R0 ; SEE IF RAD-50 MODE BNE 30$ ; NO CMPB (R4),#'. ; CHECK FOR "." BEQ 20$ CMPB (R4),#'$ ; CHECK FOR "$" BNE 30$ 20$: INC .PSTCN ; GOOD CHAR - BUMP COUNT INC R4 ; GOBBLE THE CHAR SOB R3,10$ ; COUNT IT AND LOOP 30$: TST .PSTCN ; IF NONE FOUND, RETURN WITH Z SET RETURN ; END OF LINE OR NON-ALPHA NUMERIC ; ; THIS ROUTINE CHECKS FOR A SINGLE ALPHABETIC. ; RETURNS WITH C SET IF NOT. ; GETALP: CMPB #'Z,(R4) ; CHECK IF LESS THAN "Z" BLO 40$ ; NO - CARRY IS SET CMPB (R4),#'A ; CHECK AGAINST "A" (SETS CARRY RIGHT!) 40$: RETURN ; (DO NOT MESS WITH THE ABOVE COMPARES.) ; ; THIS ROUTINE TESTS FOR A SINGLE DIGIT. ; RETURNS WITH C SET IF NOT. ; GETDIG: CMPB #'9,(R4) ; CHECK IF LESS THAN '9" BLO 50$ ; NO - CARRY IS SET CMPB (R4),#'0 ; TEST AGAINST "0" - SETS CARRY RIGHT 50$: RETURN ; (SAME WARNING ABOUT THESE TESTS.) ; ; THIS ROUTINE FINDS AND PASSES OVER BLANKS AND TABS AT THE CURRENT ; POSITION IN THE COMMAND LINE. ; GETSP: CLR R2 ; ZERO CHAR COUNT TST R3 ; CHECK FOR END OF STRING BLE 80$ ; IF YES, DON'T TRY THIS 60$: CMPB (R4),#SPA ; TEST FOR SPACE IN COMMAND LINE BEQ 70$ CMPB (R4),#TAB ; TEST FOR TAB BNE 80$ 70$: INC R2 ; BLANK OR TAB FOUND - BUMP COUNT INC R4 ; BUMP STRING POINTER SOB R3,60$ ; COUNT CHARS AND LOOP 80$: RETURN .SBTTL NUMERIC CONVERSION ROUTINE ; ; THIS ROUTINE CONVERTS AN ASCII STRING POINTED TO BY R5 WITH LENGTH ; IN R4 TO A DOUBLE PRECISION INTEGER POINTED TO BY R3. ; .DD2CT: CLR R0 ; INITIALIZE RESULT 10$: DEC R4 BLT 20$ ; IF NEG, DONE MOVB (R5)+, R1 ; R1 = NEXT BYTE SUB #'0, R1 MOV R0, R2 ; MUL #10., R0 ASL R0 ASL R0 ADD R2, R0 ASL R0 ADD R1, R0 ; ADD IN THIS DIGIT BR 10$ 20$: CLR (R3)+ MOV R0, (R3) RETURN .OD2CT: RETURN ; SLP doesn't use octal numbers .END