   Dim Version$/"Parameterized DO file processor V1.0a (C) 1985 Software Dynamics"/
!  Accepts a single command line (unfinished)
!       Arguments are named ?n, where n varies from 0 to 9, corresponding     !
!       to the first through last argument.  Should an argument not be        !
!       supplied, the value of ?n is '0'.                                     !
!                                                                             !
!       Local labels can be generated by use of ?a, where 'a' is a letter.    !
!                                                                             !
!       EXAMPLE MACRO                                                         !
!                                                                             !
!       MACRO   PRINT   This macro prints a message on the terminal (chan 0)  !
!       *               The args are as follows: string,error routine         !
!       *               if the error routine isn't supplied (=0), an          !
!       *               error exit is performed on an error                   !
!               LDX     #?A                                                   !
!               JSR     $FB                                                   !
!               BCC     ?B                                                    !
!               IF      0=?1    IS THERE NO ERROR ROUTINE?                    !
!               STX     ?C                                                    !
!               LDX     #?D                                                   !
!               JMP     $FB     BYE-BYE!                                      !
!               ELSE                                                          !
!               JMP     ?1      GO TO HIS ERROR RECOVERY ROUTINE              !
!               FIN                                                           !
!       ?A      FCB     SYSCALL:WRITEA                                        !
!               FCB     WRITEA:SCLEN                                          !
!               FCB     0,IGNORED                                             !
!               FDB     ?E      STRING ADDRESS                                !
!               FDB     ?F      STRING LENGTH                                 !
!                                                                             !
!       ?E      FCC     ?0                                                    !
!       ?F      EQU     *-?E                                                  !
!                                                                             !
!       ?D      FCB     SYSCALL:ERROREXIT                                     !
!               FCB     ERROREXIT:SCLEN                                       !
!               FDB     CHANGED                                               !
!                                                                             !
!       ?B      EQU     *                                                     !
!               MEND                                                          !
!                                                                             !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

         DIM MACROS$[2048]/""/

         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         ! Macro expansion variable                                 !
         ! ! :FF ! name of macro ! :FE ! channel # ! File position !!
         !    1         n           1        1           3          !
         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!       other variables for macro expansion:

         DIM MACRO$[20], MLINE$[100], MACROLINE$[100], FF$/:FF/
         DIM FE$/:FE/, T$[4], ARGS$[80], BYTES4$/0,0,0,0/, TABCHR$/9/

!       macro processor state variable

         DIM MACROSTATE/1/

!       argument binding variables

         DIM ARGSP(10), ARGSL(10), NARGS/0/

!       position in macros$ of current macro

         DIM MACROPOS

!       VARIABLES FOR PREPARSING

!       various fields in line

         DIM LABEL$[32], CF$[32], AF$[80], REST$[100]

!       input line and scratch

         DIM LINE$[100], TEMP$[100]

!       GET LINE VARIABLES

         DIM CURCHAN/2/, OUTPUT/1/, FILE$[30]

!       SYSCALL VARIABLE(S)

         DIM GETCURPOS$/:F,:E,0,0/, CHANNEL/3/

!       local label variables

         DIM LABELBASE/0/,NLABELSUSED/0/

                              !!!!!!!!!!!!!!!!!!!
                              ! PROGRAM STARTUP !
                              !!!!!!!!!!!!!!!!!!!

	 PRINT	"MACRO v1.0g    Copyright (C) 1980 Software Dynamics"
	 ON ERROR GOTO NOMACLIB
        OPEN #CURCHAN,"MACRO.LIB"
	 ON ERROR GOTO NOOUTPUTFILE
	 GOTO GETLINE

GETINPUTFILE:
	ON ERROR GOTO 0
       INPUT "Input file= " FILE$
	IF FILE$<>"CONSOLE:" THEN
		CURCHAN=CURCHAN+1
		OPEN #CURCHAN,FILE$
	ELSE CURCHAN=0
       INPUT "Output file= " FILE$
       IF    FILE$="CONSOLE:" THEN OUTPUT=0
       ELSE  CREATE #OUTPUT, FILE$
	ON ERROR GOTO ENDOFINPUT
	GOTO GETLINE

