SYSTEMROUTINE  EDIT
      SYSTEMROUTINESPEC  MOVE(INTEGER  LEN, FROM, TO)
      SYSTEMROUTINESPEC  SIM2(INTEGER  EP, R1, R2, INTEGERNAME  R3)

      BYTEINTEGERARRAY  EDITS, INPUT(0:160)
      OWNSTRING  (3) ARRAY  ACTION(0:7)="ALT", "DEL", "E", "INS",  C 
        "R", "TC", "TS", "T"
      OWNBYTEINTEGERARRAY  ACTIONSWITCH(0:7)=65, 68, 69, 73, 82, C 
        85, 86, 84
      OWNINTEGERARRAY  ACTIONTYPE(0:25)=0, -1(2), 1, 2, -1(3), 3, C 
        -1(8), 4, -1, 5, -1(6)
      CONSTSTRING  (1) ARRAY  DELIM(0:4)=",", "/", "=", "?", "
"
      OWNBYTEINTEGERARRAY  DELIMCHRS(0:3)=44, 47, 61, 63
      CONSTSTRING  (1)NL="
"

      INTEGER  LEN, IN, OUT, CTL, LINE, ADRINPUT, ADREDITS, M, I, LENI
      INTEGER  INSET, FLAG, POSITION, TYPEFLG, ENDSET, ERR, INREAD
      INTEGER  INLINE, SWITCHSET, EDITR, FROM, TO, PRINTBUFF, C 
        EDITREAD, TEXT, STR, TEXTSET, COPYSW
      INTEGER  REPFROM, REPTO, REPCOUNT
      STRING  (255)EDITCOM, PAR1, PARAM1, PARAM2, REST, C, D, ST, C 
        OUTPUTSTR, RESTOFLINE
      STRING  (1)LASTDELIM
      SWITCH  SW(65:90)


      OWNSTRING  (35) ARRAY  MESS(1:7)='INVALID EDIT COMMAND', 
      'POSITIONING BACKWARDS INVALID', 
      'RANGE INCORRECT', 
      'INPUT ENDED', 
      'INVALID PARAMETERS TO EDIT COMMAND', 
      'STRING NOT FOUND', 
      'EDIT STREAM EXHAUSTED'
      !*
      !*
      !**************************************************************
      !*
                                       !                         
                                       ! ROUTINE WRITEOUTPUT99
      !*
      !**************************************************************
      !*
      !*


      ROUTINE  WRITEOUTPUT99
         SELECTOUTPUT(99)
         SIM2(1, ADREDITS, LEN, FLAG)
         SELECTOUTPUT(OUT)
      END  
      !*
      !*
      !***************************************************************
      !*
                                       !ROUTINE WRITEOUTPUT
      !*
      !****************************************************************
      !*
      !*


      ROUTINE  WRITEOUTPUT(INTEGER  I)
         IF  I=1 THENSTART  
            IF  INREAD=1 THENSTART  
               IF  OUTPUTSTR='' THEN  SIM2(1, ADRINPUT+1, LENI-1, C 
                 FLAG) ELSE  PRINTSTRING C 
                 (OUTPUTSTR.RESTOFLINE) AND  OUTPUTSTR=''
INREAD=0
            FINISHELSE  SIM2(1, ADRINPUT, LENI, FLAG)
         FINISHELSE  SIM2(1, ADREDITS, LEN, FLAG)
      END  
      !*
      !*
      !**************************************************************
      !*
                                       !       ROUTINE GETINPUT
      !*
      !*****************************************************************
      !*
      !*


      ROUTINE  GETINPUT(INTEGER  I)
         IF  I=1 THENSTART  
            IF  INSET=0 THEN  SELECTINPUT(IN) AND  INSET=1
            IF  INREAD=0 THEN  SIM2(0, ADRINPUT+1, 0, LENI) AND  C 
              LINE=LINE+1 
         FINISHELSESTART  
            IF  INSET=1 THEN  SELECTINPUT(CTL) AND  INSET=0
            SIM2(0, ADREDITS+1, 0, LEN)
         FINISH  
      END  
      !*
      !*
      !**************************************************************
      !*
                                       ! FUNCTION COPY
      !*
      !**************************************************************
      !*
      !*


      INTEGERFN  COPY(INTEGER  UPTO)
