home *** CD-ROM | disk | FTP | other *** search
- BMLP.P
-
- '-----------------------------------------------------------------------------
- '- (C) Bendorf Associates, 1984-85 -
- '-----------------------------------------------------------------------------
- '- Program:BMLP (BASIC MACRO LANGUAGE PREPROCESSOR)
- '- System :PPE
- '- Module :TOOLS
- '- Task :EXPAND MACROS USING LOCAL OR LIBRARY DEFINITIONS.
- '- Created:10.1.82
- '- By :D. L. BENDORF
- '- Version:PUBLIC DOMAIN
- '- Notes :THIS PROGRAM IS NOT FOR RESALE.
- '- History:
- '-----------------------------------------------------------------------------
- '- ** Data Division -
- '-----------------------------------------------------------------------------
- SIGN$ = "$"
- DOT$ = "."
- OEXT$ = ".P" ' Output file default extension
- IEXT$ = ".M" ' Input file default extension
- LEXT$ = ".ML" ' Library file default extension
- SOURCE% = 2 ' Input file number
- O.FILE% = 1 ' Output file number
- I.FILE% = 2
- ERRORS% = 0
- FALSE% = 0
- TRUE% = NOT FALSE%
- EXPAND% = TRUE%
- STORE.% = 0
- NEST% = 1
- DIM FILE.%(50) ' TEMPORARY STACK OF POINTERS TO THE NEXT SUBSCRIPT
- ' OF STORE$ ARRAY. ALLOWS NESTED MACROS AND LIBRARIES.
- DIM PARM$(500) ' TEMPORARY STORAGE OF PARAMETERS TO PASS TO MACROS.
- DIM PARM%(100) ' ARRAY OF POINTERS TO PARAMETER STORAGE.
-
- DIM MACRO$(100) ' STORAGE FOR MACRO NAMES.
- DIM MACRO%(100) ' ARRAY OF POINTERS TO FIRST CODE LOCATION IN STORE$ ARRAY
- ' FOR EACH MACRO NAME IN THE MACRO$ ARRAY.
- DIM STORE$(1000) ' STORAGE FOR MACRO TEXT.
- DIM SUBS$(50) ' STORAGE FOR MACRO SUBROUTINE NAMES.
- '
- '------------------------------------------------------
- '- ** Procedure Division -
- '------------------------------------------------------
- '
- prog BMLP
- PRINT "BMLP V1.0B (C) BENDORF ASSOCIATES, 1984-85"
- PRINT
- GoSub FILENAMES
- when I.FILE%>0
- GoSub PROCESS-SOURCE-FILE
- CLOSE
- when ERRORS%>0
- KILL O.FILE$
- PRINT O.FILE$;" ABORTED WITH ";STR$(ERRORS%);" ERROR(S)."
- else
- PRINT"<";O.FILE$;"> DONE!"
- endw
- else when I.FILE$<>""
- PRINT"CANNOT OPEN ";I.FILE$
- endw
- pend
- proc PROCESS-SOURCE-FILE
- OPEN"O",O.FILE%,O.FILE$
- OPEN"I",I.FILE%,I.FILE$
- FILE.%(NEST%)=-1
- loop unless NEST%=0
- while ENDOFF%=FALSE%
- GoSub INPUT-BUFFER
- when LN.%>1 AND ENDOFF%=FALSE%
- GoSub INSERT-PARAMETERS
- GoSub PARSE-INPUT-LINE
- else when SKIP% AND I.FILE%=SOURCE%
- PRINT #O.FILE%,BUF$
- endw
- wend
- IF(NEST%=1)THEN FIRST%=0 ELSE FIRST%=PARM%(NEST%-1)
- LAST%=PARM%(NEST%)
- PARM%(NEST%)=0
- while (FIRST%<LAST%)
- PARM$(LAST%)=""
- LAST%=LAST%-1
- wend
- when FILE.%(NEST%)<0 AND NEST%>1 AND I.FILE%>SOURCE%
- CLOSE #I.FILE%
- I.FILE%=I.FILE%-1
- else
- POINTER%=FILE.%(NEST%-1)
- endw
- NEST%=NEST%-1
- ENDOFF%=FALSE%
- unless NEST%>0 OR SUBS%=LAST.S%
- LAST.S%=LAST.S%+1
- TEXT$=SUBS$(LAST.S%)
- GoSub FIND-MACRO-NAME
- when FOUND%
- FILE.%(NEST%+1)=FIND%:POINTER%=FIND%
- NEST%=NEST%+1
- else
- EBUF$="SUBROUTINE ("+TEXT$+") NOT FOUND!"
- GoSub ERRORS
- endw
- endu
- endl unless NEST%>0
- endp
- '
- '------------------------------------------------------
- '- ** SubRoutine Division -
- '------------------------------------------------------
- '
- proc PARSE-INPUT-LINE
- GoSub PARSER
- GoSub LCASE
- when LEFT$(TEXT$,1)=SIGN$
- TEXT$=RIGHT$(TEXT$,LEN(TEXT$)-1)
- when TEXT$="if"
- GoSub SET-CONDITIONAL
- else when TEXT$="else"
- EXPAND%=(EXPAND%=FALSE%)
- else when TEXT$="end"
- EXPAND%=TRUE%
- else when LEFT$(TEXT$,1)=SIGN$
- TEXT$=RIGHT$(TEXT$,LEN(TEXT$)-1)
- GoSub SUBROUTINE
- else when EXPAND%
- GoSub EXPAND-MACRO
- endw
- else when TEXT$="macro"
- GoSub INPUT-A-MACRO
- else when TEXT$="library"
- GoSub LIBRARY
- else when EXPAND% AND I.FILE%=SOURCE%
- PRINT #O.FILE%,BUF$
- endw
- endp
- proc INSERT-PARAMETERS
- LB%=INSTR(1,BUF$,"[")
- while (LB%>0)
- RB%=INSTR(LB%,BUF$,"]")
- when RB%>0
- INSERT$=PARM$(PARM%(NEST%-1)+VAL(MID$(BUF$,LB%+1,RB%-LB%)))
- BUF$=LEFT$(BUF$,LB%-1)+INSERT$+RIGHT$(BUF$,LEN(BUF$)-RB%)
- LB%=INSTR(RB%,BUF$,"[")
- else
- LB%=0
- endw
- wend
- LN.%=LEN(BUF$)
- endp
- proc SET-CONDITIONAL
- GoSub PARSER
- L$=TEXT$:OP$=""
- IF(L$="=" OR L$="#" OR L$="<>")THEN OP$=L$:L$=""
- GoSub PARSER
- when TEXT$=""
- OP$="<>":R$=""
- else when OP$=""
- OP$=TEXT$
- GoSub PARSER
- R$=TEXT$
- endw
- when OP$="="
- EXPAND%=(R$=L$)
- else when OP$="<>" OR OP$="#"
- EXPAND%=(R$<>L$)
- else
- EBUF$="ILLEGAL OPERATOR("+OP$+")"
- GoSub ERRORS
- endw
- endp
- proc EXPAND-MACRO
- GoSub FIND-MACRO-NAME
- when FOUND%
- IF(FILE.%(NEST%)=>0)THEN FILE.%(NEST%)=POINTER%
- POINTER%=FIND%
- NEST%=NEST%+1
- FILE.%(NEST%)=FIND%
- PARM%(NEST%)=PARM%(NEST%-1)
- GoSub LOAD-PARAMETERS
- else
- EBUF$="MACRO ("+TEXT$+") NOT DEFINED."
- GoSub ERRORS
- endw
- endp
- proc LOAD-PARAMETERS
- PASS%=FALSE%
- while PASS%=FALSE%
- PASS%=(CON%=FALSE%)
- GoSub PARSER
- while (FIRST%<=LN.%)
- PARM%(NEST%)=PARM%(NEST%)+1
- PARM$(PARM%(NEST%))=TEXT$
- GoSub PARSER
- wend
- IF(CON%)THEN GoSub INPUT-SOURCE
- wend
- endp
- proc INPUT-BUFFER
- when FILE.%(NEST%)<0
- GoSub INPUT-SOURCE
- else
- BUF$=STORE$(POINTER%)
- POINTER%=POINTER%+1
- ENDOFF%=(BUF$=CHR$(7))
- SKIP%=FALSE%
- CON%=SKIP%
- LN.%=LEN(BUF$)
- INDEX%=0
- endw
- endp
- proc INPUT-SOURCE
- INDEX%=0:CON%=FALSE%
- LINE INPUT #I.FILE%,BUF$
- ENDOFF%=EOF(I.FILE%)
- LN.%=LEN(BUF$):I%=1:II%=0
- while (I%>II% AND I%<LEN(BUF$))
- II%=I%:I%=I%+ABS(MID$(BUF$,I%,1)=" " OR MID$(BUF$,I%,1)=CHR$(9))
- wend
- II%=LN.%+1
- while (II%>LN.% AND LN.%>I%)
- II%=LN.%:LN.%=LN.%+(MID$(BUF$,LN.%,1)=" " OR MID$(BUF$,LN.%,1)=CHR$(9))
- wend
- BUF$=MID$(BUF$,I%,LN.%):LN.%=LEN(BUF$)
- SKIP%=(MID$(BUF$,1,1)="'" OR MID$(BUF$,1,1)=";" OR LEN(BUF$)<2)
- when SKIP%
- LN.%=1
- else when RIGHT$(BUF$,2)="\\"
- CON%=TRUE%
- BUF$=LEFT$(BUF$,LEN(BUF$)-2)
- LN.%=LEN(BUF$)
- endw
- endp
- proc FIND-MACRO-NAME
- FIND%=FALSE%:THIS.M%=0
- FOR M%=1 TO LAST.M%
- IF(MACRO$(M%)=TEXT$)THEN THIS.M%=M%:M%=LAST.M%+1
- NEXT M%
- FOUND%=(THIS.M%>0)
- IF(FOUND%)THEN FIND%=MACRO%(THIS.M%)
- endp
- proc INPUT-A-MACRO
- GoSub PARSER
- GoSub LCASE
- GoSub FIND-MACRO-NAME
- when FOUND%
- MACRO%(THIS.M%)=STORE.%+1
- else
- MACRO$(LAST.M%+1)=TEXT$
- MACRO%(LAST.M%+1)=STORE.%+1
- LAST.M%=LAST.M%+1
- endw
- GoSub INPUT-SOURCE
- GoSub PARSER
- GoSub LCASE
- while (TEXT$<>"endm" AND ENDOFF%=FALSE%)
- IF(SKIP%=FALSE%)THEN GoSub STORE-MACRO-CODE
- GoSub INPUT-SOURCE
- IF(SKIP%=FALSE%)THEN GoSub PARSER:GoSub LCASE
- wend
- BUF$=CHR$(7)
- GoSub STORE-MACRO-CODE
- endp
- proc STORE-MACRO-CODE
- STORE.%=STORE.%+1
- STORE$(STORE.%)=BUF$
- endp
- proc PARSER
- I%=32
- while (I%=32)
- INDEX%=INDEX%+1
- IF(INDEX%<=LEN(BUF$))THEN I%=ASC(MID$(BUF$,INDEX%,1)) ELSE I%=7
- I%=I%+(23*ABS(I%=9))
- wend
- FIRST%=INDEX%
- while (I%<>32 AND I%<>7)
- when I%=44 OR I%=9
- I%=32
- else
- when I%=34
- X%=INSTR(INDEX%+1,BUF$,CHR$(34))
- IF(X%>INDEX%)THEN INDEX%=X%
- endw
- INDEX%=INDEX%+1
- IF(INDEX%<=LEN(BUF$))THEN I%=ASC(MID$(BUF$,INDEX%,1)) ELSE I%=7
- endw
- wend
- TEXT$=MID$(BUF$,FIRST%,INDEX%-FIRST%)
- endp
- proc FILENAMES
- LINE INPUT"INPUT FILE [.M]:",I.FILE$
- unless I.FILE$=""
- IF(INSTR(I.FILE$,DOT$)=0)THEN I.FILE$=I.FILE$+IEXT$
- LK.$=I.FILE$:LK.%=I.FILE%:GoSub _Lookup:I.FILE%=LK.%
- unless I.FILE%=FALSE%
- I%=INSTR(1,I.FILE$,DOT$)
- IF(I%=0)THEN I%=LEN(I.FILE$)+1
- FILE$=LEFT$(I.FILE$,I%-1)
- LINE INPUT"OUTPUT FILE [.P]:",O.FILE$
- IF(O.FILE$="")THEN O.FILE$=FILE$
- IF(INSTR(O.FILE$,DOT$)=0)THEN O.FILE$=O.FILE$+OEXT$
- endu
- endu
- endp
- proc ERRORS
- ERRORS%=ERRORS%+1
- EBUF$="ERR#"+STR$(ERRORS%)+" ("+EBUF$+")"
- PRINT EBUF$
- endp
- proc LCASE
- I%=1
- while (I%<=LEN(TEXT$))
- II%=ASC(MID$(TEXT$,I%,1))
- MID$(TEXT$,I%,1)=CHR$(II%+(32*ABS(II%>64 AND II%<91))):I%=I%+1
- wend
- endp
- proc LIBRARY
- GoSub PARSER
- unless TEXT$=""
- IF(INSTR(TEXT$,DOT$)=0)THEN TEXT$=TEXT$+LEXT$
- LK.%=I.FILE%+1:LK.$=TEXT$:GoSub _Lookup
- when LK.%>0
- OPEN"I",LK.%,LK.$:I.FILE%=LK.%
- NEST%=NEST%+1:FILE.%(NEST%)=-1
- else
- EBUF$="LIBRARY ("+LK.$+") NOT FOUND!"
- GoSub ERRORS
- endw
- endu
- endp
- proc _Lookup
- OPEN"R",LK.%,LK.$:L.K!=LOF(LK.%):CLOSE LK.%
- IF(L.K!<1)THEN LK.%=0:KILL LK.$
- endp
- proc SUBROUTINE
- S%=0
- while (S%<SUBS%)
- S%=S%+1:IF(TEXT$=SUBS$(S%))THEN S%=SUBS%+1
- wend
- IF(S%=SUBS%)THEN SUBS%=SUBS%+1:SUBS$(SUBS%)=TEXT$
- endp