NOMACLIB:
	IF ERR<>1011 THEN ERROR
	PRINT "I can't find MACRO.LIB"
	CURCHAN=CURCHAN-1
	GOTO GETINPUTFILE

NOOUTPUTFILE:
	IF ERR=9000 THEN GETINPUTFILE
	IF ERR<>1032 THEN ERROR
	PRINT "I can accept only macro definitions from MACRO.LIB"
	ERROR 100

ENDOFINPUT:
	IF ERR<>9000 THEN ERROR
	PRINT #OUTPUT,LINE$
	EXIT

                           !!!!!!!!!!!!!!!!!!!!!!!!
                           ! GET LINE FROM SOURCE !
                           !!!!!!!!!!!!!!!!!!!!!!!!

GETLINE: !
       INPUT #CURCHAN, LINE$
       IF    EOF(CURCHAN) THEN LINE$="	END	<END supplied by MACRO>"

       GOSUB PREPARSE
       IF    CF$<>"END" THEN MACROEXPANDER
	ERROR 9000


                             !!!!!!!!!!!!!!!!!!!!!
                             ! PRE PARSE ROUTINE !
                             !!!!!!!!!!!!!!!!!!!!!

PREPARSE: !
       LABEL$=""
       CF$=""
       AF$=""
       REST$=""

!       a few quick tests...

       IF    LEN(LINE$)=0 THEN RETURN
       IF    LINE$(1)=ASC "*" OR LINE$(1)=ASC ";" THEN
             REST$=LINE$
             RETURN
       FI

       TEMP$=UPPERCASE$(LINE$)

PREPARSEFORLABEL: !
       IF    TEMP$(1,1)=' ' OR TEMP$(1,1)=TABCHR$ THEN
             GOSUB EATSPACES
             IF    FIND(TEMP$,';')=1 THEN
                   REST$=LINE$
                   RETURN
             FI
             GOTO PREPARSEFORCF
       FI

       I=FIND(TEMP$,TABCHR$)
       J=FIND(TEMP$,' ')

       IF    I=0 THEN I=J
       IF    J=0 THEN J=I
       IF    I<J THEN
             LABEL$=TEMP$(1,I-1)
             TEMP$=RIGHT$(TEMP$,I+1)
       ELSE
             IF    J=0 THEN
                   LABEL$=TEMP$
                   RETURN
             FI
             LABEL$=TEMP$(1,J-1)
             TEMP$=RIGHT$(TEMP$,J+1)
       FI

       GOSUB EATSPACES

PREPARSEFORCF: !
       IF    TEMP$=""
       THEN
             LABEL$=""
             REST$=LINE$
             RETURN
       FI

       I=FIND(TEMP$,TABCHR$)
       J=FIND(TEMP$,' ')
       IF    I=0 THEN I=J
       IF    J=0 THEN J=I

       IF    I<J THEN
             CF$=TEMP$(1,I-1)
             TEMP$=RIGHT$(TEMP$,I+1)
       ELSE
             IF    J=0 THEN
                   CF$=TEMP$
                   RETURN
             FI
             CF$=TEMP$(1,J-1)
             TEMP$=RIGHT$(TEMP$,J+1)
       FI

       GOSUB EATSPACES

PREPARSEFORAF: !
       IF    TEMP$="" THEN RETURN
             IF    FIND(TEMP$,";")=1 THEN PREPARSEREST

       I=FIND(TEMP$,TABCHR$)
       J=FIND(TEMP$," ")

       IF    I=0  THEN I=J
       IF    J=0 THEN J=I
       IF    I<J THEN
             AF$=TEMP$(1,I-1)
             TEMP$=RIGHT$(TEMP$,I+1)
       ELSE
             IF    J=0 THEN
                   AF$=TEMP$
                   RETURN
             FI
             AF$=TEMP$(1,J-1)
             TEMP$=RIGHT$(TEMP$,J+1)
       FI

       GOSUB EATSPACES

PREPARSEREST: !
       REST$=TEMP$
       RETURN

                  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                  ! EAT SPACES AND TABS FROM FRONT OF TEMP$ !
                  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

EATSPACES: !
      IF    FIND(TEMP$,' ')=1 OR FIND(TEMP$,TABCHR$)=1 THEN
            TEMP$=RIGHT$(TEMP$,2)
            GOTO EATSPACES
      FI
      RETURN


                        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                        ! ACTUAL MACRO EXPANSION CODE !
                        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!       Macro states:
!               1-not defining nor expanding a macro
!               2-expanding a macro (included for completeness)
!               3-defining a macro


MACROEXPANDER: !
        MLINE$=LINE$
        ON MACROSTATE GOTO MACROSTART, EXPANDLOOP, ENDMACDEF
	PRINT	"Error encountered in MACROEXPANDER.  Processing continues."
	MACROSTATE=1
	GOTO MACROEXPANDER

!       state 1: look for either starting to define the macro
!                or a macro call.  If neither, just pass line
!                to the output routine.

MACROSTART: !
        IF    LABEL$="MACRO" THEN STARTMACDEF

!       now, look to see if name is in macro table...

        TEMP$=FF$ CAT CF$ CAT FE$
        MACROPOS=FIND(MACROS$,TEMP$)

        IF    NOT(MACROPOS) THEN
              GOSUB MACROOUTPUT
              GOTO GETLINE
        FI

!       Since we're here, we have found a macro which matches CF$

!       Now, parse the arguments... (iQUE DOLOR!)

!       LIST MACRO CALL WITH ";" FOLLOWING LABEL FIELD-SEPARATOR

	I=FIND(RIGHT$(MLINE$,LEN(LABEL$)+1),CF$)+LEN(LABEL$)
        MLINE$=LEFT$(MLINE$,I-1) CAT ";" CAT RIGHT$(MLINE$,I)
        GOSUB MACROOUTPUT


!       bind the arguments for the expansion phase

BINDARGS: !
        NARGS=0
        ARGS$=""

BINDLOOP: !
        I=FIND(AF$,",")
        IF    NOT(I) THEN LASTARG
        NARGS=NARGS+1

        ARGSP(NARGS)=LEN(ARGS$)+1
        ARGSL(NARGS)=I-1
        LEN(ARGS$)=LEN(ARGS$)+I-1
        ARGS$(ARGSP(NARGS),ARGSL(NARGS))=AF$(1,I-1)

        AF$=RIGHT$(AF$,I+1)
        GOTO BINDLOOP

LASTARG: !
        IF    AF$="" THEN EXPAND

        NARGS=NARGS+1
        ARGSP(NARGS)=LEN(ARGS$)+1
        ARGSL(NARGS)=LEN(AF$)
        LEN(ARGS$)=LEN(ARGS$)+LEN(AF$)
        ARGS$(ARGSP(NARGS),ARGSL(NARGS))=AF$

!       now start the expansion of the macro

EXPAND: !
        MACROSTATE=2
        GOSUB MACROFETCHINIT

EXPANDLOOP: !
        GOSUB MACROFETCH

        IF    MACROLINE$="MEND" THEN
              LABELBASE=LABELBASE+NLABELSUSED
              NLABELSUSED=0
              MACROSTATE=1
              GOTO GETLINE
        FI
        I=0

SUBSARGSLOOP: !
	IF I+1 >= LEN(MACROLINE$) THEN DONETHISLINE
        J=I+FIND(RIGHT$(MACROLINE$,I+1),"?")
        IF    J=I THEN DONETHISLINE
        IF    J=LEN(MACROLINE$) THEN DONETHISLINE

        I=J
        IF    MACROLINE$(I+1)>=ASC '0' AND MACROLINE$(I+1)<=ASC '9' THEN
              J=VAL(MACROLINE$(I+1,1))+1
              IF    J>NARGS THEN
                    MACROLINE$=MACROLINE$(1,I-1) CAT '0' CAT ...
&                   RIGHT$(MACROLINE$,I+2)
                    GOTO SUBSARGSLOOP
              FI
              MACROLINE$=MACROLINE$(1,I-1) CAT ...
&             ARGS$(ARGSP(J),ARGSL(J)) CAT ...
&             RIGHT$(MACROLINE$,I+2)
              GOTO SUBSARGSLOOP
        FI

!       maybe it's a local label...

        IF    MACROLINE$(I+1)>=ASC 'A' AND MACROLINE$(I+1)<=ASC 'Z'
        THEN
              J=MACROLINE$(I+1)-ASC 'A'+1
              IF    J>NLABELSUSED THEN NLABELSUSED=J
              MACROLINE$=MACROLINE$(1,I-1) CAT ...