READ:    GETINPUT(1)
         IF  INPUT(1)=25 THENRESULT  =4
         WRITEOUTPUT(1)
         IF  LINE>=UPTO THENRESULT  =0
         ->READ
      END  
      !*
      !*
      !**************************************************************
      !*
                                       ! FUNCTION DELETE
      !*
      !**************************************************************
      !*
      !*


      INTEGERFN  DELETE(INTEGER  FROM, TO)
         INTEGER  LOOP
         LOOP=FROM
READ:    GETINPUT(1)
         LOOP=LOOP+1
         IF  INPUT(1)=25 AND  TO=-1 THENRESULT  =0
         IF  INPUT(4)=25 THENRESULT  =1
         IF  LOOP>TO AND  TO#-1 THENRESULT  =0 ELSE  ->READ
      END  
      !*
      !*
      !**************************************************************
      !*
                                       ! FUNCTION GETRANGE
      !*
      !**************************************************************
      !*
      !*


      INTEGERFN  GETRANGE(INTEGERNAME  FROM, TO)
         INTEGER  I, J, L, K, ADR, PSET, NUMBER, TRANGE, NO
         STRING  (255)A, B, SP
         NUMBER=0
         TRANGE=0
         PSET=0
         TO=0
         FROM=0
         I=1
         J=1
         A=PARAM1
         B=''
         IF  PARAM1->A.("-").B THENSTART  
            I=2
            IF  B->SP.("+").B THEN  PSET=1
            ->GETNO
         FINISH  
         IF  PARAM1->B.("+").A THEN  TRANGE=1
GETNO:   IF  J=1 THEN  ADR=ADDR(A) ELSE  ADR=ADDR(B)
         IF  J=1 THEN  K=LENGTH(A) ELSE  K=LENGTH(B)
         IF  K<=0 THENRESULT  =3
         CYCLE  L=1, 1, K
            NO=BYTEINTEGER(ADR+L)
            IF  X'30'<=NO<=X'39' THEN  NUMBER=NUMBER*10+NO-'0' AND  C 
              ->REP
            IF  NO=X'20' THEN  ->REP
            IF  NO='E' THENSTART  
               RESULT  =3 IF  TRANGE=1
               TO=-1
               IF  I=1 THEN  FROM=-1
               RESULT  =0
            FINISH  
            RESULT  =3
REP:     REPEAT  
         IF  J=1 THEN  FROM=NUMBER ELSE  TO=NUMBER
         J=J+1
         IF  I=1 AND  TO#-1 THEN  TO=FROM
         IF  TRANGE=1 THENSTART  
            IF  COPYSW>81 THEN  FROM=FROM+LINE-1 ELSE  FROM=FROM+LINE
         FINISH  
         IF  I=1 THENRESULT  =0
         IF  J<3 THEN  ->GETNO
         IF  PSET=1 THEN  TO=FROM+TO
         RESULT  =0
      END  
      !*
      !*
      !**************************************************************
      !*
                                       !FUNCTION SPLIT
      !*
      !**************************************************************
      !*
      !*


      INTEGERFN  SPLIT(INTEGER  TYPE)
                                       !TYPE=4 FOR R
                                       !TYPE#4 OTHERWISE
         INTEGER  I, CHR
         STRING  (255)REST
REM:     IF  PAR1->(" ").PAR1 THEN  POSITION=POSITION+1 AND  ->REM
         IF  TYPE=4 THEN  ->R
         IF  5<=TYPE<=6 THEN  ->T
         CHR=BYTEINTEGER(ADDR(PAR1)+1)
         IF  TYPE=7 AND  (CHR='/' OR  CHR='?' OR  CHR='=') THEN  ->T
         CYCLE  I=0, 1, 4
            IF  PAR1->PARAM1.(DELIM(I)) THENSTART  
               IF  DELIM(I)=NL THEN  POSITION=1 ELSE  C 
                 POSITION=POSITION+LENGTH(PARAM1)+1
               RESULT  =0
            FINISH  
         REPEAT  
         RESULT  =5
R:       CYCLE  I=1, 1, 3
            IF  PAR1->(DELIM(I)).PARAM1.(DELIM(I)).PARAM2.(DELIM(I) C 
              ).REST THENSTART  
               POSITION=POSITION+3+LENGTH(PARAM1)+LENGTH(PARAM2)
               IF  POSITION>=LEN THEN  POSITION=1
               RESULT  =0
            FINISH  
         REPEAT  
         RESULT  =5
T:       CYCLE  I=1, 1, 3
            IF  PAR1->(DELIM(I)).PARAM1.(DELIM(I)).REST THENSTART  
               TEXTSET=TYPE-5
               POSITION=POSITION+2+LENGTH(PARAM1)
               IF  POSITION>=LEN THEN  POSITION=1
               RESULT  =0
            FINISH  
         REPEAT  
         RESULT  =5
      END  
      !*
      !*
      !***************************************************************
      !*
                                       !FUNCTION GET EDIT COMMAND
      !*
      !**************************************************************
      !*
      !*


      INTEGERFN  GET EDIT COMMAND(INTEGERNAME  SWITCHSET)
         INTEGER  I, J, TYP
         PARAM1=''
         PARAM2=''
         PAR1=''
         IF  REPCOUNT>0 THENSTART  
            MOVE(LEN-POSITION+1, ADREDITS+POSITION, ADDR(EDITCOM)+1)
            BYTEINTEGER(ADDR(EDITCOM))=LEN-POSITION+1
            IF  EDITCOM->(")").EDITCOM THENSTART  
               REPCOUNT=REPCOUNT-1
               IF  REPCOUNT=0 THEN  POSITION=REPTO AND  ->ENDREPTN
               REPTO=POSITION+1
               POSITION=REPFROM
            FINISH  
            ->NO EDIT READ
         FINISH  
         IF  POSITION>1 THEN  ->NO EDIT READ
         IF  EDITREAD=1 THEN  EDITREAD=0 AND  ->NO EDIT READ
SELECT:  GETINPUT(0)
         IF  EDITS(1)=25 THENRESULT  =7
         CYCLE  I=LEN-1, -1, 1
            IF  EDITS(I)=32 THEN  LEN=LEN-1 ELSE  EDITS(LEN)=10 C 
              ANDEXIT  
         REPEAT  
         WRITEOUTPUT99
NO EDIT READ:MOVE(LEN-POSITION+1, ADREDITS+POSITION, ADDR(EDITCOM)+1)
         BYTEINTEGER(ADDR(EDITCOM))=LEN+1-POSITION
SPACES:  IF  EDITCOM->(" ").EDITCOM THEN  POSITION=POSITION+1 AND  C 
           ->SPACES
ENDREPTN:IF  EDITCOM=NL THEN  POSITION=1 AND  ->SELECT
         CYCLE  J=1, 1, 3
            CYCLE  I=0, 1, 3
               IF  EDITCOM->(DELIM(I)).EDITCOM THENSTART  
                  POSITION=POSITION+1
                  UNLESS  I=0 THEN  LASTDELIM=DELIM(I)
                  ->REP
               FINISH  
            REPEAT  
            ->START EDIT COM