&             "MACRO" CAT HEX$(J+LABELBASE) CAT ...
&             RIGHT$(MACROLINE$,I+2)
        FI
        GOTO SUBSARGSLOOP

DONETHISLINE: !
        MLINE$=MACROLINE$
        GOSUB MACROOUTPUT
        GOTO EXPANDLOOP


!       Macro definition loop

STARTMACDEF: !
	 IF CURCHAN=0 THEN
		PRINT "I can't accept macro definitions from the CONSOLE:"
		GOTO GETLINE
	 FI
        IF    CF$="" THEN
              PRINT "NULL MACRO NAME ENCOUNTERED!"
              GOTO ENDMACDEF
        FI

        GETCURPOS$(CHANNEL)=CURCHAN
        SYSCALL(GETCURPOS$,'',BYTES4$)

        BYTES4$(1)=CURCHAN

        MACRO$=FF$ CAT CF$ CAT FE$ CAT BYTES4$

        LEN(MACROS$)=LEN(MACROS$)+LEN(MACRO$)
        MACROS$(LEN(MACROS$)+1-LEN(MACRO$),LEN(MACRO$))= MACRO$
        MACROSTATE=3
        GOTO GETLINE

ENDMACDEF: !
        IF    CF$<>"MEND" THEN GETLINE
        MACROSTATE=1
        GOTO GETLINE




                           !!!!!!!!!!!!!!!!!!!!!!!!!
                           ! EXPANSION SUBROUTINES !
                           !!!!!!!!!!!!!!!!!!!!!!!!!




!       macro fetch init... prepare for fetching macros

MACROFETCHINIT: !
        I=FIND(RIGHT$(MACROS$,MACROPOS),FE$)
        MACRO$=MACROS$(MACROPOS,I+4)

        GETCURPOS$(CHANNEL)=MACRO$(I+1)
        SYSCALL(GETCURPOS$,'',BYTES4$)

        POSITION #MACRO$(I+1), ...
&       MACRO$(I+2)*65536+MACRO$(I+3)*256+MACRO$(I+4)

        RETURN

!       macro fetch...must watch for end of macro

MACROFETCH: !
        INPUT #MACRO$(LEN(MACRO$)-3), MLINE$
        IF    EOF(MACRO$(LEN(MACRO$)-3)) THEN
              PRINT "End encountered before MEND"
              EMITSTATE=1
              MLINE$=TABCHR$ CAT "MEND"
        FI
        LINE$=MLINE$
        GOSUB PREPARSE
        IF    CF$="MEND" THEN
              POSITION #MACRO$(LEN(MACRO$)-3), ...
&             BYTES4$(2)*65536+BYTES4$(3)*256+BYTES4$(4)
              MLINE$="MEND"
        FI

        MACROLINE$=MLINE$
        RETURN


                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                      ! MACRO OUTPUT ROUTINE...FOR NOW !
                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



MACROOUTPUT: !
        PRINT #OUTPUT,MLINE$
        RETURN


        END
   DIM TAB$/9/,MLINE$[100],LINE$[100],TEMP$[100],MACROLINE$[100]
   DIM LABEL$[32],CF$[32],AF$[80],REST$[100]
   DIM IN/1/,OUT/2/,FILE$[50],STACK$[256]
   DIM EMITSTATE/1/,CONDBLOCK/0/

   PRINT "STRIPIFS v2.0    Copyright (C) 1980 Software Dynamics"
   PRINT
   PRINT "Strips conditional IFs from assembly source:"
   PRINT "   copies input file to output file, requiring a response"
   PRINT "   from the user at each appropriate IF or ELSEIF statement."
   PRINT "   (See the assembler manual for a complete discussion"
   PRINT "   of conditional assembly)"
   GOSUB HUH
   INPUT "Input file=" FILE$
   OPEN #IN,FILE$
   INPUT "Output file=" FILE$
   CREATE #OUT,FILE$

   REPEAT
      INPUT #IN,MLINE$
      IF EOF(IN) THEN
         PRINT "EOF encountered before END"
         MLINE$=TAB$ CAT "END" CAT TAB$ CAT "<supplied by STRIPIFS>"
      FI
      LINE$=MLINE$
  