REP:     REPEAT  
START EDIT COM:IF  EDITCOM->(" ").EDITCOM THEN  POSITION=POSITION+1 C 
           AND  ->START EDIT COM
         I=BYTEINTEGER(ADDR(EDITCOM)+1)-65
         UNLESS  I>=0 AND  I<26 THENSTART  
            IF  EDITCOM->("*").PARAM1.("(").EDITCOM THENSTART  
               POSITION=POSITION+2+LENGTH(PARAM1)
               ERR=GETRANGE(REPCOUNT, TO)
               UNLESS  ERR=0 THENRESULT  =ERR
               REPFROM=POSITION
               ->START EDIT COM
               FINISHELSERESULT  =1
            FINISH  
            TYP=ACTIONTYPE(I)
            IF  TYP=-1 THENRESULT  =1
            CYCLE  I=TYP, 1, 7
               IF  EDITCOM->(ACTION(I)).PAR1 THENSTART  
                  POSITION=POSITION+LENGTH(ACTION(I))
                  J=SPLIT(I)
                  UNLESS  J=0 THENRESULT  =5
                  COPYSW=SWITCHSET
                  SWITCHSET=ACTIONSWITCH(I) ANDRESULT  =0
               FINISH  
            REPEAT  
            RESULT  =1
         END  
         !*
         !*
         !**************************************************************
         !*
         !*
         RESTOFLINE=''
         OUTPUTSTR=''
         REPCOUNT=0
         LASTDELIM=''
         SWITCHSET=0
         TEXTSET=0
         INREAD=0
         TEXT=0
         PRINTBUFF=0
         EDITREAD=0
         EDITR=0
         IN=101
         OUT=102
         CTL=108
         ENDSET=0
         POSITION=1
         LINE=1
         TYPEFLG=0
         ADRINPUT=ADDR(INPUT(0))
         ADREDITS=ADDR(EDITS(0))
         INPUT(0)=10
         EDITS(0)=10
         SELECTINPUT(CTL) AND  INSET=0
         SELECTOUTPUT(OUT)
         !*
         !*
GET COMMAND:ERR=GET EDIT COMMAND(SWITCHSET)
         UNLESS  ERR=0 THEN  ->ERROR
         ->SW(SWITCHSET)
         !*
         !*
         !**************************************************************
         !*
         !*
SW(69):                                !E  END
COPY NEXT:GETINPUT(1)
         IF  INPUT(1)=25 AND  ENDSET=1 THEN  ENDSET=0 AND  ->ALT
JUMP:    IF  INPUT(1)=25 THEN  ->END
         WRITEOUTPUT(1)
         ->COPY NEXT
         !*
         !*
         !**************************************************************
         !*
         !*
SW(68):                                !DEL,D  DELETE
         ERR=GETRANGE(FROM, TO)
         UNLESS  ERR=0 THEN  ->ERROR
         IF  LINE=FROM THEN  ->DEL
         IF  LINE>FROM THEN  ERR=2 AND  ->ERROR
         IF  LINE<FROM THEN  ERR=COPY(FROM)
         UNLESS  ERR=0 THEN  ->ERROR
DEL:     ERR=DELETE(FROM, TO)
         UNLESS  ERR=0 THEN  ->ERROR
         IF  TYPEFLG=1 THEN  TYPEFLG=0 AND  ->ALT
         ->GET COMMAND
         !*
         !*
         !**************************************************************
         !*
         !*
SW(84):                                !  T   TRANSCRIBE
         IF  TEXTSET=2 THEN  TEXTSET=0 AND  ->TEXT
         ERR=GETRANGE(FROM, TO)
         UNLESS  ERR=0 THEN  ->ERROR
         IF  FROM=-1 THEN  ENDSET=1 AND  ->SW(69)
         COPYSW=0
         IF  LINE=FROM AND  INREAD=0 THENSTART  
            IF  TYPEFLG=1 THEN  TYPEFLG=0 AND  ->ALT ELSE  ->GETCOMMAND
         FINISH  
         IF  LINE>FROM THEN  ERR=2 AND  ->ERROR
         IF  LINE<=FROM THEN  ERR=COPY(FROM)
         UNLESS  ERR=0 THEN  ->ERROR
         IF  TYPEFLG=1 THEN  TYPEFLG=0 AND  ->ALT
         ->GET COMMAND
TEXT:    IF  PARAM1='' THEN  ERR=5 AND  ->ERROR
TEXT1:   GETINPUT(1)
         IF  INPUT(1)=25 THEN  ERR=4 AND  ->ERROR
         INPUT(0)=LENI
         IF  STRING(ADDR(INPUT(0)))->(PARAM1).REST THEN  INREAD=1 C 
           AND  INPUT(0)=10 AND  ->GETCOMMAND ELSE  INPUT(0)=10 AND  C 
           WRITEOUTPUT(1) AND  ->TEXT1
         !*
         !*
         !**************************************************************
         !*
         !*
SW(85):                                !TC
TC:      IF  PARAM1='' THEN  ERR=5 AND  ->ERROR
RDTEXT:  GETINPUT(1)
         IF  INPUT(1)=25 THEN  ERR=4 AND  ->ERROR
         INPUT(0)=LENI
         IF  STRING(ADDR(INPUT(0)))->ST.(PARAM1).REST THEN  INREAD=1 C 
           AND  INPUT(0)=10 AND  ->GET COMMAND ELSE  INPUT(0)=10 C 
           AND  WRITEOUTPUT(1) AND  ->RDTEXT
         !*
         !*
         !**************************************************************
         !*
         !*
SW(86):                                !TS
TS:      IF  PARAM1='' THEN  ERR=5 AND  ->ERROR
RDTEXT2: GETINPUT(1)
         IF  INPUT(1)=25 THEN  ERR=4 AND  ->ERROR
         INPUT(0)=LENI
         IF  STRING(ADDR(INPUT(0)))->ST.(PARAM1).REST THENSTART  
            INPUT(0)=10
SP:         IF  ST->(" ").ST THEN  ->SP
            IF  ST='' THEN  INREAD=1 AND  ->GET COMMAND
         FINISH  
         INPUT(0)=10
         WRITEOUTPUT(1)
         ->RDTEXT2
         !*
         !*
         !**************************************************************
         !*
         !*
SW(82):                                !R  REPLACE
         INLINE=0
         M=0
         REST=''
         GETINPUT(1)
         IF  INPUT(1)=25 THEN  ERR=4 AND  ->ERROR
MAKESTRING:IF  PARAM1='' THEN  ERR=5 AND  ->ERROR
         MOVE(LENI, ADRINPUT+1, ADDR(C)+1)
         BYTEINTEGER(ADDR(C))=LENI
SPLITSTRING:IF  C->D.(PARAM1).RESTOFLINE THEN  C 
           OUTPUTSTR=OUTPUTSTR.D.PARAM2 ELSE  ERR=6 AND  ->ERROR
         LENI=LENGTH(RESTOFLINE)
         MOVE(LENI, ADDR(RESTOFLINE)+1, ADRINPUT+1)
         INREAD=1
        -> GET COMMAND
         !*
         !*
         !**************************************************************
         !*
         !*
SW(65):                                !ALT  ALTER
         TYPEFLG=1
         ->SW(68)
ALT:     GETINPUT(0)
         CYCLE  I=LEN-1, -1, 1
            IF  EDITS(I)=32 THEN  LEN=LEN-1 ELSE  EDITS(LEN)=10 C 
              ANDEXIT  
         REPEAT  
         WRITEOUTPUT99
         STR=EDITS(1)
         IF  STR=BYTEINTEGER(ADDR(LASTDELIM)+1) THENSTART  
            IF  LEN>2 THEN  EDITREAD=1
            ->GET COMMAND
         FINISH  
         IF  EDITS(1)=25 THEN  ERR=7 AND  ->ERROR
         WRITEOUTPUT(0)
         ->ALT
         !*
         !*
         !**************************************************************
         !*
         !*
SW(73):                                !INS INSERT
         TYPEFLG=1
         ->SW(84)
         !*
         !*
         !**************************************************************
         !*
         !*
         !*
         !*
ERROR:   SELECTOUTPUT(99)
         PRINTSTRING(MESS(ERR))
         NEWLINE
         SELECTOUTPUT(OUT)
         ENDSET=0
         ->SW(69)
END:     SELECTOUTPUT(99)
         PRINTSTRING('EDIT COMPLETED
')
      END  
ENDOFFILE