Trailing-Edge
-
PDP-10 Archives
-
BB-Z759A-SM
-
cobol-source/strgen.mac
There are 7 other files named strgen.mac in the archive. Click here to see a list.
; UPD ID= 1117 on 5/18/83 at 9:10 AM by NIXON
TITLE STRGEN FOR COBOL V13
SUBTTL CODE GENERATORS FOR STRING & UNSTRING C.MCCOMAS
SEARCH COPYRT
SALL
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
COPYRIGHT (C) 1974, 1983, 1984 BY DIGITAL EQUIPMENT CORPORATION
SEARCH P
%%P==:%%P
SEARCH INTERM ;NEED VALUE FOR "TOPS20"
IFE TOPS20, SEARCH MACTEN ;GET DEFS OF "MOVX", ETC.
IFN TOPS20,<SEARCH MONSYM,MACSYM>
TWOSEG
.COPYRIGHT ;Put standard copyright statement in REL file
SALL
RELOC 400000
;EDITS
;NAME DATE COMMENTS
;V12B****************
;JEH 01-Dec-82 [1434] Allow UNSTRING to return signs to signed
; destination fields.
;JEH 14-Jun-82 [1365] If STRING source is edited and has occurs clause
; wrong size is used, change to external size.
;JEH 11-Jun-82 [1364] UNSTRING delimiter has wrong size if figurative constant
; and source is edited.
;V12*****************
;DMN 1-APR-80 [1004] MAKE ASCII & EBCDIC COLLATING SEQUENCES WORK.
;DAW 1-MAR-79 [646] FIX ERROR MESSAGE ALWAYS POINTS TO LINE 371 IF
; ERROR WAS IN SUBSCRIPTED "COUNT" ITEM IN UNSTRING.
;DMN 29-NOV-78 [604] PUT OUT CORRECT ERROR MESSAGE ON STRING OF NON-NUMERIC TO NUMERIC.
;V10*****************
;NAME DATE COMMENTS
;EHM 12-DEC-77 [524] FIX UNSTRING INTO RECEIVING FIELD WITH DECIMAL PLACES.
;EHM 8-FEB-77 FIX STRING ERROR "RECEIVING ITEM MAY NOT BE EDITED
; OR JUSTIFIED" WHICH COMES OUT AT WRONG PLACE.
;ACK 2-JUN-75 FIX RANDOM ERROR MESSAGES THAT COME OUT SOMETIMES.
;ACK 3-JUN-75 COMP-3/EBCDIC FOR STRING.
;********************
ENTRY STRGEN ;STRING
ENTRY UNSGEN ;UNSTRING
;EXTERNAL ROUTINES
EXTERN LNKSET
;IN COBCOM
EXTERN CPOPJ,CPOPJ1
;IN CMNGEN
EXTERN PUTASY,PUTASN,PUT.EX,STASHI,STASHL,STASHP,STASHQ,POOLIT,POOL
EXTERN SZDPVA,DEPTSA,NB1PAR,SETOPA,SETOPB,SETOPN,OPNFAT,SUBSCA,GETEMP
EXTERN D.LTCD,BYTE.S
;IN MSCGEN
EXTERN GETTEM,MVAUN0
;IN MOVGEN
EXTERN MXX.,LITD.0
;IN IFGEN
EXTERN HIVQOT,IFSPCS,IFZROS
;IN MESGEN
EXTERN CSEQGN
EXTERN BMPEOP,GETTAG,REFTAG,PUTTAG
EXTERN TEMLOC,TEMNXT,EOPLOC,CUREOP,OPERND
EXTERN EBASEA,ERESA,EINCRA,EMODEA,ESIZEA,EDPLA,ETABLA,EFLAGA,EBYTEA
EXTERN EBASEB,ERESB,EINCRB,EMODEB,ESIZEB,EDPLB,ETABLB,EFLAGB,EBYTEB
EXTERN DA.JST,DA.EDT,DA.EXS,DA.BWZ,AS.CNB,AS.LIT,AS.MSC,TESUBC
EXTERN BYTLIT,OCTLIT,XWDLIT
EXTERN MOVEI.,MOV,MOVEM.,JRST.,POPJ.,SETZM.
EXTERN DSMODE,D1MODE,FPMODE,D7MODE,D9MODE
;IMPURE LOCS
EXTERN NSTRSE,STFLGS,STSSO,STPTO,SDSTIN,STSEST,STSELS,STSENS
EXTERN STSENX,STSETP,CURSSE,CURSRE
EXTERN ONLYEX,ALSTMP
EXTERN ELITPC,PLITPC,LITERR
EXTERN ESIZEZ
EXTERN SAVPR0
EXTERN M.ARG1,M.ARG2,M.ARG3,M.ARG4,LITNN
EXTERN STRSAV
EXTERN COLSEQ,COHVLV
DEFINE $CERR,< JSP TE,SIMPER >
SUBTTL HOW STRGEN WORKS
COMMENT \
Please read comments in STRNGL.MAC to understand what
is being generated by STRGEN. The remainder of the text here
assumes you have done that.
STRGEN first reads in all operands having to do with the
STRING or UNSTRING statement into EOPTAB. Then it shuffles them
around to make EOPTAB look like a bunch of operands (OPERATORS
are transformed into the 2-word pair (-1 + first word of operator)).
It also fills in the optional operands as (-2 + 0), so that
everything has a fixed number of operands. This constitutes the
"first pass" of STRING and UNSTRING code generation.
Next, extensive use of the TEM table allows STRGEN to
store some operands away for later code generation, while generating
some code for subscripts, other operands, or to get the initial value
of the item. In this pass, all operands are examined for validity,
and all initial setup code is generated. The operands are read from
EOPTAB, and some are put into TEMTAB for later use.
Next, the code for the runtime routines are generated. A "JRST"
is generated to jump over them. The operands needed for the runtime routines
are all read from TEMTAB entries. (The format of the TEMTAB entries is
explained elsewhere in this STRGEN). Each runtime routine ends with a POPJ
and is called by "PUSHJ'ing" to its tag. The tags are put into the
argument list when it is generated.
Next, the argument list is generated. Most of the information
in the TEMTAB entries is used to write the arguments in the argument list,
which is put into the literal table.
And finally, the "MOVEI 16,addr" and "PUSHJ 17,STR." is generated.
The information in TEMTAB is just left there. (Any code generator may
use TEMTAB for its own use.. each has the responsibility for resetting
it before it is used).
\ ;; end of comment
SUBTTL TEMTAB ENTRY FORMATS FOR STRING
;1) LOCATION STSETP POINTS TO FIRST STRING-SERIES ENTRY.
;
;2) EACH STRING-SERIES ENTRY HAS THE FOLLOWING FORMAT:
; +0/ LINK TO NEXT SS ENTRY, OR 0 IF THIS IS THE LAST
; +1/ LINK TO FIRST SOURCE ENTRY FOR THIS SS
; +2/ DELIMITER INFO FLAGS+BSI.DEL,,%TEMP OR 0
; +3/ %TAG OR 0
; +4/ NUMBER OF SOURCES
; +5-20/ OPERAND (IF NECESSARY TO STORE IT)
;
;3) EACH SOURCE-ENTRY HAS THE FOLLOWING FORMAT:
; +0/ LINK TO NEXT SOURCE ENTRY, OR 0 IF THIS IS THE LAST ONE
; +1/ BSI.SOURCE,,%TEMP OR 0
; +2/ %TAG OR 0
; +3-16/ OPERAND (IF NECESSARY TO STORE IT)
;TEMTAB ENTRY OFFSETS
;SS ENTRY
.SSLNK==0 ;LINK TO NEXT SS ENTRY
.SSLKS==1 ;LINK TO SOURCE ENTRIES FOR THIS SS
.SSFLG==2 ;FLAG WORD
SS%DLS==1B0 ;DELIMITED BY SIZE
SS%DNM==1B1 ;NUMERIC DELIMITER
BSI.DL: POINT 3,.SSFLG(TA),17 ;BSI OF DELIMITER
SPT.DL: POINT 18,.SSFLG(TA),35 ;POINTER TO %LIT FOR DELIMITER
TAG.DL: POINT 18,3(TA),35 ;TAG TO DELIMITER SETUP CODE
NUM.SR: POINT 18,4(TA),35 ;# OF SOURCES
.SSHLN==5 ;LEN OF FIXED PART OF SS ENTRY
.SSOPR==5 ;FIRST WORD OF OPERAND, IF ANY
;SOURCE ENTRY
.SRLNK==0 ;LINK TO NEXT SOURCE ENTRY
.SRFLG==1 ;FLAG WORD
SR%SRN==1B0 ;SOURCE IS NUMERIC
BSI.SR: POINT 3,.SRFLG(TA),17 ;BSI OF SOURCE
SPT.SR: POINT 18,.SRFLG(TA),35 ;PTR TO %LIT FOR SOURCE
TAG.SR: POINT 18,3(TA),35 ;TAG TO SOURCE SETUP CODE
.SRHLN==4 ;LEN OF FIXED PART OF SOURCE ENTRY
.SROPR==4 ;FIRST WORD OF OPERAND, IF ANY
SUBTTL GENERATE A "STRING"
COMMENT \
GENFIL FOR A STRING LOOKS LIKE:
SENDING ITEM 1.1
SENDING ITEM 1.2
...
SENDING ITEM 1.I
DELIMITER 1 (NOT PRESENT IF DELIMITED BY SIZE)
SDELIM OPERATOR (WITH FLAG 9 ON IF DELIMITED BY SIZE)
SENDING ITEM 2.1
SENDING ITEM 2.2
...
SENDING ITEM 2.J
DELIMETER 2 (NOT ...)
SDELIM OPERATOR (WITH ...)
...
SENDING ITEM K.1
SENDING ITEM K.2
...
SENDING ITEM K.L
DELIMITER K (NOT ...)
SDELIM OPERATOR (WITH ...)
RECEIVING ITEM
POINTER ITEM (OPTIONAL)
STRNG OPERATOR (WITH FLAG 10 ON IF THE POINTER ITEM IS PRESENT)
\
;ARRIVE HERE ON AN SDELIM OPERATOR
; FOLLOWED (OPTIONALLY) BY OTHER SDELIM'S WHICH MUST BE FORCIBLY READ
; AND THEN A STRNG OPERATOR WHICH ALSO MUST BE FORCIBLY READ
STRGEN: MOVE W2,W1 ;STORE [-1 + W1] IN EOPTAB
SETO W1, ; JUST AFTER OPERANDS FOR THIS SDELIM
PUSHJ PP,PUSH12##
HRRZ TB,EOPNXT## ;SAVE PTR TO NEXT LOC ON EOPTAB
ADDI TB,1
MOVEM TB,ARGSTR## ;USE THIS AS TEMP STORE
PUSHJ PP,READEM## ;READ NEXT OPERANDS+OPERATOR SET
CAIN W2,SDELIM ;ANOTHER SDELIM? OR A STRNG?
JRST STRGEN ;SDELIM
CAIE W2, STRNG ;WAS IT REALLY A STRING.
POPJ PP, ;NO, FORGET THE WHOLE THING, THE
; ERROR MESSAGE SHOULD HAVE BEEN
; GENERATED BY THE SYNTAX SCAN.
LDB TB,[POINT 1,W1,10] ;IS THERE A POINTER-ITEM?
JUMPN TB,STRG1 ;YES
PUSH PP,W1 ;SAVE STRNG OPERATOR
MOVNI W1,2 ;STORE [-2 + 0] ON EOPTAB
PUSHJ PP,PUSH%T
POP PP,W1 ;RESTORE STRNG OPERATOR
COMMENT \
ALL OPERANDS AND OPERATORS FOR THE STRING HAVE BEEN READ IN.
EOPTAB NOW LOOKS LIKE:
SENDING ITEM 1.1
SENDING ITEM 1.2
...
SENDING ITEM 1.I
DELIMITER 1 (NOT PRESENT IF DELIMITED BY SIZE)
[-1 + W1]
SENDING ITEM 2.1
SENDING ITEM 2.2
...
SENDING ITEM 2.J
DELIMITER 2 (NOT ...)
[-1 + W1]
...
SENDING ITEM K.1
SENDING ITEM K.2
...
SENDING ITEM K.L
DELIMITER K (NOT ...)
[-1 + W1]
RECEIVING ITEM
POINTER ITEM (OR [-2 + 0] IF THERE WAS NO POINTER ITEM)
\
STRG1: SWOFF FEOFF1 ;TURN OFF MOST FLAGS
SETZM STFLGS ; CLEAR FLAGS
SETZM STSSO ;STRING SOURCE-SERIES OFFSET IN TEMTAB
SETZM STPTO ; POINTER ITEM
SETZM STSETP ;PTR TO FIRST SS ENTRY
;CLEAR OUT TEMTAB
MOVE TE,TEMLOC
AOBJN TE,.+1 ;PRETEND 0 ENTRY IS USED
MOVEM TE,TEMNXT
; ARGSTR NOW POINTS TO THE RECEIVING ITEM IN EOPTAB.
;(NOT THE POINTER ITEM, BECAUSE IT WAS USED TO HOLD THE "NEXT LOCATION"
;IN EOPTAB, AND WASN'T UPDATED AFTER THE LAST ARG WAS STORED)
HRRZ TC,ARGSTR ;GET ABS ADDRESS OF RECEIVING ITEM
MOVEM TC,CUREOP ;SAVE IT
HRLM TC,OPERND ;FOR NB1PAR AND SUBSCA
HRRZI TA,(TC) ; MAKE RELATIVE ADDRESS
HRRZ TB,EOPLOC
SUBI TA,(TB)
MOVEM TA,ARGSTR ;SAVE REL. ADDRESS IN ARGSTR
MOVE TB,(TC) ;MAKE SURE RECEIVING ITEM ISN'T
TLNN TB,GNLIT!GNFIGC ; A LITERAL OR FIGURATIVE CONSTANT
JRST STRG2 ;NO, OK
$CERR ;? SYNTAX SCAN SHOULD HAVE GOT IT
;CUREOP (AND "TC") POINTS TO THE RECEIVING ITEM.
STRG2: PUSHJ PP,SETOPA ;SET IT UP AS OPERAND "A"
; IF ERRORS, RETURN TO PHASE E DRIVER
TSWF FANUM ;IF NUMERIC,
JRST STRE1 ;IT'S AN ERROR
;SETUP BSI OF RECEIVING ITEM
HRRZ TE,EMODEA ;GET MODE
CAILE TE,DSMODE ; HAS TO BE DISPLAY IF NON-NUMERIC!
$CERR ;? IMPOSSIBLE ERROR
MOVEM TE,SDSTIN ;STRING DESTINATION INFO
HRRZ TA,ETABLA ;CAN'T BE JUSTIFIED
PUSHJ PP,LNKSET
LDB TE,DA.JST
JUMPN TE,STRE5 ; GO COMPLAIN
LDB TE,DA.EDT ;OR EDITED
JUMPN TE,STRE5
;THE RECEIVING ITEM IS IN "A". IT IS OK.
; (FALL INTO CODE ON NEXT PAGE)
;GENERATE CODE TO STORE BP IN DST.BP, CC IN DST.CC
PUSHJ PP,NB1PAR ;GET BP TO "A" IN AC5
TSWF FERROR
POPJ PP, ;ERRORS, RETURN
;GEN CODE TO STORE BP: "MOVEM AC5,DST.BP"
MOVE CH,[MOVEM.+AC5,,DST.BP##]
PUSHJ PP,PUT.EX
;GEN CODE TO STORE CC
PUSHJ PP,DEPTSA ;DOES "A" HAVE A DEPENDING ITEM?
JRST STRG3 ;NO, GENERATE "MOVEI" TO GET SIZE
MOVEI TE,7 ;USE AC7 TO GET SIZE
SETZM SAVPR0 ;DON'T HAVE TO SAVE %PARAM
PUSHJ PP,SZDPVA ;GET SIZE IN RUNTIME AC7
$CERR ;?? ERRORS.. IMPOSSIBLE
JRST STRG4 ;SKIP OVER "MOVEI"
STRG3: PUSHJ PP,GTCCA ;GEN "MOVEI AC7,SIZE OF A"
;NOW SIZE IS IN AC7, MOVE IT TO DST.CC
STRG4: MOVE CH,[MOVEM.+AC7,,DST.CC##]
PUSHJ PP,PUT.EX
;STORE MAX SIZE IN LH (SDSTIN)
HRRZ TE,ESIZEA
HRLM TE,SDSTIN
;WE ARE NOW DONE WITH THE DESTINATION (RECEIVING) ITEM
; GO ON TO THE POINTER ITEM
;SETUP POINTER ITEM
HRRZ TA,ARGSTR ;POINTER TO RECEIVING ITEM
ADD TA,EOPLOC ;IT WAS RELATIVE, MAKE IT ABSOLUTE
HRRZM TA,CUREOP ;AND CALL BMPEOP TO FIND START OF NEXT
PUSHJ PP,BMPEOP ; OPERAND
$CERR ;? MUST BE THERE (-2,,0) STORED
HRRZ TE,CUREOP ;NEW CUREOP (POINTS TO POINTER ITEM)
MOVE TD,(TE) ;GET 1ST WORD
CAMN TD,[-2] ; -2 MEANS NO POINTER ITEM
JRST STRG4B ;GO GEN CODE TO PUT 1 IN PT.VAL
;MAKE ARGSTR POINT TO REL ADDRESS OF THE "POINTER" ITEM..
HRRZ TD,EOPLOC ;START
SUBI TE,(TD)
MOVEM TE,ARGSTR
;THERE WAS A POINTER ITEM. CUREOP NOW POINTS TO IT.
HRRZ TC,CUREOP ;POINTER IN TC FOR SETOPA
MOVE TD,(TC)
TLNN TD,GNLIT!GNFIGC
JRST STRG4A ;NOT LIT OR FIG. CONST--OK
$CERR ;?SYNTAX SCAN SHOULD CATCH THIS
;HERE WITH TC POINTING TO THE "POINTER" ITEM
STRG4A: PUSHJ PP,SETOPA ;SET IT UP AS "A"
; (ERRORS RETURN TO PHASE E DRIVER).
TSWF FANUM ;POINTER MUST BE NUMERIC
SKIPE EDPLA ; AND CAN'T HAVE DECIMAL PLACES
JRST STRE2 ;ELSE COMPLAIN AND QUIT
HRRZ TA,EMODEA
CAIN TA,FPMODE ;DISALLOW FLOATING POINT
JRST STRE2
PUSHJ PP,STRGT3 ;GIVE ERROR IF THE "POINTER" ITEM IS EDITED
; (STILL IN STRG4.. CODE - HANDLING POINTER ITEM)
;MAKE SURE IT IS BIG ENOUGH TO BE A POINTER ITEM FOR THIS RECEIVING ITEM
PUSHJ PP,STRT4P ;MAKE TEST
;REMEMBER THERE WAS A POINTER ITEM
STRG4C: MOVEI TE,1B18 ;"POINTER ITEM"
IORM TE,STFLGS ; SET IT IN THE FLAGS
;GET ALL SUBSCRIPTS FOR POINTER ITEM INTO %TEMP
SETOM ONLYEX ;JUST EXAMINE
SETOM ALSTMP ; EVEN COMP SUBSCRIPTS INTO %TEMP
HRRZ TC,CUREOP ;SUBSCA EXPECTS THE "A" OPERAND
HRLM TC,OPERND ; IN LH (OPERND)
PUSHJ PP,SUBSCA
SETZM ONLYEX ;CLEAR FLAGS THAT SUBSCR DOESN'T BOTHER TO
SETZM ALSTMP
TSWF FERROR ;ERRORS?
POPJ PP, ;YES, RETURN
; NOW ALL SUBSCRIPTS ARE IN %TEMP SO THEY WON'T BE AFFECTED BY THE STRING STMT.
;IF THE POINTER ITEM WASN'T SUBSCRIPTED, NO CODE HAS BEEN GENERATED
;BY THE CALL TO SUBSCA ABOVE.
;
;NOTE THAT DEPENDING ITEMS ARE NOT A PROBLEM SINCE THE POINTER ITEM
;IS NUMERIC.
;LOOKING AT POINTER ITEM
;COPY OPERAND TO TEMTAB SO WE CAN GET IT LATER
HRRZ TE,ARGSTR ;REL ADDRESS OF POINTER ITEM
ADD TE,EOPLOC ;GET ABS LOC OF OPERAND
HRRZ TC,TE
MOVE TE,1(TC) ;HOW MANY SUBSCRIPTS AND STUFF TO FOLLOW?
LDB TA,TESUBC
LSH TA,1 ;= THIS MANY WORDS
ADDI TA,2 ;PLUS TWO FOR THE BASE OPERAND
PUSH PP,TA ;SAVE # WORDS TO COPY
PUSHJ PP,GETTEM ; GET THE WORDS IN TEMTAB
HRRZ TB,TA ;TA RETURNED BY GETTEM,
; = REL LOC OF ENTRY IN TEMTAB
HRRM TA,STPTO ; REMEMBER WHERE THE POINTER OPERAND WILL GO
ADD TA,TEMLOC ;MAKE TA BE ABS LOC
;COPY OPERAND TO TEMTAB
POP PP,TD ;TD:= # WORDS TO COPY
HRRZ TB,ARGSTR ; START OF OPERAND IN EOPTAB
ADD TB,EOPLOC
PUSHJ PP,COPYOP ;COPY THE OPERAND
;POINTER ITEM'S OPERAND IS NOW IN TEMTAB.
; NOW RH (STPTO) = REL ADDRESS IN TEMTAB OF THE OPERAND
; LH (STPTO) = 0
;NOW GENERATE CODE TO PUT INITIAL VALUE OF POINTER INTO PT.VAL
SWON FBSIGN ;MAKE PT.VAL A COMP SIGNED FIELD
SWOFF FBSUB ;NOT SUBSCRIPTED
MOVE TE,[^D36,,PT.VAL##]
MOVEM TE,EBASEB
SETZM EINCRB
MOVEI TE,D1MODE ;1-WORD COMP
MOVEM TE,EMODEB
SETZM EFLAGB
SETZM ETABLB
SETZM EBYTEB
SETZM EDPLB
HRRZ TE,ESIZEA ;SAME SIZE
CAILE TE,^D10 ;UNLESS > 10.
MOVEI TE,^D10 ; IN WHICH CASE, WE WILL TRUNCATE TO 10
HRRZM TE,ESIZEB
PUSHJ PP,MXX. ;MOVE "A" TO "B"
TSWF FERROR ;IF ERRORS,
POPJ PP, ;GIVE UP NOW
;GET A TAG WHICH WILL BE ADDRESS OF ROUTINE TO CALL TO STORE NEW POINTER
; VALUE. THE CODE FOR THIS ROUTINE WILL BE GENERATED LATER ON.
PUSHJ PP,GETTAG ;RETURNS TAG IN "CH"
HRLM CH,STPTO ;STORE TAG IN LH(STPTO)
;NOW RH (STPTO) = REL ADDRESS IN TEMTAB OF POINTER ITEM OPERAND
; LH (STPTO) = TAG OF ROUTINE TO CALL TO STORE POINTER VALUE.
JRST STRG5 ;DONE WITH POINTER ITEM (FOR NOW)
;HERE IF THERE WAS NO POINTER ITEM.. GEN CODE TO
; STORE VALUE OF 1 IN PT.VAL.
STRG4B: MOVE CH,[MOVEI.+0,,1]
PUSHJ PP,PUTASY ;"MOVEI 0,1"
MOVE CH,[MOVEM.+0,,PT.VAL##]
PUSHJ PP,PUT.EX ;"MOVEM 0,PT.VAL"
;HERE WHEN DONE WITH POINTER ITEM
STRG5: HRRZ TE,EOPLOC ;START AT THE TOP NOW
ADDI TE,1 ;POINT TO FIRST OPERAND IN EOPTAB
SETZM NSTRSE ;COUNT # OF STRING-SERIES FOUND
;HERE WITH TE POINTING TO EITHER START OF EOPTAB
; OR JUST AFTER THE SDELIM OPERATOR FOR THE LAST
; STRING-SERIES WE PROCESSED.
;FIND SDELIM OPERATOR IF WE CAN, IF THERE ARE NO MORE, EXIT THIS LOOP
STRG6: MOVEM TE,STSEST ;SAVE START OF THIS STRING SERIES
MOVEM TE,STSELS ;SO FAR, THIS IS THE LAST OPERAND IN THIS
; STRING SERIES
SETZM STSENS ;COUNT NUMBER OF SOURCES
MOVEM TE,CUREOP ;READY TO CALL BMPEOP TO FIND THE END
STRG6A: PUSHJ PP,BMPEOP ; GET NEXT ITEM..
JRST STRG77 ;NO MORE, EXIT LOOP
AOS STSENS ;ASSUME WE'VE SEEN ANOTHER SOURCE
; THIS COULD BE A DELIMITER, HOWEVER, IN
; WHICH CASE WE'LL HAVE TO REMEMBER TO
; SUBTRACT ONE FROM THIS COUNTER!
HRRZ TC,CUREOP ;CHECK THIS ITEM OUT
MOVE TD,(TC) ;GET 1ST WORD
CAMN TD,[-1] ; ARE WE AT (-1 + W1) OPERAND?
JRST STRG7 ;YES -- FOUND END OF STRING SERIES
MOVEM TC,STSELS ;SAVE LAST OPERAND IN THE STRING SERIES
JRST STRG6A ;GO GET THE REST, IF ANY
;HERE WHEN WE REACHED THE END OF THE "STRING SERIES"
;CUREOP POINTS TO THE (-1 + W1) ENTRY
STRG7: AOS NSTRSE ;COUNT ANOTHER STRING-SERIES
;AT STRG6 WE STORED THE ABS. LOCATIONS OF "NEXT OPERAND" (STSENX),
; "LAST OPERAND" (STSELS), AND "STARTING OPERAND" (STSEST). NOW WE
; WILL CONVERT THEM TO RELATIVE ADDRESSES SO EXPANDING TABLES WILL
; NOT CAUSE COMPILER BUGS.
;SAVE REL ADDRESS OF START OF NEXT "STRING-SERIES"
HRRZ TD,CUREOP ;GET REL ADDR TO SAVE BEFORE THIS EXPAND
ADDI TD,2 ;NEXT ONE STARTS JUST PAST THE (-1+W1) WORDS
HRRZ TE,EOPLOC
SUBI TD,(TE) ;TD:= OFFSET INTO EOPTAB
MOVEM TD,STSENX ;LOC OF NEXT "STRING-SERIES"
;SAVE REL ADDRESS OF START OF THIS STRING SERIES
HRRZ TD,STSEST
SUBI TD,(TE)
MOVEM TD,STSEST
;SAVE REL ADDRESS OF LAST OPERAND IN THIS STRING SERIES
HRRZ TD,STSELS
SUBI TD,(TE)
MOVEM TD,STSELS
;MAKE AN ENTRY IN TEMTAB FOR THIS STRING-SERIES
; (TO SEE THE FORMAT OF THE TEMTAB ENTRY, GO TO AN EARLY PAGE IN
;THE LISTING OF STRGEN).
;THE FIRST THING IS TO GET A TEMTAB ENTRY FOR THE STRING-SERIES.
; LOOK AT THE DELIMITER TO SEE HOW BIG THE ENTRY HAS TO BE.
HRRZ TC,CUREOP ;LOOK AT W1 TO SEE IF THERE WAS A DELIMITER
MOVE TD,1(TC)
TXNN TD,1B9 ;DELIMITED BY SIZE?
JRST STRG8 ;NO, REAL DELIMITER
;DELIMITED BY SIZE, DON'T HAVE TO STORE AN OPERAND IN TEMTAB
MOVEI TA,.SSHLN ;JUST FIXED SIZE
PUSHJ PP,TLNKSS ;LINK TO LAST SS ENTRY
;NOW CURSSE POINTS TO THE ENTRY WE'VE JUST GOT
HRRZ TA,CURSSE
ADD TA,TEMLOC ;;RH (TA) = ABS POINTER TO ENTRY
;SET FLAG SAYING "DELIMITED BY SIZE"
MOVX TB,SS%DLS
IORM TB,.SSFLG(TA)
;ALL DONE WITH DELIMITER, GO HANDLE SOURCES
JRST STRG9
;HERE IF THERE WAS A REAL DELIMITER. CHECK IT OUT AND
; FIND # WORDS FOR ENTRY IN TEMTAB.
;WE WILL SET CUREOP TO POINT TO THE DELIMITER AND SET IT UP AS "A".
STRG8: SOS STSENS ;FIX COUNTER TO REALLY BE # SOURCES
HRRZ TE,STSELS ;LAST OPERAND WAS THE DELIMITER
ADD TE,EOPLOC ;GET ABS. ADDRESS
HRRZM TE,CUREOP ;TELL PHASE E ROUTINES WHAT WE ARE
HRLM TE,OPERND ; LOOKING AT
MOVE TE,(TE)
TLNE TE,GNLIT!GNFIGC ;LITERAL OR FIG CONST?
JRST STRG8D ;YES
HRRZ TC,CUREOP ;POINT TO THE OPERAND
PUSHJ PP,SETOPA ;SET UP DELIMITER IN "A", IF ERRORS,
; RETURN TO PHASE E DRIVER
LDB TE,[POINT 3,ETABLA,20]
CAIN TE,TB.MNE## ;SYMBOLIC-CHARACTER?
JRST STRG8S ;YES
TSWT FANUM ;IS THE DELIMITER NUMERIC?
JRST STRG8A ;NO
;IF NUMERIC, THE DELIMITER MUST BE AN INTEGER
HRRZ TE,EMODEA
CAIE TE,FPMODE
SKIPE EDPLA
JRST STRE6
;NUMERIC DELIMITER LOOKS GOOD. WE WILL HAVE TO COPY THE OPERAND
; TO TEMTAB ENTRY, SO FIGURE OUT HOW BIG THE ENTRY HAS TO BE AND CREATE IT.
HRRZ TC,CUREOP ;THE DELIMITER OPERAND
MOVE TE,1(TC) ;HOW MANY SUBSCRIPTS?
LDB TA,TESUBC
LSH TA,1
ADDI TA,2 ;+2 WORDS FOR BASE ITEM
PUSH PP,TA ;SAVE # WORDS IN OPERAND
ADDI TA,.SSHLN ;ADD WORDS FOR REST OF SS ENTRY
PUSHJ PP,TLNKSS ; GET AN SS ENTRY AND PUT IN LINKED LIST
HRRZ TA,CURSSE ;ENTRY WE'VE JUST CREATED
ADD TA,TEMLOC ;GET ABS PTR TO IT
ADDI TA,.SSOPR ;POINT TO THE RIGHT PLACE
;COPY THE OPERAND
HRRZ TB,STSELS ;FIND DELIMITER OPERAND AGAIN
ADD TB,EOPLOC ; BEING CAREFUL BECAUSE IT MAY HAVE MOVED
POP PP,TD ;TD:= # WORDS IN OPERAND
PUSHJ PP,COPYOP ;COPY IT..
;SET "OPERAND IS NUMERIC" FLAG
HRRZ TA,CURSSE
ADD TA,TEMLOC
MOVX TE,SS%DNM ;"NUMERIC DELIMITER"
IORM TE,.SSFLG(TA) ; SET THE FLAG
;GET A TAG WHICH WILL BE ROUTINE TO CALL TO SETUP
; TMP.DL, DLM.CC, AND DLM.BP. THE CODE FOR THIS ROUTINE
; WILL BE GENERATED LATER
PUSHJ PP,GETTAG ;RETURN AS.TAG+N IN CH
HRRZ TA,CURSSE
ADD TA,TEMLOC
DPB CH,TAG.DL ;STORE TAG
JRST STRG9 ;DONE WITH DELIMITER, GO HANDLE SOURCES
;HERE FOR NON-NUMERIC DELIMITER
; IT HAS BEEN SETUP IN "A". WE KNOW IT IS NOT A LITERAL OR FIG CONST.
; THEREFORE IT HAS TO BE SOME KIND OF DISPLAY.
STRG8A: HRRZ TE,EMODEA ;MAKE SURE
CAILE TE,DSMODE
$CERR ;? IMPOSSIBLE!
;FOR NORMAL DATANAMES, WE DON'T HAVE TO COPY THE OPERAND TO TEMTAB.
; (JUST GENERATE %LIT00 POINTER TO BP AND CC).
; HOWEVER, IF IT'S SUBSCRIPTED OR HAS A DEPENDING VARIABLE, WE HAVE
; TO STORE THE OPERAND IN TEMTAB.
;NOTE: SUBSCRIPTS MUST NOT BE PUT INTO %TEMP AT THIS POINT!!!
; ACTUALLY WE WOULD LIKE TO CATCH ALL CONSTANT SUBSCRIPTS,
;BUT THE SUBSCR ROUTINE CAN'T DO IT WITHOUT PUTTING THINGS INTO %TEMP
; (THIS MIGHT BE A GOOD THING TO ENHANCE!)
PUSHJ PP,DEPTSA ;DOES "A" HAVE A DEPENDING VARIABLE?
TSWF FASUB ; NO, BUT IT IS SUBSCRIPTED?
JRST STRG8C ;YUP, HAVE TO COPY OPERAND!
MOVEI TA,.SSHLN ;JUST MAKE THE FIXED-LENGTH ENTRY
PUSHJ PP,TLNKSS
HRRZ TA,CURSSE ;MAKE TA POINT TO ENTRY
ADD TA,TEMLOC ; WE'VE JUST CREATED
;STORE BSI.DELIM
HRRZ TE,EMODEA
DPB TE,BSI.DL
;GEN CODE TO STORE CC AND BP IN LITERALS
HRRZ TE,STSELS ;RESET CUREOP AND OPERND
ADD TE,EOPLOC ;JUST INCASE TLNKSS MADE TABLES EXPAND
HRRM TE,CUREOP
HRLM TE,OPERND
PUSHJ PP,GTLBPC ;GET LITERAL TO BP AND CC FOR "A"
;AS.LIT+N HAS BEEN RETURNED BY GTLBPC IN "TE"
HRRZ TA,CURSSE ;SETUP TA AGAIN TO POINT TO ENTRY
ADD TA,TEMLOC
DPB TE,SPT.DL ;STORE LOC OF 2-WORD BLOCK
JRST STRG9 ;DONE WITH DELIMITER
;HERE WHEN DELIM OPERAND MUST BE COPIED TO TEMTAB ENTRY
STRG8C: HRRZ TC,CUREOP
MOVE TE,1(TC) ;HOW MANY SUBSCRIPTS?
LDB TA,TESUBC
LSH TA,1 ; # WORDS
ADDI TA,2 ;+ 2 FOR BASE ITEM
PUSH PP,TA ;SAVE # WORDS IN THE OPERAND ITSELF
ADDI TA,.SSHLN ;GET # WORDS IN WHOLE TEMTAB SS ENTRY
PUSHJ PP,TLNKSS ;MAKE IT
HRRZ TA,CURSSE ;MAKE TA POINT TO ENTRY
ADD TA,TEMLOC
ADDI TA,.SSOPR ;POINT TO THE RIGHT PLACE
;COPY THE OPERAND
HRRZ TB,STSELS ;FIND IT AGAIN
ADD TB,EOPLOC
POP PP,TD ;TD:= # WORDS TO COPY
PUSHJ PP,COPYOP ;COPY IT..
;GET A TAG FOR ROUTINE TO CALL LATER
;THE ROUTINE WILL SETUP DLM.CC AND DLM.BP
PUSHJ PP,GETTAG ;CH RETURNED IS AS.TAG+N
HRRZ TA,CURSSE
ADD TA,TEMLOC ;TA POINTS TO TEMTAB ENTRY
DPB CH,TAG.DL ;STORE TAG IN ENTRY
;STORE BSI OF DELIMITER
HRRZ TE,EMODEA
DPB TE,BSI.DL
JRST STRG9 ;DONE WITH DELIMITER
;HERE IF DELIMITER IS A LITERAL OR FIG CONST.
STRG8D: HRRZ EACA,SDSTIN ;SET LIT TO MODE OF DESTINATION
; IF POSSIBLE
PUSHJ PP,SETLFC ;SETUP LITERAL OR FIG. CONST.
POPJ PP, ;ERRORS, RETURN
STRG8E: MOVEI TA,.SSHLN ;NEED FIXED-LENGTH TEMTAB ENTRY
PUSHJ PP,TLNKSS
HRRZ TA,CURSSE ;MAKE TA POINT TO CURRENT ENTRY
ADD TA,TEMLOC
;STORE BSI.DELIM
HRRZ TE,EMODEA ; = BSI.DEST
DPB TE,BSI.DL ;STORE BSI OF DELIMITER
;IF "ALL" WAS SPECIFIED, GIVE ERROR
HRRZ TC,STSELS ;FIND OPERAND AGAIN
ADD TC,EOPLOC
MOVE TE,0(TC)
TLNE TE,GNALL ;"ALL" SPECIFIED?
PUSHJ PP,[MOVEM TC,CUREOP ;PREPARE TO POINT TO LITERAL
MOVEI DW,E.273 ;"Improper use of ALL"
PUSHJ PP,OPNFAT
SWOFF FERROR ;TURN OFF "ERROR SEEN" FLAG
POPJ PP,] ;RETURN
;GEN BP AND CC
MOVE TA,[^D36,,AS.MSC] ;SETUP "A" TO POINT TO THE LITERAL
MOVEM TA,EBASEA
HRRZM EACC,EINCRA ;%LIT + N
PUSHJ PP,GTLBPC ;GET TE= PTR TO 2-WORD LITERAL
;STORE PTR TO THE BP AND CC IN THE STRING-SERIES TEMTAB ENTRY
HRRZ TA,CURSSE
ADD TA,TEMLOC
DPB TE,SPT.DL ;STORE %LIT POINTER
JRST STRG9 ;ALL DONE WITH DELIMITER, GO ON TO SOURCES
;HERE IF DELIMITER IS A SYMBOLIC-CHARACTER
STRG8S: HRRZ TA,ETABLA
PUSHJ PP,LNKSET ;POINT TO MNETAB
LDB EACC,MN.ESC## ;SEE IF EBCDIC SYMBOLIC CHAR
SKIPE EACC ;SKIP IF ASCII
SKIPA EACA,[D9MODE] ;ITS EBCDIC
MOVEI EACA,D7MODE ;MODE TO MAKE LITERAL
LDB EACC,MN.SCV## ;GET SYMBOLIC-CHARACTER
PUSHJ PP,SETLF2 ;SETUP THE LITERAL
POPJ PP, ;ERROR, SHOULD NEVER HAPPEN
JRST STRG8E ;COMMON CODE
;HERE WHEN ALL DONE WITH THE DELIMITER, HANDLE THE SOURCES
STRG9: SKIPG TE,STSENS ;# SOURCES.. AT LEAST ONE?
$CERR ;-- IT'S LIKELY THAT THIS SHOULD BE A POPJ --
;(PHASE D MAY HAVE PARSED IT INCORRECTLY BUT
; FAILED TO TURN OPERAND INTO A "YECCH")
MOVEM TE,M.ARG1 ;M.ARG1 = # SOURCES LEFT TO DO
;STORE # SOURCES IN THIS SS ENTRY
HRRZ TA,CURSSE
ADD TA,TEMLOC
DPB TE,NUM.SR ;STORE # SOURCES
;SETUP FOR INITIAL STRG10 LOOP
HRRZ TE,STSEST ;LOOK AT FIRST SOURCE
MOVEM TE,M.ARG2 ;M.ARG2 = REL EOPTAB PTR TO LAST SOURCE WE DID
SETZM CURSRE ;CLEAR "CURRENT SOURCE" ENTRY
;HERE TO LOOK AT NEXT SOURCE.. TE IS REL EOPTAB PTR OF IT
; M.ARG1 IS # SOURCES LEFT TO DO.
STRG10: ADD TE,EOPLOC ;LOOK AT THIS SOURCE
HRRM TE,CUREOP
HRLM TE,OPERND ;FOR NB1PAR
MOVE TE,(TE) ;LOOK AT FIRST WORD OF OPERAND
TLNE TE,GNLIT!GNFIGC ;LITERAL OR FIG CONST?
JRST STRG20 ;YES
HRRZ TC,CUREOP ;POINT TO THE OPERAND
PUSHJ PP,SETOPA ;SET UP SOURCE IN "A", IF ERRORS, RETURN
; TO PHASE E DRIVER
LDB TE,[POINT 3,ETABLA,20]
CAIN TE,TB.MNE## ;SYMBOLIC-CHARACTER?
JRST STRG25 ;YES
TSWT FANUM ;NUMERIC SOURCE?
JRST STRG15 ;NO
;SOURCE IS NUMERIC. IT MUST REPRESENT AN INTEGER
HRRZ TE,EMODEA
CAIE TE,FPMODE ;NO FLOATING POINT ALLOWED
SKIPE EDPLA
JRST STRE6 ;"MUST REPRESENT AN INTEGER"
SKIPGE EFLAGA ;IF SEP. SIGN,
JRST STRG15 ;TREAT AS NON-NUMERIC
;NUMERIC SOURCE LOOKS GOOD. WE WILL HAVE TO COPY THE OPERAND
; TO TEMTAB ENTRY, SO FIGURE OUT HOW BIG THE ENTRY HAS TO BE
; AND CREATE IT.
HRRZ TC,CUREOP ;THE SOURCE OPERAND
MOVE TE,1(TC)
LDB TA,TESUBC ;HOW MANY WORDS FOR SUBSCRIPTS?
LSH TA,1 ;TA: = THAT MANY
ADDI TA,2 ;+2 FOR THE BASE ITEM
PUSH PP,TA ;SAVE # WORDS IN OPERAND
ADDI TA,.SRHLN ;ADD WORDS FOR REST OF SOURCE ENTRY
PUSHJ PP,TLNKSR ; GET A SOURCE ENTRY AND PUT IN LINKED LIST
HRRZ TA,CURSRE ;ENTRY WE'VE JUST CREATED
ADD TA,TEMLOC ;TA:= ABS PTR TO IT
ADDI TA,.SROPR ;POINT TO THE RIGHT PLACE
;COPY THE OPERAND
HRRZ TB,M.ARG2 ;FIND SOURCE OPERAND
ADD TB,EOPLOC
POP PP,TD ;TD:= # WORDS IN OPERAND
PUSHJ PP,COPYOP ;COPY THE OPERAND
;SET "OPERAND IS NUMERIC" FLAG
HRRZ TA,CURSRE
ADD TA,TEMLOC
MOVX TE,SR%SRN ;"SOURCE IS NUMERIC"
IORM TE,.SRFLG(TA) ; SET THE FLAG
;GET A TAG WHICH WILL BE ROUTINE TO CALL TO SETUP
; SR.TMP, SRC.CC, AND SRC.BP. THE CODE FOR THIS
; ROUTINE WILL BE GENERATED LATER
PUSHJ PP,GETTAG ;RETURNS CH= AS.TAG+N
HRRZ TA,CURSRE
ADD TA,TEMLOC ;;GET TA:= PTR TO SOURCE ENTRY
DPB CH,TAG.SR ;STORE TAG
JRST STRG30 ;DONE WITH THIS SOURCE, GO ON TO NEXT ONE
;HERE FOR NON-NUMERIC SOURCE
STRG15: HRRZ TE,EMODEA ;MAKE SURE IT'S REALLY DISPLAY
CAILE TE,DSMODE
$CERR ;??? AAAAAH!
;THE SAME RULES APPLY AS FOR NON-NUMERIC DELIMITERS:
;1) SUBSCRIPTS MUST NOT BE PUT INTO %TEMP
;2) %TAG WILL BE USED IF SUBSCRIPTS OR DEPENDING VARIABLES
;3) %LIT00 POINTER WILL BE USED OTHERWISE
PUSHJ PP,DEPTSA ;DOES "A" HAVE A DEPENDING VARIABLE?
TSWF FASUB ; NO, BUT IS IT SUBSCRIPTED?
JRST STRG17 ;YUP, HAVE TO COPY OPERAND
MOVEI TA,.SRHLN ;JUST MAKE THE FIXED-LENGTH ENTRY
PUSHJ PP,TLNKSR ;LINK TO REST OF SOURCES
HRRZ TA,CURSRE ;MAKE TA POINT TO THIS ENTRY
ADD TA,TEMLOC
;STORE BSI.SOURCE
HRRZ TE,EMODEA
DPB TE,BSI.SR
;GEN CODE TO STORE CC AND BP IN LITERALS
HRRZ TE,M.ARG2 ;FIND SOURCE OPERAND AGAIN
ADD TE,EOPLOC
HRRM TE,CUREOP
HRLM TE,OPERND
PUSHJ PP,GTLBPC ;GET LITERAL TO BP AND CC FOR "A"
;AS.LIT+N HAS BEEN RETURNED BY GTLBPC IN "TE"
HRRZ TA,CURSRE ;SETUP TA AGAIN TO POINT TO SOURCE ENTRY
ADD TA,TEMLOC
DPB TE,SPT.SR ;STORE LOC OF 2-WORD BLOCK
JRST STRG30 ;DONE WITH THIS SOURCE
;HERE WHEN SOURCE OPERAND MUST BE COPIED TO SOURCE-ENTRY
;BECAUSE THERE WERE SUBSCRIPTS AND/OR DEPENDING ITEMS
STRG17: HRRZ TC,CUREOP
MOVE TE,1(TC) ;FIND # SUBSCRIPTS
LDB TA,TESUBC
LSH TA,1
ADDI TA,2 ;+2 FOR BASE ITEM
PUSH PP,TA ;SAVE # WORDS IN OPERAND
ADDI TA,.SRHLN ;GET TOTAL # WORDS IN TEMTAB ENTRY
PUSHJ PP,TLNKSR ; LINK TO OTHER SOURCE ENTRIES
HRRZ TA,CURSRE ;MAKE TA POINT TO ENTRY
ADD TA,TEMLOC
ADDI TA,.SROPR
;COPY THE OPERAND
HRRZ TB,M.ARG2 ;FIND IT AGAIN
ADD TB,EOPLOC
POP PP,TD ;TD:= # WORDS TO COPY
PUSHJ PP,COPYOP ;COPY IT..
;GET A TAG FOR ROUTINE TO CALL LATER
; THE ROUTINE WILL SET UP SRC.CC AND SRC.BP
PUSHJ PP,GETTAG ;CH RETURNED IS AS.TAG+N
HRRZ TA,CURSRE
ADD TA,TEMLOC ;TA POINTS TO TEMTAB SOURCE ENTRY AGAIN
DPB CH,TAG.SR ;STORE TAG IN ENTRY
;STORE BSI OF SOURCE
HRRZ TE,EMODEA
DPB TE,BSI.SR
JRST STRG30 ;DONE WITH THIS SOURCE
;HERE IF SOURCE IS LITERAL OR FIG CONST.
STRG20: HRRZ TA,CURSSE
ADD TA,TEMLOC ;POINT TO CURRENT SS ENTRY
MOVE TE,.SSFLG(TA) ;GET FLAG WORD
TXNE TE,SS%DLS ;IF DELIMITED BY SIZE,
SKIPA EACA,SDSTIN ; USE DESTINATION MODE
LDB EACA,BSI.DL ;OTHERWISE USE DELIMITER MODE
PUSHJ PP,SETLFC ;SETUP LITERAL OR FIG. CONST.
POPJ PP, ;ERRORS, RETURN
STRG21: MOVEI TA,.SRHLN ;;NEED SMALL FIXED-LENGTH TEMTAB ENTRY
PUSHJ PP,TLNKSR
HRRZ TA,CURSRE ;;MAKE TA POINT TO THE ENTRY
ADD TA,TEMLOC
;STORE BSI.SOURCE
HRRZ TE,EMODEA ;;WILL BE = BSI.DEST
DPB TE,BSI.SR
;DON'T ALLOW "ALL 'LITERAL' "
HRRZ TC,M.ARG2 ;FIND OPERAND AGAIN
ADD TC,EOPLOC
MOVE TE,0(TC)
TLNE TE,GNALL ;"ALL" SPECIFIED?
PUSHJ PP,[MOVEM TC,CUREOP ;YES, POINT TO LITERAL
MOVEI DW,E.273 ;"Improper use of ALL"
PUSHJ PP,OPNFAT ;GIVE ERROR
SWOFF FERROR ;TURN OFF ERROR FLAG
POPJ PP,] ;AND GO CATCH SOME MORE IF WE CAN
;GEN BP AND CC
MOVE TA,[^D36,,AS.MSC] ;SETUP "A" TO POINT TO THE LITERAL
MOVEM TA,EBASEA
HRRZM EACC,EINCRA
PUSHJ PP,GTLBPC ;GET TE= PTR TO 2-WORD LITERAL
;STORE PTR TO THE BP AND CC IN THE SOURCE TEMTAB ENTRY
HRRZ TA,CURSRE
ADD TA,TEMLOC ;TA POINTS TO ENTRY
DPB TE,SPT.SR ;STORE %LIT PTR.
JRST STRG30 ;ALL DONE WITH THIS SOURCE
;HERE IF SOURCE IS A SYMBOLIC-CHARACTER
STRG25: HRRZ TA,ETABLA
PUSHJ PP,LNKSET ;POINT TO MNETAB
LDB EACC,MN.ESC## ;SEE IF EBCDIC SYMBOLIC CHAR
SKIPE EACC ;SKIP IF ASCII
SKIPA EACA,[D9MODE] ;ITS EBCDIC
MOVEI EACA,D7MODE ;MODE TO MAKE LITERAL
LDB EACC,MN.SCV## ;GET SYMBOLIC-CHARACTER
PUSHJ PP,SETLF2 ;SETUP THE LITERAL
POPJ PP, ;ERROR, SHOULD NEVER HAPPEN
JRST STRG21 ;COMMON CODE
;HERE WHEN DONE PROCESSING A SOURCE.. BUMP PTR AND LOOP FOR THE REST.
STRG30: SOSG M.ARG1 ;DONE WITH SOURCES?
JRST STRG40 ;YES
HRRZ TC,M.ARG2 ;NO, CALL BMPEOP TO GET TO NEXT ONE
ADD TC,EOPLOC
HRRM TC,CUREOP
PUSHJ PP,BMPEOP
$CERR ;?? CANT HAPPEN
HRRZ TE,CUREOP
HRRZ TD,EOPLOC
SUBI TE,(TD) ;GET TE: = REL LOC OF NEXT OPERAND
MOVEM TE,M.ARG2 ;REMEMBER IT
JRST STRG10 ;GO DO NEXT SOURCE
;HERE WHEN DONE PROCESSING THIS STRING-SERIES
STRG40: MOVE TE,STSENX ;AFTER -1+W1
HRRZ TD,EOPLOC
ADD TE,TD ;GET TE= ABS POINTER TO START OF NEXT SS
JRST STRG6 ;GO PROCESS NEXT SS
;HERE WHEN ALL STRING-SERIES HAVE BEEN PROCESSED.
STRG77: SKIPN NSTRSE ;THERE MUST BE AT LEAST ONE STRING-SERIES..
$CERR ; NO, THIS IS IMPOSSIBLE (PROBABLY PHASE D BUG)
;** ALL ARGS ARE NOW SETUP IN TEMTAB **
;NOW WE CAN START GENERATING ROUTINES.
; USE M.ARG1 AS A FLAG. = 0 UNTIL JUMP HAS BEEN GENERATED AROUND THE
;; %TAGS. THEN IT IS AS.TAG+N FOR THE PLACE TO GO.
SETZM M.ARG1 ;NO JUMP GENERATED YET
;DO THE POINTER ITEM
HLRZ CH,STPTO ;ANY POINTER ITEM?
JUMPE CH,STRG80 ;JUMP IF NONE
PUSHJ PP,PUTJMP ;PUT JRST OVER ROUTINE (WILL BE NECESSARY)
HLRZ CH,STPTO ;GET TAG FOR THE ROUTINE
HRRZ TA,CH ;GET IN TA ALSO
PUSHJ PP,REFTAG ;REFERENCE IT SO /O DOESN'T DELETE IT
PUSHJ PP,PUTTAG ;PUT IT OUT
;GEN A MOVE FROM PT.VAL TO THE POINTER ITEM.
; WE WILL SET UP POINTER ITEM AS "B".
HRRZ TC,STPTO ;GET OFFSET INTO TEMTAB OF THE OPERAND
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OP TO TEMP AREA
HRRM TC,CUREOP ;SETUP CUREOP TO POINT TO IT
HRRM TC,OPERND
PUSHJ PP,SETOPB ;SET IT UP AS "B" OPERAND
PUSHJ PP,FAKPTV ;FAKE AN "A" OPERAND TO BE PT.VAL
PUSHJ PP,MXX. ;MOVE "A" TO "B"
TSWF FERROR ;IF ERRORS,
POPJ PP, ;GIVE UP
PUSHJ PP,PUTPPJ ;GENERATE "POPJ" TO FINISH THE ROUTINE
; JRST STRG80 ;DONE WITH POINTER
;HERE WHEN DONE WITH POINTER
;LOOK AT EACH SS TO DO DELIMITER AND SOURCES
STRG80: HRRZ TA,STSETP ;START WITH FIRST SS
;HERE WITH TA:= REL ADDRESS IN TEMTAB OF NEXT SS ENTRY TO DO
STRG81: MOVEM TA,CURSSE ;CURSSE WILL POINT TO CURRENT SS ENTRY
ADD TA,TEMLOC
LDB CH,TAG.DL ;IS THERE A %TAG TO DELIMITER?
JUMPE CH,STRG85 ; JUMP IF NO
;PUT OUT DELIMITER CODE
PUSH PP,CH
PUSHJ PP,PUTJMP ;PUT JRST OVER ROUTINE (IF NECESSARY)
POP PP,CH ;RESTORE OUR TAG
HRRZ TA,CH ;REFERENCE TAG
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;AND PUT IT OUT
HRRZ TA,CURSSE ;MAKE TA POINT TO CURRENT ENTRY
ADD TA,TEMLOC ; AGAIN
LDB TD,BSI.DL ;GET BSI OF DELIMITER
MOVEM TD,M.ARG3 ; PUT IN ARG3 FOR A LITTLE WHILE
MOVX TD,SS%DNM ;WAS DELIMITER NUMERIC?
TDZN TD,.SSFLG(TA)
JRST STRG83 ;NO
;FALL -- DELIMITER WAS NUMERIC
;STILL IN STRG81 ROUTINE.. GENERATING CODE FOR NUMERIC DELIMITER
;GEN CODE TO MOVE IT TO TMP.DL.
HRRZ TC,CURSSE ;PREPARE TO POINT TO OPERAND
ADD TC,TEMLOC
ADDI TC,.SSOPR
PUSHJ PP,CPYOPP ;COPY OPERAND TO SAFE PLACE
HRRM TC,CUREOP ;POINT TO IT
HRLM TC,OPERND ;SET IT UP AS "A"
HRRZ TC,CUREOP ;TC POINTS TO OPERAND FOR "SETOPA"
PUSHJ PP,SETOPA ;IF ERRORS, RETURNS TO PHASE E DRIVER
;SETUP "B" AS TMP.DL
MOVE TE,[^D36,,TMP.DL##]
MOVEM TE,EBASEB
SETZM EINCRB
SWON FBNUM ;THIS TEMP IS NUMERIC! (LEADING 0'S)
SWOFF FBSUB!FBSIGN ;NOT SUBSCRIPTED, OR SIGNED
HRRZ TE,M.ARG3 ;MODE
HRRZM TE,EMODEB
HRRZ TE,ESIZEA ;SAME SIZE AS "A"
HRRZM TE,ESIZEB
SETZM EDPLB ;NO DECIMAL PLACES (S.B. NONE IN "A" EITHER!)
SETZM ETABLB
SETZM EFLAGB
SETZM EBYTEB
PUSHJ PP,MXX. ;GENERATE MOVE
TSWF FERROR ;IF ERRORS,
POPJ PP, ;QUIT
;NOW CODE HAS BEEN GENERATED TO MOVE THE DELIMITER TO THE NUMERIC TEMP.
; WE STILL MUST GENERATE THE STORE OF THE BP AND CC, THEN THIS
;GENERATED SUBROUTINE WILL BE COMPLETE.
;STILL IN STRG81 ROUTINE.. GENERATING CODE FOR NUMERIC DELIMITER
;STORE BP AND CC
MOVE TA,[BYTLIT,,2] ;FIRST MAKE LITERAL BP TO THE ITEM
PUSHJ PP,STASHP
MOVEI TA,TMP.DL## ;POINTING TO TMP.DL
PUSHJ PP,STASHQ
MOVSI TA,440000 ;PARTIAL BYTE PTR
HRRZ TC,EMODEB
MOVE TC,BYTE.S(TC) ;BITS/BYTE
DPB TC,[POINT 6,TA,11] ;STORE IN BP
PUSHJ PP,POOLIT ;PUT OUT REST OF BP AND POOL IT
SKIPE PLITPC ;SKIP IF IT WASN'T POOLED
JRST .+3 ;WAS--GET PLITPC
HRRZ TE,ELITPC ;GET PC
AOSA ELITPC ;BUMP IT AND SKIP
HRRZ TE,PLITPC ; WAS POOLED
IORI TE,AS.LIT ;POINTER TO LITERAL IN TE
MOVE CH,[MOV+AC0+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,TE
PUSHJ PP,PUTASN ;GENERATE MOVE 0,[POINTER TO TMP.DL]
MOVE CH,[MOVEM.+AC0,,DLM.BP##]
PUSHJ PP,PUT.EX
;GENERATE STORE OF CC
HRRZ CH,ESIZEB
MOVEM CH,ESIZEA ;PUT SIZE IN "ESIZEA" FOR GTCCA
PUSHJ PP,GTCCA ;GENERATE "MOVEI AC7,SIZE"
MOVE CH,[MOVEM.+AC7,,DLM.CC##]
PUSHJ PP,PUT.EX ;"MOVEM AC7,DLM.CC"
JRST STRG84 ;DONE, GO GEN "POPJ"
;NON-NUMERIC DELIMITER. JUST STORE CC AND BP.
STRG83: HRRZ TC,CURSSE ;PREPARE TO POINT TO OPERAND
ADD TC,TEMLOC
ADDI TC,.SSOPR
PUSHJ PP,CPYOPP ;MOVE OPERAND TO SAFE PLACE
HRRM TC,CUREOP
HRLM TC,OPERND ;FOR NB1PAR
PUSHJ PP,SETOPA ;SET IT UP AS "A"
; (ERRORS RETURN TO PHASE E DRIVER)
PUSHJ PP,NB1PAR ;GET BP TO "A" IN AC5
TSWF FERROR ;IF ERRORS,
POPJ PP, ;GIVE UP
;GEN CODE TO STORE BP: "MOVEM AC5,DLM.BP"
MOVE CH,[MOVEM.+AC5,,DLM.BP##]
PUSHJ PP,PUT.EX
;GEN CODE TO STORE CC
PUSHJ PP,DEPTSA ;DOES IT HAVE A DEPENDING VARIABLE?
JRST STRG86 ;NO, GENERATE "MOVEI" TO GET SIZE
MOVEI TE,7 ;USE AC7 TO GET SIZE
SETZM SAVPR0 ;DON'T HAVE TO SAVE %PARAM
PUSHJ PP,SZDPVA ;GET SIZE IN RUNTIME AC7
$CERR ;??ERRORS
JRST STRG87 ;SKIP OVER "MOVEI"
STRG86: PUSHJ PP,GTCCA ;GENERATE "MOVEI AC7,SIZE"
;NOW SIZE IS IN AC7, MOVE IT TO DLM.CC
STRG87: MOVE CH,[MOVEM.+AC7,,DLM.CC##]
PUSHJ PP,PUT.EX
STRG84: PUSHJ PP,PUTPPJ ;POPJ TO END ROUTINE
;HERE TO LOOK AT SOURCES
STRG85: HRRZ TA,CURSSE ;;GET LINK TO SOURCE ENTRIES
ADD TA,TEMLOC
SKIPN TA,.SSLKS(TA) ;GET LINK TO FIRST SOURCE ENTRY
$CERR ;??NOT SET UP
;HERE WITH TA POINTING TO NEXT SOURCE LINK.
; STORE IT IN CURSRE
STRG88: MOVEM TA,CURSRE ;STORE "CURRENT SOURCE ENTRY"
ADD TA,TEMLOC ;GET PTR TO IT
LDB CH,TAG.SR ;%TAG GENERATED?
JUMPE CH,STRG89 ;JUMP IF NO
;PUT OUT A ROUTINE FOR SOURCE ITEM
PUSH PP,CH
PUSHJ PP,PUTJMP ;PUT JRST OVER ROUTINE (IF NECESSARY)
POP PP,CH ;RESTORE OUR TAG
HRRZ TA,CH ;REFERENCE TAG
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;PUT IT OUT
HRRZ TA,CURSRE ;MAKE TA POINT TO CURRENT ENTRY
ADD TA,TEMLOC
LDB TD,BSI.SR ;GET BSI OF SOURCE
MOVEM TD,M.ARG3 ;PUT IN ARG3 FOR A LITTLE WHILE
MOVX TD,SR%SRN ;WAS SOURCE NUMERIC?
TDZN TD,.SRFLG(TA)
JRST STR88B ;NO
; FALL INTO CODE TO HANDLE NUMERIC SOURCE
;STILL IN STRG88 ROUTINE.. GENERATING CODE FOR NUMERIC SOURCE
;GEN CODE TO MOVE IT TO SR.TMP.
HRRZ TC,CURSRE ;POINT TO THE OPERAND
ADD TC,TEMLOC
ADDI TC,.SROPR
PUSHJ PP,CPYOPP ;MOVE OPERAND TO A SAFE PLACE
HRRM TC,CUREOP ;TC AND CUREOP POINT TO THE OPERAND
HRLM TC,OPERND ;FOR SUBSCA
PUSHJ PP,SETOPA ;SET IT UP AS "A"
;SETUP "B" AS SR.TMP
MOVE TE,[^D36,,SR.TMP##]
MOVEM TE,EBASEB
SETZM EINCRB
SWON FBNUM ;NUMERIC TEMP
SWOFF FBSUB!FBSIGN ;NOT SUBSCRIPTED, OR SIGNED
HRRZ TE,M.ARG3 ;MODE
HRRZM TE,EMODEB
HRRZ TE,ESIZEA ;SAME SIZE AS "A"
HRRZM TE,ESIZEB
SETZM EDPLB ;NO DECIMAL PLACES
SETZM ETABLB ;ALL OTHER THINGS ZERO
SETZM EBYTEB
SETZM EFLAGB
PUSHJ PP,MXX. ;GENERATE MOVE
TSWF FERROR ;IF ERRORS,
POPJ PP, ;QUIT
;STILL IN STRG88 ROUTINE.. GENERATING CODE FOR NUMERIC SOURCE
;STORE BP AND CC
MOVE TA,[BYTLIT,,2]
PUSHJ PP,STASHP
MOVEI TA,SR.TMP## ;POINTER TO SR.TMP
PUSHJ PP,STASHQ
MOVSI TA,440000 ;BUILD REST OF BYTE PTR
HRRZ TC,EMODEB
MOVE TC,BYTE.S(TC) ;BITS/BYTE
DPB TC,[POINT 6,TA,11]
PUSHJ PP,POOLIT ;PUT OUT REST OF BP
SKIPE PLITPC ;WAS IT POOLED?
JRST .+3 ;YES
HRRZ TE,ELITPC ;NO, GET WHERE IT IS
AOSA ELITPC ;BUMP PC AND SKIP
HRRZ TE,PLITPC ;POOLED--GET PC
IORI TE,AS.LIT ;POINTER TO LITERAL IN TE
MOVE CH,[MOV+AC0+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,TE
PUSHJ PP,PUTASN ;GENERATE MOVE 0,[POINTER TO SR.TMP]
MOVE CH,[MOVEM.+AC0,,SRC.BP##]
PUSHJ PP,PUT.EX
;GENERATE STORE OF CC
HRRZ CH,ESIZEB ;HERE IT IS
HRRZM CH,ESIZEA ;STORE IN ESIZEA FOR GTCCA
PUSHJ PP,GTCCA ;"MOVEI AC7,SIZE"
MOVE CH,[MOVEM.+AC7,,SRC.CC##]
PUSHJ PP,PUT.EX
JRST STR88E ;GO PUT OUT THE "POPJ" TO END THE ROUTINE
;HERE FOR NON-NUMERIC SOURCE.
STR88B: HRRZ TC,CURSRE
ADD TC,TEMLOC
ADDI TC,.SROPR
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP ;TC AND CUREOP POINT TO THE OPERAND
HRLM TC,OPERND ;FOR NB1PAR
PUSHJ PP,SETOPA ;SET OPERAND AS "A"
; (IF ERRORS, RETURNS TO PHASE E DRIVER)
HRRZ TA,ETABLA ;[1365] GET ASSOCIATED DATA ITEM
LDB TE,LNKCOD ;[1365]
CAIE TE,TB.DAT ;[1365] IS IT IN DATAB?
JRST STR8BB ;[1365] NO, CONT
PUSHJ PP,LNKSET ;[1365] YES
LDB TE,DA.EDT ;[1365] IS IT EDITED?
JUMPE TE,STR8BB ;[1365] NO
LDB TE,DA.EXS ;[1365] YES,
MOVEM TE,ESIZEA ;[1365] USE EXTERNAL SIZE
STR8BB: ;[1365]
;STORE BP
PUSHJ PP,NB1PAR ;GET BP IN AC5
TSWF FERROR
POPJ PP, ;IF ERRORS, RETURN
MOVE CH,[MOVEM.+AC5,,SRC.BP##]
PUSHJ PP,PUT.EX
;STORE CC
PUSHJ PP,DEPTSA ;DOES IT HAVE A DEPENDING ITEM?
JRST STR88C ;NO, USE "MOVEI"
MOVEI TE,7 ;USE AC7
SETZM SAVPR0 ;DON'T SAVE %PARAM
PUSHJ PP,SZDPVA ;GET SIZE IN RUNTIME AC7
$CERR ;?ERRORS
JRST STR88D ;SKIP OVER "MOVEI"
STR88C: PUSHJ PP,GTCCA ;GEN "MOVEI AC7,SIZE"
;NOW SIZE OF SOURCE IS IN AC7
STR88D: MOVE CH,[MOVEM.+AC7,,SRC.CC##]
PUSHJ PP,PUT.EX ;STORE IN CC
;GEN "POPJ" TO END THE ROUTINE
STR88E: PUSHJ PP,PUTPPJ
; JRST STRG89 ;DONE WITH THE SOURCE ITEM
;HERE WHEN DONE A SOURCE ITEM. GO ON TO THE NEXT ONE IF THERE ARE ANY
STRG89: HRRZ TA,CURSRE
ADD TA,TEMLOC
SKIPE TA,.SRLNK(TA) ;ANOTHER ONE?
JRST STRG88 ;YES, GO PROCESS IT
;HERE WHEN DONE ALL SOURCE ITEMS FOR THIS SS. GO ON TO NEXT SS
; (IF THERE ARE ANY).
STR89A: HRRZ TA,CURSSE
ADD TA,TEMLOC
SKIPN TA,.SSLNK(TA) ;ANOTHER ONE?
JRST STR89B ;NO
JRST STRG81 ;YES, GO PROCESS IT
;HERE WHEN DONE GENERATING ALL ROUTINES.
; GENERATE %TAG IF NECESSARY TO START OFF STRING STMT.
STR89B: SKIPE CH,M.ARG1 ;"JRST" GENERATED?
PUSHJ PP,PUTTAG ;YES, GENERATE %TAG:
;GENERATE THE ARG LIST IN THE LITERALS
STRG90: HRRZ TE,ELITPC ;SET M.ARG4 TO POINT TO START OF
HRRZM TE,M.ARG4 ; LITERALS INCASE WE DON'T POOL
;FIRST WORD OF ARG LIST: XWD -N,,FLAGS
; WHERE N= NUMBER OF SOURCE-SERIES
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
MOVN TA,NSTRSE ;-# SOURCE-SERIES
HRLE TA,TA ;PUT IN LH
HRRI TA,AS.CNB ; LARGE CONSTANT
PUSHJ PP,STASHQ
HRL TA,STFLGS ;FLAGS IN RH (STFLGS)
HRRI TA,AS.CNB
PUSHJ PP,STASHQ ;PUT OUT RH OF XWD
AOS ELITPC
;2ND WORD OF ARG LIST: BSI.DEST
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
SETZ TA, ;LH= 0
PUSHJ PP,STASHQ
HRRZ TA,SDSTIN ;BSI OF DEST IS IN RH (SDSTIN)
PUSHJ PP,STASHQ
AOS ELITPC
;3RD WORD OF ARG LIST: (OPTIONALLY, IF POINTER ITEM GIVEN):
; %TAG TO ROUTINE THAT STORES THE POINTER ITEM VALUE.
SKIPN STPTO ;SKIP IF POINTER ITEM GIVEN
JRST STRG92 ; NO POINTER ITEM, DON'T WRITE 3RD WORD
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
SETZ TA,
PUSHJ PP,STASHQ
HLRZ TA,STPTO ;AS.TAG+N
PUSHJ PP,STASHQ ;NOTE: TAG REFERENCE MADE EARLIER
AOS ELITPC
;START WRITING SS ENTRIES
STRG92: MOVE TA,STSETP ;POINT TO FIRST SS ENTRY
STRG93: MOVEM TA,CURSSE ;SAVE PTR TO CURRENT SS
;FIRST WORD - OCT M (# OF SOURCES)
ADD TA,TEMLOC
LDB TE,NUM.SR ;GET # SOURCES
MOVEM TE,M.ARG3 ;;SAVE HERE FOR A SECOND
MOVE TA,[OCTLIT,,1]
PUSHJ PP,STASHP
HRRZ TA,M.ARG3
PUSHJ PP,STASHQ
AOS ELITPC
;NOW DELIMITER INFO.. FLAG+BSI.DEL,,%LIT00 OR 0
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
MOVE TA,CURSSE
ADD TA,TEMLOC
MOVE TE,.SSFLG(TA) ;GET THE WORD TO WRITE OUT
MOVEM TE,M.ARG3 ;SAVE FOR A SEC..
HLLZ TA,TE ;COPY LH = FLAGS & BSI.DEL
HRRI TA,AS.CNB
PUSHJ PP,STASHQ ;OUTPUT IT
HRLZ TA,M.ARG3 ;COPY RH = %LIT00 PTR
SKIPE TA ;UNLESS IT'S 0
HRRI TA,AS.MSC ;; SAY "MISC" ENTRY
PUSHJ PP,STASHQ ;OUTPUT THAT
AOS ELITPC
;MORE DELIMITER INFO.. %TAG OR 0
MOVE TA,CURSSE
ADD TA,TEMLOC
LDB TE,TAG.DL ;GET TAG FOR DELIMITER
JUMPE TE,STRG94 ;JUMP IF NONE
MOVEM TE,M.ARG3 ;SAVE TAG FOR A SEC.
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP ;WRITE AS AN XWD 0,%TAG
SETZ TA,
PUSHJ PP,STASHQ
HRRZ TA,M.ARG3
PUSHJ PP,STASHQ
JRST STRG95 ;SKIP OVER "NO TAG" CODE
STRG94: MOVE TA,[OCTLIT,,1] ;NO TAG, SO STORE "OCT 0"
PUSHJ PP,STASHP
SETZ TA,
PUSHJ PP,STASHQ
STRG95: AOS ELITPC
;NOW LOOP FOR SOURCES, WRITING OUT THE TWO WORDS FOR EACH:
; FLAGS+BSI.SOURCE,,%LIT OR 0
; %TAG OR 0
HRRZ TA,CURSSE
ADD TA,TEMLOC
LDB TE,NUM.SR ;GET # SOURCES
MOVEM TE,M.ARG2 ;M.ARG2= # SOURCES LEFT TO LOOK AT
SKIPN TA,.SSLKS(TA) ;GET LINK TO FIRST SOURCE
$CERR ;?? NONE, DIE
;HERE WITH TA POINTING TO THE NEXT SOURCE ENTRY
STRG96: MOVEM TA,CURSRE ;SAVE CURRENT SOURCE ENTRY
ADD TA,TEMLOC
MOVE TE,.SRFLG(TA) ;GET FLAG WORD
MOVEM TE,M.ARG3 ;SAVE HERE (IT WILL BE WRITTEN OUT)
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
HLLZ TA,M.ARG3 ;GET LH
HRRI TA,AS.CNB
PUSHJ PP,STASHQ ;WRITE IT OUT
HRLZ TA,M.ARG3 ;%LIT PTR
SKIPE TA ;UNLESS IT'S 0
HRRI TA,AS.MSC ; SAY "MISC" ENTRY
PUSHJ PP,STASHQ ;OUTPUT THAT
AOS ELITPC
;WRITE %TAG OR 0 FOR SOURCE ENTRY
HRRZ TA,CURSRE
ADD TA,TEMLOC
LDB TE,TAG.SR
JUMPE TE,STRG97 ;JUMP IF NO SOURCE TAG
MOVEM TE,M.ARG3 ;SAVE IT FOR A SEC
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP ;WRITE AS AN XWD 0,%TAG
SETZ TA,
PUSHJ PP,STASHQ
HRRZ TA,M.ARG3
PUSHJ PP,STASHQ
JRST STR97A ;SKIP OVER "NO TAG" CODE
STRG97: MOVE TA,[OCTLIT,,1] ;NO TAG, WRITE "OCT 0"
PUSHJ PP,STASHP
SETZ TA,
PUSHJ PP,STASHQ
STR97A: AOS ELITPC
;HERE WHEN DONE WITH THIS SOURCE
HRRZ TA,CURSRE
ADD TA,TEMLOC
SOSG M.ARG2 ;ANY MORE SOURCES?
JRST STRG98 ;NO
SKIPN TA,.SRLNK(TA) ;GET LINK TO NEXT SOURCE ENTRY
$CERR ;?? IT WASN'T SET UP.. COMPLAIN
JRST STRG96 ;GO PROCESS IT
;NO MORE SOURCES -- MAKE SURE NO MORE LINKS
STRG98: SKIPE .SRLNK(TA) ;BETTER BE NO MORE LINKS
$CERR ;ELSE ?COMPILER ERROR
;GO ON TO NEXT SS ENTRY, IF THERE ARE MORE
HRRZ TA,CURSSE
ADD TA,TEMLOC
SKIPE TA,.SSLNK(TA) ;SKIP IF NO MORE
JRST STRG93 ;ELSE GO BACK WITH TA POINTING TO IT
;ALL DONE GENERATING ARG LIST
PUSHJ PP,POOL ;POOL IT IF WE CAN...!
;GENERATE "MOVEI 16,ARG.LIST"
; "PUSHJ 17,STR. OR STR.O"
SKIPN TE,PLITPC ;DID WE POOL?
HRRZ TE,M.ARG4 ;NO, GET STARTING LITERAL
MOVEM TE,LITNN ;STORE ADDRESS OF ARGS
SKIPE PLITPC ;DID WE POOL?
JRST [HRRZ TE,M.ARG4 ;YES, RESTORE START OF LITERALS
MOVEM TE,ELITPC
JRST .+1]
MOVEI TA,STR.## ;GENERATE "MOVEI" AND "PUSHJ"
TLNE W1,(GWFL9) ; "WITH OVERFLOW" CLAUSE?
MOVEI TA,STR.O## ;YES, CALL OTHER ROUTINE
PJRST CSEQGN ;RETURN FROM STRING CODE GEN
;COPYOP -- ROUTINE TO COPY OPERAND TO TEMTAB ENTRY
;CALL:
; TA POINTS TO TEMTAB ENTRY
; TB POINTS TO OPERAND IN EOPTAB
; TD IS # OF WORDS TO TRANSFER
; PUSHJ PP,COPYOP
; <RETURN HERE>
; USES TA,TB
COPYOP: HRL TA,TB ;FROM,,TO
HRRZ TB,TA
ADDI TB,-1(TD)
BLT TA,(TB) ;COPY THE WORDS
POPJ PP, ;AND RETURN
;CPYOPP -- ROUTINE TO COPY OPERAND FROM TEMTAB ENTRY
; TO TEMP AREA (GUARDS AGAINST TABLES EXPANDING)
;CALL:
; TC POINTS TO OPERAND IN TEMTAB
; PUSHJ PP,CPYOPP
; <RETURN HERE>
;RETURNS:
; TC/ STRSAV
; STRSAV/ THE OPERAND
; USES:
; TA,TB,TD,TE
CPYOPP: MOVE TE,1(TC) ;FIND # SUBSCRIPTS
LDB TD,TESUBC
LSH TD,1
ADDI TD,2 ;TD= # WORDS IN OPERAND TO COPY
MOVEI TA,STRSAV ;COPY TO HERE
MOVE TB,TC ;FROM HERE
MOVEI TC,STRSAV ;POINT TO HERE WHEN YOU RETURN
PJRST COPYOP ;COPY OPERAND AND RETURN
;GTCCA - ROUTINE TO GENERATE A MOVEI OF THE CHARACTER COUNT
; IN ESIZEA
;CALL: ESIZEA/ THE LENGTH
; PUSHJ PP,GTCCA
; <RETURN HERE AFTER GENERATING THE "MOVEI 7,CHAR-COUNT"
GTCCA: HRRZ CH,ESIZEA ;GET SIZE
CAILE CH,77777
JRST [HRLI CH,MOVEI.+AC7
PJRST PUTASY] ;GENEREATE MOVEI AND RETURN
;IT WAS A LARGE CONSTANT.. HAVE TO PUT 2 WORDS IN ASY FILE
MOVE CH,[MOVEI.+AC7+ASINC,,AS.CNB]
PUSHJ PP,PUTASY
HRRZ CH,ESIZEA
PJRST PUTASN ;FINISH INSTRUCTION AND RETURN
;TLNKSS - GET AN SS ENTRY AND PUT IN LINKED LIST.
;CALL: TA/ # OF WORDS IN TEMTAB TO GET
; PUSHJ PP,TLNKSS
; <RETURN HERE>
;INPUT:
; STSETP/ POINTS TO FIRST SS ENTRY, OR 0
; CURSSE/ POINTER TO PREVIOUS ENTRY, UNLESS C(STSETP)= 0
;RETURNS:
; TEMTAB ENTRY GENERATED, AND ZEROED
; STSETP SET UP IF IT WAS 0
; LINK SET UP IN PREVIOUS ENTRY TO POINT TO THIS ONE
; CURSSE SET UP TO POINT TO THIS ENTRY
;ACS USED: TA-TE
TLNKSS: PUSH PP,TA ;SAVE # WORDS
PUSHJ PP,GETTEM ;GET (TA) LOCS IN TEMTAB
;NOW TA= REL LOC
;LINK TO LAST ENTRY
SKIPN STSETP ;IS THIS 1ST SS?
JRST STRTSS ;YES
HRRZ TB,CURSSE ; NO, LINK LAST ONE TO THIS ONE
ADD TB,TEMLOC
MOVEM TA,.SSLNK(TB) ;LAST ENTRY'S LINK POINTS TO THIS ONE
TRNA ;LEAVE INITIAL PTR ALONE
STRTSS: MOVEM TA,STSETP ;1ST ARG--SETUP INITIAL POINTER
MOVEM TA,CURSSE ;MAKE THIS ENTRY THE CURRENT ONE
;ZERO OUT THIS TEMTAB ENTRY
POP PP,TD ;TD:= # WORDS TO CLEAR
ADD TA,TEMLOC ;TA POINTS TO FIRST WORD
SETZM (TA) ;CLEAR FIRST WORD
HRL TA,TA ;MAKE START LOC,,START LOC
HRRZ TB,TA
ADDI TB,-1(TD) ;END LOC
ADDI TA,1 ;START LOC,,START LOC+1
BLT TA,(TB) ;CLEAR OUT TEMTAB ENTRY
POPJ PP, ;DONE, RETURN
;TLNKSR - GET A SOURCE ENTRY AND PUT IN LINKED LIST.
;CALL: TA/ # WORDS IN TEMTAB TO GET
; PUSHJ PP,TLNKSR
; <RETURN HERE>
;INPUT:
; CURSSE/ POINTS TO CURRENT SS ENTRY
; CURSRE/ POINTS TO PREVIOUS SOURCE ENTRY OR 0
;RETURNS:
; TEMTAB ENTRY GENERATED AND ZEROED
; LINK IN SS ENTRY SET UP IF IT WAS 0
; CURSRE SET UP TO POINT TO THIS ENTRY
;ACS USED: TA-TE
TLNKSR: PUSH PP,TA ;SAVE # WORDS TO GET
PUSHJ PP,GETTEM ;GET C(TA) WORDS IN TEMTAB
; NOW TA:= REL LOC
;LINK TO LAST ENTRY
HRRZ TB,CURSSE
ADD TB,TEMLOC
SKIPN .SSLKS(TB) ;SOURCE LINK SETUP?
JRST STRTSR ;NO, SETUP 1ST ONE
HRRZ TB,CURSRE ;LINK LAST ONE TO THIS ONE
ADD TB,TEMLOC
MOVEM TA,.SRLNK(TB)
TRNA ;SKIP SET OF INITIAL PTR
STRTSR: MOVEM TA,.SSLKS(TB) ;1ST SOURCE--SETUP INITIAL PTR IN SS ENTRY
MOVEM TA,CURSRE ;MAKE THIS ENTRY THE CURRENT SOURCE
;ZERO OUT THIS TEMTAB ENTRY
POP PP,TD ;TD:= # WORDS TO CLEAR
ADD TA,TEMLOC ;TA POINTS TO FIRST WORD
SETZM (TA) ;CLEAR FIRST WORD
HRL TA,TA ;START LOC,,START LOC
HRRZ TB,TA
ADDI TB,-1(TD) ;TB:= END LOC
ADDI TA,1 ;TA:= BLT PTR
BLT TA,(TB) ;CLEAR OUT TEMTAB ENTRY
POPJ PP, ;DONE, RETURN
;SETUP DELIMITER OR SOURCE IF LIT OR FIG. CONST.
;CALL: CUREOP POINTS TO OPERAND
; EACA/ MODE TO PUT ITEM IN (D6MODE, D7MODE, OR D9MODE)
; PUSHJ PP,SETLFC
;
;RETURNS:
; +1 IF ERRORS
; +2 IF OK WITH LITERAL PUT IN LITAB
; EACC POINTING TO THE LITERAL
; EMODEA = MODE
; ESIZEA = CC
SETLFC: HRRZ TA,CUREOP
MOVE TC,0(TA) ;LOOK AT OPERAND FLAGS
TLNN TC,GNLIT ;BETTER BE LIT OR FIG CONST.
$CERR ; ELSE WE SHOULDN'T HAVE BEEN CALLED!
TLNN TC,GNFIGC ;FIG CONST.?
JRST SETLFL ;NO, LITERAL
;THE ANS68 COMPILER CONVERTS FIG. CONSTS TO 1-CHAR LITERALS IN PHASE C
; WHEN COMPILING THE "STRING" STATEMENT.
; BUT THIS CODE SHOULD PROBABLY BE LEFT IN FOR ANS68 ANYWAY
; INCASE SOMEDAY THAT CHANGES.
TLNN TC,GNFCS!GNFCZ!GNFCQ!GNFCHV!GNFCLV
JRST BADLIT ;? FUNNY KIND OF LITERAL.. PARSE ERROR (?)
; GET THE APPROPRIATE CHARACTER IN THE
;MODE OF THE DESTINATION
TLNE TC,GNFCS ;SPACE
HRRZ EACC,IFSPCS(EACA)
TLNE TC,GNFCZ ;ZERO
HRRZ EACC,IFZROS(EACA)
TLNE TC,GNFCQ ;QUOTE
HRRZ EACC,HIVQOT(EACA)
TLNE TC,GNFCLV ;LOW-VALUES
MOVEI EACC,0
TLNE TC,GNFCHV ;HIGH-VALUES
HLRZ EACC,HIVQOT(EACA)
SKIPLE COLSEQ ;[1004] PROGRAM COLLATING SEQUENCE = ALPHABET-NAME?
TLNN TC,GNFCLV!GNFCHV ;AND LOW-VALUES OR HIGH-VALUES
JRST SETLF2 ;NO, HAVE CORRECT CHAR IN EACC
TLNE TC,GNFCHV ;HIGH-VALUES?
MOVE EACC,COHVLV(EACA) ;GET HIGH-VALUES CHARACTER
TLNE TC,GNFCLV ;LOW-VALUES?
MOVE EACC,COHVLV+3(EACA) ;GET LOW-VALUES CHARACTER
;HERE WITH CHARACTER OF THE FIG. CONST IN EACC
;SETUP LITERAL TO BE 1-CHAR.
SETLF2: MOVEI TE,1 ;1-CHAR
MOVEM TE,ESIZEZ
HRL TA,D.LTCD(EACA) ;GET LITAB CODE
HRRI TA,1 ;ONE WORD LITERAL
PUSHJ PP,STASHP
SETZ TA,
DPB EACC,[POINT 6,TA,5
POINT 7,TA,6
POINT 9,TA,8](EACA)
PUSHJ PP,POOLIT
SKIPN EACC,PLITPC
MOVE EACC,ELITPC
SKIPN PLITPC
AOS ELITPC
IORI EACC,AS.LIT ;FINISH SETTING UP EACC
MOVEI TE,1 ;SET ESIZEA TO 1
MOVEM TE,ESIZEA
MOVEM EACA,EMODEA ;SET EMODEA TO MODE OF THE ITEM
JRST CPOPJ1 ;GIVE OK RETURN
;SUBROUTINE SETLFL (CONT'D)
;HERE IF WE GOT A LITERAL
SETLFL: HRRZM EACA,EMODEB ;SAVE MODE TO COERCE LITERAL INTO FOR LITD.
MOVE TC,CUREOP ;HAVE A LITERAL, CALL SETOPN
MOVEI LN,EBASEA
PUSHJ PP,SETOPN
TSWF FERROR
POPJ PP, ;IF ERRORS, TAKE THE ERROR RETURN
HRRZ EACA,EMODEB ;GET MODE
JUMPN EACA,SETL1A ;JUMP IF NOT SIXBIT
;CHECK LITERAL FOR ASCII CHARACTERS. IF THERE ARE SOME, IT MUST
; BE CREATED AS AN ASCII LITERAL.
MOVE TA,EBYTEA ;GET BP TO LITERAL
HRRZ TC,ESIZEA ;GET SIZE OF LITERAL
SETL1B: ILDB TE,TA ;GET NEXT CHARACTER OF LITERAL
CAIL TE,40 ;IS CHARACTER CONVERTIBLE TO SIXBIT?
CAILE TE,137
JRST [MOVEI EACA,D7MODE ;NO, USE ASCII
HRRM EACA,EMODEB
JRST SETL1A]
SOJG TC,SETL1B ;LOOP FOR ALL CHARACTERS
SETL1A: MOVE TD,ESIZEA ;COPY SIZE TO B
MOVEM TD,ESIZEB ;SET UP FOR LITD. CALL
MOVEM TD,ESIZEZ
SETZM LITERR ;INCASE ERRORS CONVERTING
PUSHJ PP,LITD.0 ;MAKE THE LITERAL, NO IMMEDIATE MODE
TSWF FERROR
POPJ PP, ;ERRORS
SKIPE LITERR ; IF CONVERSION ERRORS,
$CERR ;?WE SHOULD HAVE PREVENTED THIS
HRRZ EACC,EINCRA ;%LIT00+N
HRRZ TE,EMODEB
HRRM TE,EMODEA ;SET MODE OF ITEM
JRST CPOPJ1
BADLIT: MOVEI DW,E.123 ;"1-CHAR NON-NUM LITERAL EXPECTED"
JRST OPNFAT
;ROUTINE TO STORE BP AND CC OF ITEM IN "A" IN THE LITERAL TABLE.
;CALL:
; "A" SET UP, NOT SUBSCRIPTED, NO DEPENDING VARIABLES
; PUSHJ PP,GTLBPC
; <RETURNS HERE>
;ON RETURN,
; TE/ %LITNN+M (POINTER TO THE 2-WORD LITERAL)
GTLBPC: PUSH PP,ELITPC ;SAVE LITERAL PC NOW
MOVE TA,[BYTLIT,,2] ; PREPARE TO WRITE BP
PUSHJ PP,STASHP
HRRZ TA,EBASEA
PUSHJ PP,STASHQ
HLRZ TA,ERESA
ROT TA,-6 ;GET DD0000,,0 FOR RESIDUE
HRRZ TC,EMODEA
MOVE TC,BYTE.S(TC) ;BITS/BYTE
DPB TC,[POINT 6,TA,11] ;STORE IN BP
HRR TA,EINCRA ;GET INCREMENT IF ANY
PUSHJ PP,STASHQ ;FINISH BP
AOS ELITPC
;NOW CC
MOVE TA,[OCTLIT,,1]
PUSHJ PP,STASHP
;IF EDITED, USE EXTERNAL SIZE
HRRZ TA,ETABLA
LDB TE,LNKCOD## ;MAKE SURE ITS A DATAB
CAIE TE,TB.DAT##
JRST GTLBP1 ;ITS NOT, LEAVE AS IS
PUSHJ PP,LNKSET
LDB TE,DA.EDT ;EDITED?
JUMPE TE,GTLBP1 ;NO
LDB TE,DA.EXS ;YES, GET EXTERNAL SIZE
MOVEM TE,ESIZEA ; USE THAT FOR THE SIZE
GTLBP1: HRRZ TA,ESIZEA
PUSHJ PP,POOLIT ;POOL THE TWO-WORD CHUNK
AOS ELITPC
POP PP,TE ;GET OLD LITERAL PC
SKIPN PLITPC ;DID WE POOL?
JRST .+3 ;NO, TE POINTS TO THE LITERAL
MOVEM TE,ELITPC ;WE DID, RESTORE LITERAL PC
MOVE TE,PLITPC ; GET TE= WHERE WE STORED IT
IORI TE,AS.LIT ;MAKE TE LOOK LIKE A LITERAL ADDRESS
POPJ PP, ;DONE, RETURN
;PUTJMP - ROUTINE TO GET A TAG AND GENERATE "JRST %TAG"
;; AND STORE AS.TAG+N IN M.ARG1
;HOWEVER IF THERE IS ALREADY SOMETHING IN M.ARG1
; IT JUST POPJ'S.
PUTJMP: SKIPE M.ARG1 ;DID IT ALREADY?
POPJ PP, ;YES, RETURN
PUSHJ PP,GETTAG ;NO, GET A TAG
MOVEM CH,M.ARG1 ;SAVE IT
HRLI CH,JRST. ;GENERATE "JRST" TO IT
PUSHJ PP,PUTASY ;WRITE INSTRUCTION
HRRZ TA,CH
PJRST REFTAG ;REFERENCE THE TAG AND RETURN
;GEN "POPJ 17," TO END ROUTINE
PUTPPJ: MOVSI CH,POPJ.+AC17
PJRST PUTASY ;WRITE OUT THE POPJ
;FAKPTV - FAKE "PT.VAL" AS "A" OPERAND
; "B" IS ASSUMED TO BE SETUP WITH THE POINTER OPERAND TO MOVE IT TO.
FAKPTV: MOVE TE,[^D36,,PT.VAL##]
JRST FAK1WC ;GO TO COMMON CODE
;FAKTLV - FAKE "TL.VAL" AS "A" OPERAND
; SAME AS FAKPTV EXCEPT A DIFFERENT EXT. LOC.
FAKTLV: MOVE TE,[^D36,,TL.VAL##]
JRST FAK1WC ;GO TO COMMON CODE
;FAKCTV - FAKE "CT.VAL" AS "A" OPERAND
FAKCTV: MOVE TE,[^D36,,CT.VAL##]
FAK1WC: MOVEM TE,EBASEA
SWOFF FASIGN!FASUB ;NOT SUBSCRIPTED OR SIGNED
SWON FANUM ;BUT NUMERIC
SETZM EINCRA
MOVEI TE,D1MODE
MOVEM TE,EMODEA
SETZM EFLAGA
SETZM EDPLA
SETZM ETABLA
SETZM EBYTEA
HRRZ TE,ESIZEB ;SAME SIZE
CAILE TE,^D10 ;UNLESS > 10.
MOVEI TE,^D10 ; IN WHICH CASE, WE WILL TRUNCATE TO 10
HRRZM TE,ESIZEA
POPJ PP, ;DONE,RETURN
SUBTTL GENERATE AN "UNSTRING"
;MORE EXTERNAL LOCS IN IMPURE, USED ONLY BY "UNSTRING"
EXTERN UNSNMF,USENII,UNSFLG,UNSTLY
EXTERN UNSDLE,CURDE,CURUS
;DEFINITIONS FOR "UNSTRING"
;LOCATION UNSDLE POINTS TO THE FIRST DELIMITER ENTRY IN TEMTAB (0 IF NONE)
; EACH DELIMITER-ENTRY HAS THE FOLLOWING FORMAT:
; +0/ LINK TO NEXT DELIMITER-ENTRY, OR 0 IF THIS IS THE LAST
; +1/ FLAGS+BSI.DEL,,%LIT OR 0
; +2/ %TAG OR 0
; +3-17/ OPERAND (IF NECESSARY TO STORE IT)
;DEL-E DEFS
.DELNK==0
.DEFLG==1
DE%NUM==1B0 ;DELIMITER IS NUMERIC
DE%ALL==1B1 ;"ALL" SPECIFIED
.DETAG==2
BSI.DE: POINT 3,.DEFLG(TA),17 ;BSI OF DELIMITER ITEM
DPL.DL: POINT 18,.DEFLG(TA),35 ;POINTER TO %LIT FOR DELIMITER
DE.TAG: POINT 18,.DETAG(TA),35 ;TAG OF ROUTINE TO CALL TO SETUP %TEMP
.DEOPR==3 ;PTR TO OPERAND, IF IT WAS STORED
.DEHLN==4 ;LENGTH OF DE ENTRY
;LOCATION STSETP POINTS TO THE FIRST UNSTRING-SERIES ENTRY.
;
;EACH UNSTRING-SERIES ENTRY HAS THE FOLLOWING FORMAT:
; +0/ LINK TO NEXT UNSTRING-SERIES ENTRY, OR 0
; +1/ FLAGS+BSI.SR,,%LIT ;SOURCE
; +2/ %TAG1,,%TAG2 ;TAG1 SETS UP %TEMP, TAG2 STORES DELIM AWAY
; ; FROM OU.TMP
; +3/ PTR TO SOURCE OPERAND OR 0
; +4/ FLAGS+BSI.DS,,%LIT ;DELIMITER STORE
; +5/ %TAG1,,%TAG2 ;TAG1 SETS UP %TEMP, TAG2 STORES DELSTORE AWAY
; ; FROM OU.TMP
; +6/ PTR TO DELSTORE OPERAND OR 0
; +7/ %TAG ;IF COUNT ITEM PRESENT, ROUTINE TO STORE IT
; ; FROM CT.VAL.
; +8/ PTR TO COUNT ITEM OPERAND OR 0
.USLNK==0 ;LINK TO NEXT UNSTRING-SERIES ENTRY
.USFLG==1 ;FLAG WORD
US%NUR==1B0 ;NUMERIC RECEIVING ITEM
US%RRJ==1B1 ;RECEIVING ITEM IS RIGHT-JUSTIFIED
US%GDS==1B2 ;GOT A DELIMITER-STORE OPERAND
US%GCT==1B3 ;GOT A COUNT ITEM
BSI.UR: POINT 3,.USFLG(TA),17 ;BSI OF UNSTRING RECEIVING ITEM
DPL.UR: POINT 18,.USFLG(TA),35 ;POINTER TO %TEMP OR %LIT OR 0
.USRTG==2 ;RECEIVING TAG
TAG.UR: POINT 18,.USRTG(TA),17 ;TAG TO SETUP %TEMP WITH BP AND CC
TAG.OR: POINT 18,.USRTG(TA),35 ;TAG TO STORE DELIM AWAY IF NUMERIC
.USPTR==3 ;POINTER TO RECEIVING ITEM OPERAND, OR 0
.USDSF==4 ;DELIMITER STORE FLAG WORD
DS%NUM==1B0 ;DELIMITER STORE IS NUMERIC
DS%JST==1B1 ;DELIMITER STORE IS RIGHT-JUSTIFIED (SET IF NUMERIC,TOO)
BSI.DS: POINT 3,.USDSF(TA),17 ;BSI OF DELIMITER-STORE
UPT.DS: POINT 18,.USDSF(TA),35 ;%LIT POINTER
.USDTG==5 ;TAGS FOR DELIMITER-STORE
TAG.DT: POINT 18,.USDTG(TA),17 ;TAG TO SETUP %TEMP WITH BP AND CC
TAG.SD: POINT 18,.USDTG(TA),35 ;TAG TO STORE DELIM AWAY IF NUMERIC
.USPTD==6 ;POINTER TO DELIM STORE OPERAND OR 0
.USCTT==7 ;TAG FOR COUNT ITEM
TAG.CT: POINT 18,.USCTT(TA),35 ;TAG TO STORE COUNT ITEM
.USPTC==10 ;PTR TO COUNT OPERAND OR 0
.USHLN==11 ;LENGTH OF UNSTRING-SERIES ENTRY
COMMENT \
GENFIL FOR AN UNSTRING LOOKS LIKE:
DELIMITER ITEM 1 (OPTIONAL)
UDELIM OPERATOR (OPTIONAL - NOT PRESENT IF DELIMITER ITEM 1 ISN'T)
DELIMITER ITEM 2 (OPTIONAL)
UDELIM OPERATOR (OPTIONAL - NOT ...)
...
DELIMITER ITEM I (OPTIONAL)
UDELIM OPERATOR (OPTIONAL - NOT ...)
RECEIVING ITEM 1
RECEIVING ITEM 1 DELIMITER (OPTIONAL)
COUNT ITEM 1 (OPTIONAL)
UNSDES OPERATOR (WITH FLAG 9 ON IF RECEIVING ITEM 1 DELIMITER IS
PRESENT AND FLAG 10 ON IF COUNT ITEM 1 IS PRESENT)
RECEIVING ITEM 2
RECEIVING ITEM 2 DELIMITER (OPTIONAL)
COUNT ITEM 2 (OPTIONAL)
UNSDES OPERATOR (WITH ...)
...
RECEIVING ITEM J
RECEIVING ITEM J DELIMITER (OPTIONAL)
COUNT ITEM J (OPTIONAL)
UNSDES OPERATOR (WITH ...)
SENDING ITEM
POINTER ITEM (OPTIONAL)
TALLYING ITEM (OPTIONAL)
UNSTR OPERATOR (WITH FLAG 10 ON IF POINTER ITEM IS PRESENT AND
FLAG 11 ON IF TALLYING ITEM IS PRESENT)
\
;ARRIVE HERE ON A UDELIM OPERATOR OR AN UNSDES OPERATOR
;ADDITIONAL FOLLOWING OPERATORS MUST BE FORCIBLY READ IN
;THE SEQUENCE IS: [UDELIM]...UNSDES[UNSDES]...UNSTR
UNSGEN: SETZM ARGCTR## ;INIT DELIMITER COUNT
HRRZ TB,EOPLOC ;SAVE ADDR OF FIRST OPERAND
ADDI TB,1 ; IN CASE UNSDES OPERATOR
MOVEM TB,ARGSTR##
CAIN W2,UNSDES ;NO UDELIM'S?
JRST UNSG1 ;NONE
UNSG0: MOVE W2,W1 ;STORE [-1 + W1] ON EOPTAB
SETO W1, ; TO MARK UDELIM OPERATOR
PUSHJ PP,PUSH12
AOS ARGCTR ;COUNT THIS DELIMITER
HRRZ TB,EOPNXT ;SAVE ADDR OF NEXT EOPTAB ENTRY
ADDI TB,1 ; IN CASE UNSDES OPERATOR
MOVEM TB,ARGSTR##
PUSHJ PP,READEM ;READ NEXT OPERAND+OPERATOR SET
CAIN W2,UDELIM ;ANOTHER UDELIM? OR UNSDES?
JRST UNSG0 ;UDELIM
UNSG1: CAIE W2,UNSDES ;WAS IT REALLY A UNSDES?
POPJ PP, ;NO, FORGET THE WHOLE THING, THE
; ERROR MESSAGE SHOULD HAVE BEEN
; GENERATED BY THE SYNTAX SCAN.
HRLZS ARGCTR ;MOVE DELIM CT TO LH, INIT DEST CT IN RH
UNSG2: LDB TB,[POINT 2,W1,10] ;GET DEL-STORE & COUNTER-ITEM FLAGS
PUSHJ PP,FIXOPS ;IF NOT BOTH PRESENT, STORE %TEMP PTRS
MOVE W2,W1 ;STORE [-1 + W1] ON EOPTAB
SETOI W1, ; TO MARK UNSDES OPERATOR
PUSHJ PP,PUSH12
AOS ARGCTR ;COUNT THIS DESTINATION, DEL-STORE & COUNTER
HRRZ TB,EOPNXT ;SAVE ADDR OF NEXT EOPTAB ENTRY
ADDI TB,1 ; IN CASE UNSTR OPERATOR
MOVEM TB,ARGSTR##
PUSHJ PP,READEM ;READ NEXT OPERAND+OPERATOR SET
CAIN W2,UNSDES ;ANOTHER UNSDES? OR UNSTR?
JRST UNSG2 ;UNSDES
CAIE W2,UNSTR ;WAS IT REALLY AN UNSTR?
POPJ PP, ;NO, FORGET THE WHOLE THING, THE
; ERROR MESSAGE SHOULD HAVE BEEN
; GENERATED BY THE SYNTAX SCAN.
LDB TB,[POINT 2,W1,11] ;GET POINTER & TALLY-ITEM FLAGS
PUSHJ PP,FIXOPS ;IF NOT BOTH, STORE %TEMP PTRS
COMMENT \
ALL OF THE OPERANDS AND OPERATORS FOR THE UNSTRING HAVE BEEN READ IN.
EOPTAB NOW LOOKS LIKE:
DELIMITER ITEM 1 (OPTIONAL)
[-1 + W1] (OPTIONAL - NOT PRESENT IF DELIMITER ITEM 1 ISN'T)
DELIMITER ITEM 2 (OPTIONAL)
[-1 + W1] (OPTIONAL - NOT ...)
...
DELIMITER ITEM I (OPTIONAL)
[-1 + W1] (OPTIONAL - NOT ...)
RECEIVING ITEM 1
RECEIVING ITEM 1 DELIMITER (OR [-2 + 0] IF THERE WAS NO
RECEIVING ITEM 1 DELIMITER)
COUNT ITEM 1 (OR [-2 + 0] IF THERE WAS NO COUNT ITEM 1)
[-1 + W1]
RECEIVING ITEM 2
RECEIVING ITEM 2 DELIMITER (OR [-2 + 0] IF ...)
COUNT ITEM 2 (OR [-2 + 0] IF ...)
[-1 + W1]
...
RECEIVING ITEM J
RECEIVING ITEM J DELIMITER (OR [-2 + 0] IF ...)
COUNT ITEM J (OR [-2 + 0] IF ...)
[-1 + W1]
SENDING ITEM
POINTER ITEM (OR [-2 + 0] IF THERE WAS NO POINTER ITEM.)
TALLYING ITEM (OR [-2 + 0] IF THERE WAS NO TALLYING ITEM)
\
SETZM STSETP ;CLEAR POINTER TO INTO ITEMS
SETZM UNSDLE ;CLEAR POINTER TO DELIMITER ENTRIES
SETZM UNSFLG ;CLEAR UNSTRING FLAGS
MOVE TE,TEMLOC ;CLEAR OUT TEMTAB
AOBJN TE,.+1
MOVEM TE,TEMNXT
;BUILD POINTER TO SENDING ITEM
;ARGSTR NOW POINTS TO THE SENDING ITEM
HRRZ TC,ARGSTR
HRRZM TC,CUREOP
HRLM TC,OPERND ;FOR SUBSCA AND NB1PAR
PUSHJ PP,SETOPA ;SET IT UP AS "A"
; (ERRORS RETURN TO PHASE E DRIVER)
;THE SENDING ITEM MUST BE A DATANAME
SETZM UNSNMF ;ASSUME IT'S NOT NUMERIC
TSWF FANUM ; IS IT NUMERIC?
SETOM UNSNMF ;YES
;CAN BE NUMERIC, BUT MUST BE AN INTEGER
HRRZ TE,EMODEA
CAIE TE,FPMODE
SKIPE EDPLA
JRST STRE6 ;'MUST REPRESENT AN INTEGER'
;IF EDITED, USE EXTERNAL SIZE
HRRZ TA,ETABLA
PUSHJ PP,LNKSET
LDB TE,DA.EDT ;EDITED?
JUMPE TE,UNSG2C ;NO
LDB TE,DA.EXS ;YES, GET EXTERNAL SIZE
MOVEM TE,ESIZEA ; USE THAT FOR THE SIZE
;GENERATE CODE TO SETUP BP IN SRC.BP, CC IN SRC.CC
; IF NUMERIC, GENERATE CODE TO MOVE IT TO SR.TMP
UNSG2C: SKIPN UNSNMF ;SKIP IF NUMERIC
JRST UNSG3 ;NO, ALPHANUMERIC
HRRZ TE,EMODEA ;GET MODE OF "A" NOW
CAIG TE,DSMODE ; IF ALREADY SOME KIND OF DISPLAY,
JRST UNSG2B ;USE THAT SAME MODE
;LET'S MAKE IT ALL ASCII. (THEN ALL LITERALS WILL WORK)
MOVEI TE,D7MODE ;GET ASCII MODE
UNSG2B: HRRM TE,USENII ;STORE IN MODE
MOVEM TE,EMODEB ;STORE IN "B"
;SET UP "B" TO BE SR.TMP
HRRZ TE,ESIZEA ;SAME SIZE AS "A"
MOVEM TE,ESIZEB
MOVE TE,[^D36,,SR.TMP##]
MOVEM TE,EBASEB
SETZM EINCRB
SETZM EDPLB
SETZM ETABLB
SETZM EFLAGB
SETZM ETABLB
SWON FBNUM ;A NUMERIC TEMP
SWOFF FBSUB!FBSIGN ;NOT SUBSCRIPTED, OR SIGNED
PUSHJ PP,MXX. ;GENERATE THE MOVE
TSWF FERROR ; IF ERRORS,
POPJ PP, ;DIE
;GEN CODE TO STORE BP AND CC
;FIRST CC. NO DEPENDING VARIABLES, BECAUSE IT IS NUMERIC
HRRZ CH,ESIZEB ;GET SIZE
HRRZM CH,ESIZEA ;STORE IN ESIZEA FOR GTCCA
PUSHJ PP,GTCCA ;GEN "MOVEI AC7,SIZE"
MOVE CH,[MOVEM.+AC7,,SRC.CC##]
PUSHJ PP,PUT.EX
;NOW BP
UNSG2A: MOVE TA,[BYTLIT,,2] ;FIRST MAKE LITERAL BP TO THE ITEM
PUSHJ PP,STASHP
MOVEI TA,SR.TMP## ;POINTING TO SR.TMP
PUSHJ PP,STASHQ
MOVSI TA,440000 ;PARTIAL BYTE PTR
HRRZ TB,EMODEB ;GET MODE OF ITEM
MOVE TB,BYTE.S(TB) ;BITS/BYTE
DPB TB,[POINT 6,TA,11]
PUSHJ PP,POOLIT ;PUT OUT REST OF BP AND POOL IT
SKIPE PLITPC ;SKIP IF NOT POOLED
JRST .+3 ;WAS--GET PLITPC
HRRZ TE,ELITPC ;NO, GET ELITPC
AOSA ELITPC ;BUMP IT AND SKIP
HRRZ TE,PLITPC ;(WAS POOLED)
IORI TE,AS.LIT ;POINTER TO LITERAL IN TE
MOVE CH,[MOV+AC0+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,TE
PUSHJ PP,PUTASN ;GENERATE "MOVE 0,[POINTER TO SR.TMP]"
MOVE CH,[MOVEM.+AC0,,SRC.BP##]
PUSHJ PP,PUT.EX
JRST UNSG4 ;DONE WITH SENDING ITEM
;HERE IF SENDING ITEM IS NON-NUMERIC
UNSG3: HRRZ TE,EMODEA ;MUST BE SOME KIND OF DISPLAY
CAILE TE,DSMODE ; MAKE A SANITY CHECK...
$CERR ;OOPS--INSANITY
HRRZM TE,USENII ;REMEMBER MODE
;GEN CODE TO STORE BP AND CC
PUSHJ PP,NB1PAR ;GET BP TO "A" IN AC5
TSWF FERROR ; ANY ERRORS?
POPJ PP, ;YES, GIVE UP
;TO STORE BP: "MOVEM AC5,SRC.BP"
MOVE CH,[MOVEM.+AC5,,SRC.BP##]
PUSHJ PP,PUT.EX
;STORE CC
PUSHJ PP,DEPTSA ;DOES "A" HAVE A DEPENDING ITEM?
JRST UNSG3A ;NO, GENERATE "MOVEI" TO GET SIZE
MOVEI TE,7 ;USE AC7 TO GET SIZE
SETZM SAVPR0 ;DON'T SAVE %PARAM
PUSHJ PP,SZDPVA ;GET SIZE IN RUNTIME AC7
$CERR ;?? ERRORS
JRST UNSG3B ;SKIP OVER "MOVEI"
UNSG3A: PUSHJ PP,GTCCA ;GEN "MOVEI AC7,SIZE"
;NOW SIZE IS IN AC7, MOVE IT TO SRC.CC
UNSG3B: MOVE CH,[MOVEM.+AC7,,SRC.CC##]
PUSHJ PP,PUT.EX
;HERE WHEN DONE WITH SENDING ITEM
UNSG4: HRRZ TE,ESIZEA ;STORE MAX SIZE IN LH (USENII)
HRLM TE,USENII
;GO ON TO THE POINTER ITEM
HRRZ TC,ARGSTR ;POINTER TO SENDING ITEM
HRRZM TC,CUREOP ; CALL BMPEOP TO FIND START OF NEXT
PUSHJ PP,BMPEOP ;OPERAND.. THE "POINTER" ITEM
$CERR ;? MUST BE THERE (-2,,0) STORED
;MAKE ARGSTR POINT TO REL ADDRESS OF THE POINTER ITEM
HRRZ TD,EOPLOC ;START
HRRZ TE,CUREOP
SUBI TE,(TD)
MOVEM TE,ARGSTR
HRRZ TE,CUREOP ;NEW CUREOP (POINTS TO POINTER ITEM)
MOVE TD,(TE) ;GET 1ST WORD
CAMN TD,[-2] ; -2 MEANS NO POINTER ITEM
JRST UNSG5 ;GO GEN CODE TO STORE 1 TO PT.VAL
;THERE WAS A POINTER ITEM. CUREOP NOW POINTS TO IT.
HRRZ TC,CUREOP ;POINTER IN TC FOR SETOPA
MOVE TD,(TC)
TLNN TD,GNLIT!GNFIGC
JRST UNSG4A ;NOT LIT OR FIG CONST.. OK
$CERR ;?SYNTAX SCAN SHOULD CATCH THIS
;HERE WITH TC POINTING TO THE "POINTER" ITEM
UNSG4A: PUSHJ PP,SETOPA ;SET IT UP AS "A"
; (ERRORS RETURN TO PHASE E DRIVER)
TSWF FANUM ;POINTER MUST BE NUMERIC
SKIPE EDPLA ; AND CAN'T HAVE DECIMAL PLACES
JRST STRE2
HRRZ TE,EMODEA ;DISALLOW FLOATING-POINT
CAIN TE,FPMODE
JRST STRE2
PUSHJ PP,STRGT3 ;GIVE ERROR IF THE "POINTER" ITEM IS EDITED
PUSHJ PP,STRGT4 ;SEE IF SIZE IS BIG ENOUGH
;REMEMBER THERE WAS A POINTER ITEM
UNSG4B: MOVEI TE,1B18 ;"POINTER ITEM"
IORM TE,UNSFLG ; SET IT IN THE FLAGS
;GET ALL SUBSCRIPTS INTO %TEMP, SO THEY WON'T BE AFFECTED BY THE STATEMENT.
SETOM ONLYEX
SETOM ALSTMP
HRRZ TC,CUREOP ;SUBSCA DOESN'T BELIEVE CUREOP,
HRLM TC,OPERND ; WE HAVE TO PUT IT HERE.
PUSHJ PP,SUBSCA ;GEN SUBSCRIPT CODE IF NECESSARY
SETZM ONLYEX
SETZM ALSTMP
TSWF FERROR ;IF ERRORS,
POPJ PP, ;GIVE UP
; COPY OPERAND TO TEMTAB SO WE CAN GET IT LATER
HRRZ TE,ARGSTR ;REL ADDR OF POINTER ITEM
ADD TE,EOPLOC ;GET ABS LOC OF OPERAND
HRRZ TC,TE
MOVE TE,1(TC) ;HOW MANY SUBSCRIPTS AND STUFF TO FOLLOW?
LDB TA,TESUBC
LSH TA,1
ADDI TA,2 ;TOTAL # WORDS TO COPY
PUSH PP,TA ;SAVE #
PUSHJ PP,GETTEM ; GET THE WORDS IN TEMTAB
HRRZ TB,TA ;TA RETURNED BY GETTEM,
; = REL LOC OF ENTRY IN TEMTAB
HRRM TA,STPTO ;REMEMBER WHERE IT IS STORED
ADD TA,TEMLOC ;MAKE TA BE ABS LOC
;COPY OPERAND TO TEMTAB
POP PP,TD ;TD:= # WORDS TO COPY
HRRZ TB,ARGSTR ; START OF OPERAND IN EOPTAB
ADD TB,EOPLOC
PUSHJ PP,COPYOP ;COPY IT..
;POINTER ITEM'S OPERAND IS NOW IN TEMTAB.
; NOW RH (STPTO) = REL ADDRESS IN TEMTAB OF THE OPERAND
; LH (STPTO) = UNDEFINED
;NOW GENERATE CODE TO PUT INITIAL VALUE OF POINTER INTO PT.VAL
SWON FBSIGN!FBNUM ;SET UP "B" AS PT.VAL
SWOFF FBSUB
MOVE TE,[^D36,,PT.VAL##]
MOVEM TE,EBASEB
SETZM EINCRB
MOVEI TE,D1MODE ;1-WORD COMP
MOVEM TE,EMODEB
SETZM EFLAGB
SETZM ETABLB
SETZM EBYTEB
SETZM EDPLB
HRRZ TE,ESIZEA ;SAME SIZE
CAILE TE,^D10 ;UNLESS > 10
MOVEI TE,^D10 ; IN WHICH CASE, WE WILL TRUNCATE TO 10
HRRZM TE,ESIZEB
PUSHJ PP,MXX. ;MOVE "A" TO PT.VAL
TSWF FERROR
POPJ PP, ;DIE IF ERRORS
;GET A TAG WHICH WILL BE ADDRESS OF ROUTINE TO CALL TO STORE THE
; NEW POINTER VALUE. THE CODE FOR THIS ROUTINE WILL BE GENERATED LATER.
PUSHJ PP,GETTAG
HRLM CH,STPTO ;STORE TAG IN LH (STPTO)
;NOW RH (STPTO) = REL ADDRESS IN TEMTAB OF POINTER ITEM OPERAND
; LH (STPTO) = TAG OF ROUTINE TO CALL TO STORE POINTER VALUE.
JRST UNSG6 ;DONE WITH POINTER ITEM (FOR NOW)
;HERE IF THERE WAS NO POINTER ITEM.. GEN CODE TO
; STORE VALUE OF 1 IN PT.VAL
UNSG5: SETZM STPTO ;CLEAR "POINTER" INFO
MOVE CH,[MOVEI.+AC0,,1]
PUSHJ PP,PUTASY ;"MOVEI 0,1"
MOVE CH,[MOVEM.+AC0,,PT.VAL##]
PUSHJ PP,PUT.EX ;"MOVEM 0,PT.VAL"
;HERE WHEN DONE WITH POINTER ITEM.
; GEN CODE FOR THE TALLYING ITEM
UNSG6: HRRZ TE,ARGSTR ;GET PTR TO "POINTER" ITEM
ADD TE,EOPLOC
HRRM TE,CUREOP ;READY TO CALL BMPEOP
PUSHJ PP,BMPEOP
$CERR ;?MUST BE THERE (-2,,0) STORED
HRRZ TE,CUREOP ;NEW CUREOP (POINTS TO TALLYING ITEM)
MOVE TD,(TE) ;GET 1ST WORD
CAMN TD,[-2] ;-2 MEANS NO TALLYING ITEM
JRST UNSG7 ;GO GEN CODE TO PUT 0 IN TL.VAL
;MAKE ARGSTR POINT TO REL ADDRESS OF THE "TALLYING" ITEM
HRRZ TD,EOPLOC
SUBI TE,(TD)
MOVEM TE,ARGSTR
;THERE WAS A TALLYING ITEM. CUREOP NOW POINTS TO IT.
HRRZ TC,CUREOP ;POINTER IN TC FOR SETOPA
MOVE TD,(TC)
TLNN TD,GNLIT!GNFIGC
JRST UNSG6A ;NOT LIT OR FIG CONST.. OK
$CERR ;?SYNTAX SCAN SHOULD CATCH THIS
;HERE WITH TC POINTING TO THE TALLYING ITEM
UNSG6A: PUSHJ PP,SETOPA ;SET IT UP AS "A"
; (ERRORS RETURN TO PHASE E DRIVER)
TSWF FANUM ;MUST BE NUMERIC
SKIPE EDPLA ; AND CAN'T HAVE ANY DECIMAL PLACES
JRST STRE2
HRRZ TA,EMODEA
CAIN TA,FPMODE ;CAN'T BE COMP-1
JRST STRE2
PUSHJ PP,STRGT3 ;GIVE ERROR IF THE "TALLYING" ITEM IS EDITED
PUSHJ PP,STRGT4 ;MAKE SURE TALLYING ITEM IS BIG ENOUGH
;REMEMBER THERE WAS A TALLYING ITEM
UNSG6B: MOVEI TE,1B19 ;"TALLYING ITEM"
IORM TE,UNSFLG ; SET IT IN THE FLAGS
;GET ALL SUBSCRIPTS INTO %TEMP SO THEY WON'T BE AFFECTED BY THE
; STRING STATEMENT
SETOM ONLYEX
SETOM ALSTMP
HRRZ TC,CUREOP
HRLM TC,OPERND ;PUT WHERE SUBSCA NEEDS IT
PUSHJ PP,SUBSCA
SETZM ONLYEX
SETZM ALSTMP
TSWF FERROR
POPJ PP, ;ERRORS, RETURN
;COPY OPERAND TO TEMTAB SO WE CAN GET IT LATER
HRRZ TE,ARGSTR
ADD TE,EOPLOC ;GET ABS LOC OF OPERAND
HRRZ TC,TE
MOVE TE,1(TC) ;FIND # WORDS TO COPY
LDB TA,TESUBC
LSH TA,1
ADDI TA,2
PUSH PP,TA ;SAVE THE #
PUSHJ PP,GETTEM ; GET THE SPACE IN TEMTAB
HRRZ TB,TA ;REL ADDR
HRRM TA,UNSTLY ; REMEMBER WHERE THE TALLYING OPERAND IS
ADD TA,TEMLOC ;TA: = PTR TO TEMTAB ENTRY
;COPY OPERAND
POP PP,TD ;TD:= # WORDS TO COPY
HRRZ TB,ARGSTR ;GET START OF OPERAND AGAIN
ADD TB,EOPLOC ; INCASE IT GOT MOVED BY GETTEM
PUSHJ PP,COPYOP ;COPY IT..
;TALLYING ITEM'S OPERAND IS NOW IN TEMTAB.
; NOW LH (UNSTLY) = UNDEFINED
; RH (UNSTLY) = REL ADDR IN TEMTAB OF THE TALLYING OPERAND
;NOW GENERATE CODE TO PUT INITIAL VALUE OF TALLYING ITEM IN TL.VAL
SWON FBNUM!FBSIGN ;TL.VAL IS SIGNED AND NUMERIC
SWOFF FBSUB ;NOT SUBSCRIPTED
MOVE TB,[^D36,,TL.VAL##]
MOVEM TB,EBASEB
SETZM EINCRB
MOVEI TE,D1MODE ;1-WORD COMP
MOVEM TE,EMODEB
SETZM EFLAGB
SETZM EDPLB
SETZM EBYTEB
SETZM ETABLB
HRRZ TE,ESIZEA ;SAME SIZE AS "A"
CAILE TE,^D10 ;UNLESS TOO BIG
MOVEI TE,^D10
HRRZM TE,ESIZEB
PUSHJ PP,MXX. ;MOVE "A" TO "B"
TSWF FERROR
POPJ PP, ;GIVE UP IF ERRORS
;GET A TAG WHICH WILL BE ADDRESS OF ROUTINE TO CALL TO STORE
; NEW TALLYING VALUE IN THE TALLY ITEM. CODE GENERATED LATER ON..
PUSHJ PP,GETTAG
HRLM CH,UNSTLY
;NOW LH (UNSTLY) = TAG
; RH (UNSTLY) = ADDR IN TEMTAB OF OPERAND
JRST UNSG8 ;DONE WITH TALLYING ITEM (FOR NOW)
;NO TALLYING ITEM.. GEN CODE TO MOVE 0 TO TL.VAL
UNSG7: MOVE CH,[SETZM.,,TL.VAL##]
PUSHJ PP,PUT.EX
SETZM UNSTLY ;CLEAR TALLY INFO
;HERE WHEN DONE WITH TALLYING ITEM
; DO THE DELIMITERS
UNSG8: MOVEI TE,1 ;AIM AT FIRST DELIMITER
MOVEM TE,ARGSTR ;OR NEXT OPERAND, IF NO DELIMITERS
HLRZ TE,ARGCTR ;GET # DELIMITERS
MOVEM TE,M.ARG1 ;M.ARG1= # DELIMITERS LEFT TO DO
JUMPE TE,UNSG20 ;JUMP IF NO DELIMITERS TO DO
;HERE WITH ARGSTR POINTING AT THE NEXT DELIMITER (REL ADDR IN EOPTAB)
UNSG9: HRRZ TE,ARGSTR
ADD TE,EOPLOC ;MAKE ABS ADDR
HRRM TE,CUREOP ;SETUP CUREOP
HRLM TE,OPERND ;AND OPERND
HRRZ TC,TE ;GET READY TO CALL SETOPA
MOVE TD,(TC) ;GET 1ST WORD OF OPERAND
TLNE TD,GNLIT!GNFIGC ;LITERAL OR FIG. CONST?
JRST UNSG12 ;YES
PUSHJ PP,SETOPA ; PUT DELIMITER IN "A"
; (RETURNS TO PHASE E DRIVER IF ERRORS)
LDB TE,[POINT 3,ETABLA,20]
CAIN TE,TB.MNE## ;SYMBOLIC-CHARACTER?
JRST UNSG14 ;YES
;SET UP ANOTHER DELIMITER ENTRY
PUSHJ PP,TLNKDE ;LINK ANOTHER DELIMITER ENTRY
TSWT FANUM ;SKIP IF NUMERIC DELIMITER
JRST UNSG11 ;NON-NUMERIC
;IF NUMERIC, THE DELIMITER MUST REPRESENT AN INTEGER
HRRZ TE,EMODEA
CAIE TE,FPMODE
SKIPE EDPLA
JRST STRE6
;SET "DELIMITER IS NUMERIC" FLAG
HRRZ TA,CURDE ;CURRENT DELIMITER ENTRY
ADD TA,TEMLOC ;GET ABS ADDRESS
MOVX TE,DE%NUM ;"DELIMITER IS NUMERIC"
IORM TE,.DEFLG(TA) ;SET FLAG IN DE ENTRY
;STORE BSI (WHICH WILL BE THE BSI OF THE SENDING ITEM)
HRRZ TE,USENII
DPB TE,BSI.DE
;IF SUBSCRIPTED, WE WILL HAVE TO COPY THE OPERAND.
TSWT FASUB ;SUBSCRIPTED?
JRST UNSG10 ;NO, PUT BP AND CC IN %LIT
HRRZ TC,CUREOP ;THE DELIMITER OPERAND
MOVE TE,1(TC) ;HOW MANY SUBSCRIPTS?
LDB TA,TESUBC
LSH TA,1
ADDI TA,2
PUSH PP,TA ;SAVE # WORDS
PUSHJ PP,GETTEM ;GET WORDS IN TEMTAB
HRRZ TE,TA ;GET REL POINTER
;SET UP LINK IN DE ENTRY
HRRZ TD,CURDE
ADD TD,TEMLOC
MOVEM TA,.DEOPR(TD)
;COPY THE OPERAND
ADD TA,TEMLOC ;TA POINTS TO TEMTAB ENTRY
HRRZ TB,ARGSTR ;FIND DELIMITER OPERAND AGAIN
ADD TB,EOPLOC ; (GETTEM MAY HAVE MOVED IT)
POP PP,TD ;TD:= # WORDS TO MOVE
PUSHJ PP,COPYOP ;COPY IT..
;HERE WHEN DONE COPYING THE OPERAND AND SETTING UP THE LINK TO IT
;IF SUBSCRIPTED, BP AND CC WILL GO IN %TEMP.
MOVEI TE,2 ;GET 2 WORDS IN %TEMP
PUSHJ PP,GETEMP ;%TEMP+NN IN EACC
;STORE %TEMP POINTER IN DE ENTRY
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB EACC,DPL.DL ;STORE POINTER
;GET TAG TO USE TO GEN CODE
PUSHJ PP,GETTAG
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB CH,DE.TAG
JRST UNSG15 ;DONE WITH THIS DELIMITER
;NUMERIC DELIMITER, CAN PUT BP AND CC DIRECTLY INTO %LIT.
; BUT FIRST, HAVE TO MOVE IT TO AN UNSIGNED NUMERIC TEMP.
UNSG10: HRRZ TE,USENII ;CONVERT TO BSI OF SENDING ITEM
PUSHJ PP,MVAUN0 ;MOVE "A" TO AN UNSIGNED TEMP
;NOW THE %TEMP IS IN "A"
PUSHJ PP,GTLBPC ;PUT BP AND CC IN %LIT
HRRZ TA,CURDE ;;STORE %LIT IN DE ENTRY
ADD TA,TEMLOC
DPB TE,DPL.DL
JRST UNSG15 ;DONE WITH THIS DELIMITER
;HERE IF DELIMITER WAS A NON-NUMERIC DATANAME
UNSG11: HRRZ TE,EMODEA ;CHECK FOR SOME KIND OF DISPLAY
CAILE TE,DSMODE
$CERR ;?INSANITY
;STORE BSI IN ENTRY
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB TE,BSI.DE
;IF SUBSCRIPTING OR DEPENDING VARIABLES, WE HAVE TO
; GET A TAG, COPY OPERAND, AND PUT BP AND CC IN %TEMP.
; ELSE WE CAN JUST PUT IT IN %LIT.
PUSHJ PP,DEPTSA ;DEPENDING VARIABLES?
TSWF FASUB ; AND/OR SUBSCRIPTING?
JRST UNS11A ;YES, DO LOTS OF WORK
;PUT THE STUFF IN %LIT
PUSHJ PP,GTLBPC ;PUT IN %LIT
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB TE,DPL.DL
JRST UNSG15 ;DONE WITH THIS DELIMITER
;NON-NUMERIC DELIMITER, WITH SUBSCRIPTING AND/OR DEPENDING ITEM
UNS11A: PUSHJ PP,GETTAG ;WELL, GET A TAG
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB CH,DE.TAG ;STORE THE TAG AWAY
;COPY OPERAND TO TEMTAB
HRRZ TA,ARGSTR
ADD TA,EOPLOC
MOVE TE,1(TA) ;FIND HOW MANY SUBSCRIPT WORDS
LDB TA,TESUBC
LSH TA,1
ADDI TA,2 ;+2 FOR BASE ITEM
PUSH PP,TA ;SAVE # WORDS TO COPY
PUSHJ PP,GETTEM ;GET THE WORDS IN TEMTAB
HRRZ TB,CURDE ;STORE LINK IN DE ENTRY
ADD TB,TEMLOC
MOVEM TA,.DEOPR(TB)
POP PP,TD ;# WORDS TO COPY
ADD TA,TEMLOC ;TA:= START OF TEMTAB BLOCK
HRRZ TB,ARGSTR ;POINT TO OPERAND AGAIN
ADD TB,EOPLOC
PUSHJ PP,COPYOP ;COPY IT..
;GET 2 TEMP LOCS TO USE FOR BP AND CC OF THIS DELIMITER
MOVEI TE,2
PUSHJ PP,GETEMP
;STORE %TEMP POINTER IN DE ENTRY
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB EACC,DPL.DL ;STORE POINTER TO %TEMP
JRST UNSG15 ;DONE WITH THIS DELIMITER
;HERE IF DELIMITER WAS LITERAL OR FIG. CONST
UNSG12: HRRZ EACA,USENII ;USE MODE OF SENDING ITEM, IF POSSIBLE
PUSHJ PP,SETLFC ;SET IT UP
POPJ PP, ;ERRORS, RETURN TO PHASE E DRIVER
UNSG13: PUSH PP,EACC ;SAVE %LIT PTR
PUSHJ PP,TLNKDE ;GET A DE ENTRY
POP PP,EACC ;RESTORE %LIT PTR
HRRZM EACC,EINCRA
MOVE TE,[^D36,,AS.MSC]
MOVEM TE,EBASEA
SETZM ETABLA ;[1364] ZERO LINK TO SOURCE FIELD
PUSHJ PP,GTLBPC ;PUT 2-WORD ENTRY IN LITERAL TABLE
HRRZ TA,CURDE
ADD TA,TEMLOC
DPB TE,DPL.DL ;STORE %LIT PTR
HRRZ TE,EMODEA ;GET MODE
DPB TE,BSI.DE ;STORE IT IN ENTRY
JRST UNSG15 ;DONE WITH THIS DELIMITER
;HERE IF DELIMITER IS A SYMBOLIC-CHARACTER
UNSG14: HRRZ TA,ETABLA
PUSHJ PP,LNKSET ;POINT TO MNETAB
LDB EACC,MN.ESC## ;SEE IF EBCDIC SYMBOLIC CHAR
SKIPE EACC ;SKIP IF ASCII
SKIPA EACA,[D9MODE] ;ITS EBCDIC
MOVEI EACA,D7MODE ;MODE TO MAKE LITERAL
LDB EACC,MN.SCV## ;GET SYMBOLIC-CHARACTER
PUSHJ PP,SETLF2 ;SETUP THE LITERAL
POPJ PP, ;ERROR, SHOULD NEVER HAPPEN
JRST UNSG13 ;COMMON CODE
;HERE WHEN DONE THIS DELIMITER
UNSG15: HRRZ TE,ARGSTR ;POINT TO NEXT DELIMITER
ADD TE,EOPLOC
HRRM TE,CUREOP
PUSHJ PP,BMPEOP
$CERR ;?ERROR
MOVE TC,CUREOP ;CHECK FOR "ALL" FLAG
MOVE TC,1(TC) ;GET OPERAND WORD
TLNE TC,(GWFL9) ;IS 'ALL' FLAG ON?
JRST [MOVE TA,CURDE ;YES, SET IT IN THE ENTRY
ADD TA,TEMLOC
MOVX TD,DE%ALL
IORM TD,.DEFLG(TA)
JRST .+1]
PUSHJ PP,BMPEOP ;SKIP THE UNSDEL 'OPERATOR'
$CERR ;?ERROR
HRRZ TE,CUREOP
HRRZ TD,EOPLOC
SUBI TE,(TD) ;GET NEW REL PTR
MOVEM TE,ARGSTR ;SAVE IN ARGSTR
SOSLE M.ARG1 ; ANY MORE DELIM'S?
JRST UNSG9 ;YES, LOOP
;HERE WHEN DONE THE DELIMITERS
;ARGSTR NOW POINTS TO THE FIRST RECEIVING ITEM
UNSG20: HRRZ TE,ARGCTR ;GET # DESTINATIONS
MOVEM TE,M.ARG1 ;M.ARG1 = # DESTS LEFT TO DO
;HERE WITH ARGSTR POINTING TO THE NEXT RECEIVING ITEM
UNSG21: HRRZ TC,ARGSTR ;POINT TO IT
ADD TC,EOPLOC
HRRM TC,CUREOP
HRLM TC,OPERND ;FOR SUBSCA
MOVE TD,(TC) ;LOOK AT RECEIVING ITEM
TLNE TD,GNLIT!GNFIGC ;BETTER NOT BE A LITERAL OR FIG CONST.
$CERR ; ** PHASE D SHOULD CATCH THIS **
PUSHJ PP,SETOPA ;SET UP RECEIVING ITEM AS "A"
; ERRORS RETURN TO PHASE E DRIVER
PUSHJ PP,TLNKUS ;GET ANOTHER UNSTRING-SERIES ENTRY
TSWT FANUM ;RECEIVING ITEM NUMERIC?
JRST UNSG25 ;NO, NON-NUMERIC
;RECEIVING ITEM IS NUMERIC. IT MAY BE ANY KIND OF NUMERIC, TOO.
; WE WILL HAVE TO GENERATE A ROUTINE TO STORE IT IN THE PROPER PLACE.
PUSHJ PP,GETTAG ;GET A TAG FOR ROUTINE
HRRZ TA,CURUS ;STORE IN ENTRY
ADD TA,TEMLOC
DPB CH,TAG.OR ;STORE TAG FOR RECEIVING ITEM
;SET "NUMERIC" BIT
MOVX TE,US%NUR!US%RRJ ;NUMERIC (THEREFORE RIGHT-JUSTIFIED)
;RECEIVING ITEM
IORM TE,.USFLG(TA)
;COPY OPERAND
HRRZ TE,ARGSTR ;POINT TO OPERAND
ADD TE,EOPLOC
MOVE TE,1(TE) ;FIND SUBSC COUNT
LDB TA,TESUBC
LSH TA,1
ADDI TA,2 ;# WORDS TO COPY
PUSH PP,TA ;SAVE # WORDS TO COPY
PUSHJ PP,GETTEM ;GET A TEMTAB ENTRY FOR THE OPERAND
HRRZ TE,TA
HRRZ TA,CURUS ;STORE POINTER IN THE ENTRY
ADD TA,TEMLOC
MOVEM TE,.USPTR(TA) ;POINTER TO RECEIVING ITEM'S OPERAND
POP PP,TD ;TD:= # WORDS TO COPY
HRRZ TA,TE ;GET ABS PLACE TO PUT IT
ADD TA,TEMLOC
HRRZ TB,ARGSTR ;TB POINTS TO OPERAND NOW
ADD TB,EOPLOC
PUSHJ PP,COPYOP ;COPY IT..
;GET 2-WORD %LIT ENTRY WHICH WILL POINT TO OU.TMP
;FAKE "A" UP AS OU.TMP
MOVE TE,[^D36,,OU.TMP##]
MOVEM TE,EBASEA
SETZM EINCRA
HRRZ TE,USENII ;BSI OF THE SENDING ITEM
MOVEM TE,EMODEA
;LEAVE SAME SIZE AS THE NUMERIC ITEM.
; (DECIMAL PLACES AND EDITED ITEMS MAY REQUIRE SPECIAL PROCESSING HERE!)
MOVN TE,EDPLA ;GET # DECIMAL PLACES
ADDB TE,ESIZEA ; FAKE SIZE = SIZE - DEC PLACES
JUMPG TE,UNSG24 ;JUMP IF ANY SIZE LEFT AT ALL
;DIAG.-- ZEROES PUT INTO ...
SETZM ESIZEA ;CLEAR SIZE
UNSG24: PUSHJ PP,GTLBPC ;GET 2-WORD %LIT ENTRY
HRRZ TA,CURUS ;STORE %LIT POINTER IN ENTRY
ADD TA,TEMLOC
DPB TE,DPL.UR
;STORE BSI OF IT
HRRZ TE,USENII
DPB TE,BSI.UR
JRST UNSG30 ;DONE WITH RECEIVING ITEM
;HERE IF RECEIVING ITEM IS NON-NUMERIC.
UNSG25: HRRZ TE,EMODEA ;SANITY CHECK
CAILE TE,DSMODE ; TO MAKE SURE IT'S DISPLAY
$CERR ;?? YUK, A BUG.
;STORE BSI IN TEMTAB ENTRY
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB TE,BSI.UR
;STORE RIGHT-JUSTIFY FLAG IF WE SHOULD
HRRZ TA,ETABLA
PUSHJ PP,LNKSET
LDB TE,DA.JST
JUMPE TE,UNSG26 ;NOT RIGHT-JUSTIFIED
HRRZ TA,CURUS
ADD TA,TEMLOC
MOVX TE,US%RRJ ;RECEIVING ITEM IS RIGHT-JUSTIFIED
IORM TE,.USFLG(TA) ;SET THE FLAG
UNSG26: PUSHJ PP,DEPTSA ;DOES IT HAVE A DEPENDING VARIABLE?
TSWF FASUB ;OR SUBSCRIPTED?
JRST UNSG27 ;YES, STORE OPERAND, AND SUCH
;BUILD POINTER IN LITAB
PUSHJ PP,GTLBPC ;PUT IN %LIT
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB TE,DPL.UR ;STORE POINTER TO %LIT
JRST UNSG30 ;DONE WITH RECEIVING ITEM
;HERE FOR NON-NUMERIC RECEIVING ITEM WITH SUBSCRIPTS OR DEPENDING VARIABLES.
UNSG27: PUSHJ PP,GETTAG ;GET A TAG
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB CH,TAG.UR ;STORE IT
;COPY OPERAND TO TEMTAB
HRRZ TA,ARGSTR
ADD TA,EOPLOC
MOVE TE,1(TA)
LDB TA,TESUBC
LSH TA,1
ADDI TA,2
PUSH PP,TA
PUSHJ PP,GETTEM
HRRZ TB,CURUS
ADD TB,TEMLOC
MOVEM TA,.USPTR(TB) ;STORE LINK TO RECEIVING ITEM OPERAND
POP PP,TD ;# WORDS TO COPY
ADD TA,TEMLOC ;TA:=START OF TEMTAB BLOCK
HRRZ TB,ARGSTR
ADD TB,EOPLOC
PUSHJ PP,COPYOP ;COPY IT..
;GET 2 %TEMP LOCS AND USE FOR BP AND CC
MOVEI TE,2
PUSHJ PP,GETEMP
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB EACC,DPL.UR ;STORE PTR TO %TEMP
; JRST UNSG30 ;DONE WITH RECEIVING ITEM
;HERE WHEN DONE WITH RECEIVING ITEM
UNSG30: HRRZ TE,ARGSTR ;GET READY TO CALL BMPEOP
ADD TE,EOPLOC
HRRM TE,CUREOP
PUSHJ PP,BMPEOP ;GO GET THE DELIMITER-STORE OPERAND
$CERR ;?? (-2 + 0) STORED
HRRZ TE,CUREOP ;GET ARGSTR POINTING TO
HRRZ TD,EOPLOC ; THE DELIM-STORE OPERAND NOW
SUBI TE,(TD)
MOVEM TE,ARGSTR ;. .
HRRZ TC,CUREOP
MOVE TD,(TC) ;GET 1ST WORD
CAMN TD,[-2] ; IF -2, THERE IS NO DELIMITER STORE
JRST UNSG40 ;"DONE DELIMITER STORE"
TLNE TD,GNLIT!GNFIGC ;CAN'T BE A LITERAL OR FIG. CONST.
$CERR ;** PHASE D SHOULD HAVE CAUGHT IT **
HRRZ TA,CURUS ;SET FLAG SAYING WE GOT A DELIMITER STORE
ADD TA,TEMLOC
MOVX TE,US%GDS ;"GOT A DELIMITER-STORE ITEM"
IORM TE,.USFLG(TA)
;TC, AND CUREOP STILL POINT AT THE DELIMITER-STORE OPERAND
PUSHJ PP,SETOPA ;SET IT UP AS "A" OPERAND
; (ERRORS RETURN TO PHASE E DRIVER)
TSWT FANUM ;SKIP IF NUMERIC
JRST UNSG35 ;"NON-NUMERIC DELIMITER-STORE"
;DELIMITER-STORE IS NUMERIC.
PUSHJ PP,GETTAG ;GET A TAG FOR ROUTINE TO CALL
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB CH,TAG.SD ;STORE TAG TO STORE DELIM-STORE AWAY
MOVX TE,DS%NUM!DS%JST ;NUMERIC
IORM TE,.USDSF(TA) ;SET FLAGS
;COPY OPERAND
HRRZ TA,ARGSTR
ADD TA,EOPLOC
MOVE TE,1(TA)
LDB TA,TESUBC
LSH TA,1
ADDI TA,2
PUSH PP,TA ;SAVE # WORDS TO COPY
PUSHJ PP,GETTEM
HRRZ TB,CURUS
ADD TB,TEMLOC
MOVEM TA,.USPTD(TB) ;POINTER TO DELIMITER-STORE OPERAND
POP PP,TD ;# WORDS TO COPY
ADD TA,TEMLOC ;TA:= START OF TEMTAB BLOCK
HRRZ TB,ARGSTR
ADD TB,EOPLOC
PUSHJ PP,COPYOP ;COPY IT..
;GET 2-WORD %LIT ENTRY WHICH WILL POINT TO OU.TMP
;FAKE "A" UP AS OU.TMP
MOVE TE,[^D36,,OU.TMP##]
MOVEM TE,EBASEA
SETZM EINCRA
HRRZ TE,USENII ;BSI OF THE SENDING ITEM
MOVEM TE,EMODEA
;LEAVE SAME SIZE AS THE NUMERIC ITEM.
; (DEC. PLACES MAY REQUIRE SPECIAL PROCESSING..!)
PUSHJ PP,GTLBPC ;GET 2-WORD %LIT ENTRY
HRRZ TA,CURUS ;STORE %LIT PTR IN ENTRY
ADD TA,TEMLOC
DPB TE,UPT.DS
;STORE BSI OF IT
HRRZ TE,USENII
DPB TE,BSI.DS
JRST UNSG40 ;DONE WITH DELIMITER ITEM
;HERE IF DELIMITER-STORE IS NON-NUMERIC
UNSG35: HRRZ TE,EMODEA ;SANITY CHECK ON MODE
CAILE TE,DSMODE
$CERR
;STORE BSI IN ENTRY
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB TE,BSI.DS ;STORE BSI OF DELIMITER-STORE
;STORE RIGHT-JUSTIFIED FLAG IF WE SHOULD
HRRZ TA,ETABLA
PUSHJ PP,LNKSET
LDB TE,DA.JST
JUMPE TE,UNSG36 ;JUMP IF NOT JUSTIFIED
HRRZ TA,CURUS ;POINT TO ENTRY AGAIN
ADD TA,TEMLOC
MOVX TE,DS%JST ;"DELIMITER-STORE IS RIGHT-JUSTIFIED"
IORM TE,.USDSF(TA) ; SET FLAG IN ENTRY
UNSG36: PUSHJ PP,DEPTSA ;DEPENDING VARIABLE?
TSWF FASUB ; OR SUBSCRIPTS?
JRST UNSG37 ;YES, COPY OPERAND
;PUT THE STUFF IN %LIT
PUSHJ PP,GTLBPC ;PUT IN %LIT
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB TE,UPT.DS ;STORE %LIT PTR IN ENTRY
JRST UNSG40 ;DONE WITH THE DELIMITER-STORE ITEM
;HERE IF NON-NUMERIC DELIMITER-STORE, WITH SUBSCRIPTS AND/OR DEPENDING VARS
UNSG37: PUSHJ PP,GETTAG ;GET A TAG FOR RUNTIME CALL
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB CH,TAG.DT ;STORE TAG - ROUTINE WILL SETUP BP AND CC
MOVEI TE,2 ;GET 2-WORD LOC IN %TEMP
PUSHJ PP,GETEMP ;%TEMP+NN IN EACC
;STORE ADDR OF %TEMP BLOCK FOR DELIMITER-STORE ITEM
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB EACC,UPT.DS
;COPY THE OPERAND
HRRZ TA,ARGSTR
ADD TA,EOPLOC
MOVE TE,1(TA)
LDB TA,TESUBC
LSH TA,1
ADDI TA,2
PUSH PP,TA ;SAVE # WORDS IN OPERAND
PUSHJ PP,GETTEM
HRRZ TB,CURUS
ADD TB,TEMLOC
MOVEM TA,.USPTD(TB) ;POINTER TO DEL-STORE OPERAND
POP PP,TD ;# WORDS TO COPY
ADD TA,TEMLOC ;TA:= START OF TEMTAB BLOCK
HRRZ TB,ARGSTR
ADD TB,EOPLOC ;TB:= START OF OPERAND
PUSHJ PP,COPYOP ;COPY IT...
; JRST UNSG40 ;DONE WITH DELIMITER-STORE ITEM
;HERE WHEN DONE WITH THE DELIMITER-STORE ITEM
UNSG40: HRRZ TE,ARGSTR
ADD TE,EOPLOC
HRRM TE,CUREOP
PUSHJ PP,BMPEOP ;POINT TO COUNT-ITEM
$CERR ;? (-2 + 0) STORED
HRRZ TE,CUREOP ;GET ARGSTR POINTING TO COUNT-ITEM NOW
HRRZ TD,EOPLOC
SUBI TE,(TD)
MOVEM TE,ARGSTR
HRRZ TC,CUREOP
MOVE TD,(TC) ;GET 1ST WORD OF OPERAND
CAMN TD,[-2] ; NO OPERAND?
JRST UNSG50 ;YES, SKIP THIS
TLNE TD,GNLIT!GNFIGC ;BETTER BE A REAL DATANAME
$CERR ;?SYNTAX SCAN SHOULD CATCH THIS
;COUNT ITEM MUST BE NUMERIC.
PUSHJ PP,SETOPA ;SET IT UP AS "A"
; IF ERRORS, RETURN TO PHASE E DRIVER
TSWT FANUM
JRST STRE2
HRRZ TE,EMODEA ;CAN'T BE FLOATING POINT
CAIE TE,FPMODE
SKIPE EDPLA ;AND NO DECIMAL PLACES!
JRST STRE2
PUSHJ PP,STRGT3 ;GIVE ERROR IF THE "COUNT" ITEM IS EDITED
;SEE IF COUNT ITEM IS BIG ENOUGH TO HOLD ALL THE CHARACTERS IN THE SOURCE.
PUSHJ PP,STRGT4 ;MAKE TEST
;COUNT ITEM SEEMS TO BE OK. STORE OPERAND IN TEMTAB AND GENERATE A TAG.
UNSG41: PUSHJ PP,GETTAG ;GET A TAG FOR RUNTIME ROUTINE
HRRZ TA,CURUS
ADD TA,TEMLOC
DPB CH,TAG.CT ;TAG TO STORE COUNT ITEM
;STORE OPERAND.
HRRZ TA,ARGSTR
ADD TA,EOPLOC
MOVE TE,1(TA)
LDB TA,TESUBC
LSH TA,1
ADDI TA,2
PUSH PP,TA ;SAVE # WORDS TO COPY
PUSHJ PP,GETTEM ;GET THE WORDS IN TEMTAB
HRRZ TB,CURUS
ADD TB,TEMLOC
MOVEM TA,.USPTC(TB) ;SAVE PTR TO "COUNT" ITEM
POP PP,TD ;HO, HUM THIS CODE AGAIN
ADD TA,TEMLOC
HRRZ TB,ARGSTR ;NOT EVEN BOTHERING TO COMMENT
ADD TB,EOPLOC ; IT INTELLIGENTLY..
PUSHJ PP,COPYOP ;COPY IT..
HRRZ TA,CURUS ;POINT AT ENTRY
ADD TA,TEMLOC
MOVX TE,US%GCT ;"GOT A COUNT ITEM"
IORM TE,.USFLG(TA) ; SET FLAG IN ENTRY
; JRST UNSG50 ;DONE WITH "COUNT" ITEM
;HERE WHEN DONE WITH "COUNT" ITEM.
UNSG50: SOSG M.ARG1 ;MORE UNSTRING-SERIES?
JRST UNSG55 ;NO--DONE
HRRZ TE,ARGSTR ;BMPEOP TO NEXT ITEM
ADD TE,EOPLOC
HRRM TE,CUREOP
PUSHJ PP,BMPEOP
$CERR ;??BUT THERE WAS MORE
PUSHJ PP,BMPEOP ;SKIP OVER -1+W1
$CERR
HRRZ TE,CUREOP ;GET ARGSTR POINTING TO NEXT INTO ITEM
HRRZ TD,EOPLOC
SUBI TE,(TD)
MOVEM TE,ARGSTR
JRST UNSG21 ;GO ON TO NEXT UNSTRING-ENTRY
;GO TO UNSG55 ON NEXT PAGE WHEN WE ARE DONE WITH ALL UNSTRING-SERIES.
; THIS IS THE FIRST PASS OF UNSTRING CODE GENERATION.
;ALL ARGS ARE NOW SETUP IN TEMTAB. THE 2ND "PASS"
; IS GENERATING THE RUNTIME ROUTINES WHICH ARE "PUSHJ'D" TO.
;HERE WHEN DONE ALL UNSTRING-SERIES
; ** ALL ARGS ARE NOW SETUP IN TEMTAB **
;NOW WE CAN START GENERATING ROUTINES.
; USE M.ARG1 AS A FLAG... = 0 UNTIL JUMP HAS BEEN GENERATED
;AROUND THE %TAGS. THEN IT IS AS.TAG+N FOR THE PLACE TO GO.
UNSG55: SETZM M.ARG1 ;JUMP NOT GENERATED YET
SKIPN STPTO ;SKIP IF ANY POINTER ITEM
JRST UNS55E ;NO
;GENERATE CODE TO STORE THE POINTER ITEM
PUSHJ PP,PUTJMP ;PUT "JRST" OUT IF NECESSARY
HLRZ CH,STPTO ;GET TAG OF POINTER ROUTINE
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;WRITE IT OUT
;GEN A MOVE FROM PT.VAL TO THE POINTER ITEM.
; WE WILL SETUP THE POINTER ITEM AS "B".
HRRZ TC,STPTO ;GET OFFSET INTO TEMTAB OF THE OPERAND
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRRM TC,OPERND
PUSHJ PP,SETOPB ;SET IT UP AS "B"
;FAKE AN "A" OPERAND TO BE PT.VAL
PUSHJ PP,FAKPTV
PUSHJ PP,MXX. ;MOVE "A" TO "B"
TSWF FERROR ;IF ERRORS,
POPJ PP, ;GIVE UP
;WRITE POPJ TO END ROUTINE
PUSHJ PP,PUTPPJ
;HERE WHEN DONE WITH THE POINTER ITEM ROUTINE
UNS55E: SKIPN UNSTLY ;SKIP IF ANY TALLYING ITEM
JRST UNS55M ;NO
;GENERATE CODE TO STORE THE TALLYING ITEM
PUSHJ PP,PUTJMP ;PUT "JRST" OUT IF NECESSARY
HLRZ CH,UNSTLY ;GET TAG OF TALLYING ROUTINE
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;WRITE IT OUT
;GEN A MOVE FROM TL.VAL TO THE TALLYING ITEM.
HRRZ TC,UNSTLY
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRRM TC,OPERND ;FOR SUBSCB
PUSHJ PP,SETOPB ;SET IT UP AS "B"
PUSHJ PP,FAKTLV ;FAKE "A" AS TL.VAL
PUSHJ PP,MXX. ;GENERATE THE 'MOVE'
TSWF FERROR ;IF ERRORS,
POPJ PP, ;QUIT
PUSHJ PP,PUTPPJ ;WRITE POPJ TO END ROUTINE
;HERE WHEN DONE WITH THE TALLYING ITEM ROUTINE
UNS55M: SKIPN TE,UNSDLE ;ANY DELIMITER ENTRIES?
JRST UNSG70 ;NO, SKIP THIS
MOVEM TE,CURDE ;STORE FIRST ENTRY AS "CURRENT ENTRY"
;HERE WITH THE NEXT DELIMITER ENTRY POINTER IN "CURDE"
UNSG56: HRRZ TA,CURDE ;SEE IF ANY CODE TO GENERATE
ADD TA,TEMLOC
LDB TE,DE.TAG ;ANY TAG?
JUMPE TE,UNSG69 ;NO
PUSH PP,TE ;SAVE TAG
PUSHJ PP,PUTJMP ;PUT "JRST" OVER ROUTINE
POP PP,CH ;RESTORE TAG
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;OUTPUT IT
;SETUP M.ARG2 = PTR TO %LIT OR %TEMP FOR BP AND CC
HRRZ TA,CURDE
ADD TA,TEMLOC
LDB TE,DPL.DL ;GET THE %TEMP OR %LIT WE WILL USE FOR BP AND CC
MOVEM TE,M.ARG2 ;STORE IN M.ARG2 FOR A MINUTE.
;SETUP THE OPERAND AS "A"
HRRZ TA,CURDE
ADD TA,TEMLOC
SKIPN TC,.DEOPR(TA) ;GET PTR TO OPERAND
$CERR ;?? OOPS
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRLM TC,OPERND
PUSHJ PP,SETOPA ;SET IT UP AS "A"
TSWT FANUM ;SKIP IF NUMERIC
JRST UNSG62 ;NON-NUMERIC
;NUMERIC DELIMITER.
;MOVE UNSIGNED TO %TEMP
HRRZ TE,USENII ;GET BSI
PUSHJ PP,MVAUN0 ;MOVE "A" TO UNSIGNED %TEMP
;NOW THE %TEMP IS IN "A"
;GEN CODE TO STORE BP IN THE %TEMP+0
MOVE TA,[BYTLIT,,2] ;PREPARE TO WRITE BP
PUSHJ PP,STASHP
HRRZ TA,EBASEA
PUSHJ PP,STASHQ
HLRZ TA,ERESA
ROT TA,-6
HRRZ TC,EMODEA
MOVE TC,BYTE.S(TC)
DPB TC,[POINT 6,TA,11]
HRR TA,EINCRA ;%TEMP+N
PUSHJ PP,POOLIT ;POOL BYTE PTR
SKIPN TE,PLITPC ;WAS IT POOLED
HRRZ TE,ELITPC ;NO, GET PC
SKIPN PLITPC ;SKIP IF POOLED
AOS ELITPC ;NO, BUMP PC
MOVE CH,[MOV+AC5+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,TE
IORI CH,AS.LIT
PUSHJ PP,PUTASN ;"MOVE AC5,[BYTE PTR TO NUMERIC ARG IN %TEMP]"
MOVE CH,[MOVEM.+AC5+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;AS.TMP+N
PUSHJ PP,PUTASN ;"MOVEM AC5,%TEMP+0"
;GEN CODE TO GET CC
PUSHJ PP,GTCCA ;GET CHARACTER-COUNT OF "A"
MOVE CH,[MOVEM.+AC7+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;GET PTR TO %TEMP
ADDI CH,1 ;ADD 1
PUSHJ PP,PUTASN ;FINISH "MOVEM AC7,%TEMP+1"
PUSHJ PP,PUTPPJ ;GEN POPJ TO END ROUTINE
JRST UNSG69 ;DONE WITH THIS DELIMITER
;HERE FOR NON-NUMERIC DELIMITER
UNSG62: PUSHJ PP,NB1PAR ;GET BP IN AC5
MOVE CH,[MOVEM.+AC5+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;PTR TO %TEMP
PUSHJ PP,PUTASN ;FINISH STORING BP
;STORE CC
PUSHJ PP,DEPTSA ;DOES IT HAVE A DEPENDING ITEM?
JRST UNSG64 ;NO, USE "MOVEI"
MOVEI TE,7 ;YES, USE RUNTIME AC7 TO GET SIZE
SETZM SAVPR0 ;DON'T SAVE %PARAM
PUSHJ PP,SZDPVA ;GET SIZE IN RUNTIME AC7
$CERR ;?? NO ERRORS SHOULD OCCUR
JRST UNSG65 ;STORE SIZE AWAY
UNSG64: PUSHJ PP,GTCCA ;PUT FIXED SIZE IN RUNTIME AC7
UNSG65: MOVE CH,[MOVEM.+AC7+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;PTR TO %TEMP
ADDI CH,1 ; MAKE IT %TEMP+1
PUSHJ PP,PUTASN ;STORE SIZE THERE
PUSHJ PP,PUTPPJ ;GEN POPJ TO END ROUTINE
;HERE WHEN DONE A DELIMITER
UNSG69: HRRZ TA,CURDE
ADD TA,TEMLOC
SKIPN TE,.DELNK(TA) ;SKIP IF ANY MORE DELIMITERS
JRST UNSG70 ;NO--GO ON TO 'INTO' ITEMS
MOVEM TE,CURDE ;YES, STORE NEXT ONE
JRST UNSG56 ;AND GO PROCESS IT
;HERE WHEN DONE ALL THE DELIMITER ENTRIES
; GENERATE ROUTINES FOR THE 'INTO' ENTRIES
UNSG70: SKIPN TA,STSETP ;POINT TO 1ST ENTRY
$CERR ;?MUST BE AT LEAST 1
;HERE WITH TA POINTING TO NEXT 'INTO' ENTRY
UNSG71: MOVEM TA,CURUS ;SAVE 'CURRENT UNSTRING-SERIES' ENTRY
ADD TA,TEMLOC
LDB CH,TAG.UR ;GET TAG IF THERE.
SKIPN CH ;%TAG1 OR %TAG2: THEY ARE MUTUALLY EXCLUSIVE
LDB CH,TAG.OR ; THIS IS PRESENT IF NUMERIC DESTINATION
JUMPE CH,UNSG74 ;JUMP IF NO ROUTINE TO GENERATE
PUSH PP,CH ;SAVE THE TAG
PUSHJ PP,PUTJMP ; JUMP OVER ROUTINE, IF NECESSARY
POP PP,CH ;RESTORE TAG
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;AND PUT IT OUT
HRRZ TA,CURUS
ADD TA,TEMLOC
SKIPN TC,.USPTR(TA) ;GET PTR TO RECEIVING ITEM OPERAND
$CERR ;??MUST BE THERE
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRLM TC,OPERND
PUSHJ PP,SETOPA ;SET IT UP AS "A"
TSWT FANUM ;SKIP IF NUMERIC
JRST UNSG73 ;NON-NUMERIC
;NUMERIC RECEIVING ITEM. GENERATE CODE TO STORE IT AWAY FROM OU.TMP
HLRZ TC,OPERND ;POINT TO OPERAND AGAIN
HRRM TC,OPERND ;MAKE IT THE "B" OPERAND TOO.
PUSHJ PP,SETOPB ;SET IT UP AS "B"
;FAKE "A" AS OU.TMP
;SAME SIZE AS "B", BUT NO DECIMAL PLACES
MOVE TA,[^D36,,OU.TMP##]
MOVEM TA,EBASEA
SETZM EINCRA
HRRZ TA,USENII ;BSI OF SENDING ITEM
MOVEM TA,EMODEA ; = BSI OF OU.TMP
MOVN TA,EDPLA ;GET # DECIMAL PLACES IN FINAL ITEM
ADDB TA,ESIZEA ; FIXUP THE SIZE
SKIPG TA ;ANY SIZE LEFT?
SETZM ESIZEA ;NO, MAKE IT 0 SIZE
SETZM EDPLA ;NO DECIMAL PLACES
SWOFF FASUB!FASIGN ;NOT SUBSCRIPTED, OR SIGNED
TSWF FBSIGN ;[1434] UNLESS B IS SIGNED -
SWON FASIGN ;[1434] THEN PASS IT ON
SETZM ETABLA
SETZM EBYTEA
SETZM EFLAGA
PUSHJ PP,MXX. ;GEN THE "MOVE"
TSWF FERROR ;IF ERRORS,
POPJ PP, ;RETURN
JRST UNS73E ;DONE ROUTINE
;HERE IF RECEIVING ITEM IS NON-NUMERIC. IT MUST BE SUBSCR OR DEP VARIABLES.
UNSG73: PUSHJ PP,NB1PAR ;GET BP IN RUNTIME AC5
HRRZ TA,CURUS
ADD TA,TEMLOC
LDB TE,DPL.UR ;GET PTR TO %TEMP
SKIPN TE ;GOTTA BE SETUP
$CERR
MOVEM TE,M.ARG2 ;SAVE IN M.ARG2 FOR A SEC.
;TO STORE BP: GEN "MOVEM AC5,%TEMP+0"
MOVE CH,[MOVEM.+AC5+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;GET %TEMP
PUSHJ PP,PUTASN
;TO STORE CC: GET SIZE IN RUNTIM AC7
PUSHJ PP,DEPTSA ;DEPENDING VARIABLE?
JRST UNS73A ;NO, GEN "MOVEI"
MOVEI TE,7 ;TO RUNTIME AC7
SETZM SAVPR0 ;DON'T SAVE %PARAM+0
PUSHJ PP,SZDPVA
$CERR ;? YECCH
TRNA
UNS73A: PUSHJ PP,GTCCA ;GEN "MOVEI AC7,<ESIZEA>"
MOVE CH,[MOVEM.+AC7+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;ADDRESS OF %TEMP
ADDI CH,1 ; STORE CC IN 2ND WORD
PUSHJ PP,PUTASN
;GEN "POPJ 17," TO END ROUTINE
UNS73E: PUSHJ PP,PUTPPJ ;WRITE OUT THE POPJ
;HERE WHEN DONE GENERATING THE ROUTINE TO HANDLE THE 'INTO' ITEM.
UNSG74: HRRZ TA,CURUS
ADD TA,TEMLOC
MOVE TE,.USFLG(TA) ;GET FLAG WORD
TXNN TE,US%GDS ;GOT A DELIMITER-STORE ITEM?
JRST UNSG78 ;NO, SKIP THIS CODE
LDB TE,TAG.DT ;SETUP %TEMP WITH BP AND CC?
JUMPE TE,UNSG76 ;NO
PUSH PP,TE ;SAVE THE TAG
PUSHJ PP,PUTJMP ; JUMP OVER ROUTINE, IF NECESSARY
POP PP,CH ;RESTORE TAG
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;PUT IT OUT
HRRZ TA,CURUS
ADD TA,TEMLOC
SKIPN TC,.USPTD(TA) ;GET DEL-STORE OPERAND
$CERR ;?? NOT THERE??
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRLM TC,OPERND
PUSHJ PP,SETOPA ;SET IT UP AS "A"
; THE OPERAND IS SUPPOSEDLY NON-NUMERIC WITH SUBSCR AND/OR DEP VAR.
TSWF FANUM ;MAKE SURE NON-NUMERIC
$CERR ;?? BAD COBOL!
PUSHJ PP,NB1PAR ;GET BP IN RUNTIME AC5
HRRZ TA,CURUS
ADD TA,TEMLOC
LDB TE,UPT.DS ;GET %TEMP PTR
MOVEM TE,M.ARG2 ;SAVE IN M.ARG2 FOR A SEC.
;TO STORE BP: GEN "MOVEM AC5,%TEMP+0"
MOVE CH,[MOVEM.+AC5+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2
PUSHJ PP,PUTASN
;TO STORE CC: GET SIZE IN RUNTIME AC7
PUSHJ PP,DEPTSA ;DEPENDING VARIABLE?
JRST UNSG75 ;NO, GEN "MOVEI"
MOVEI TE,7 ;TO RUNTIME AC7
SETZM SAVPR0 ;DON'T SAVE %PARAM+0
PUSHJ PP,SZDPVA
$CERR
TRNA
UNSG75: PUSHJ PP,GTCCA ;GEN "MOVEI AC7,<ESIZEA>"
MOVE CH,[MOVEM.+AC7+ASINC,,AS.MSC]
PUSHJ PP,PUTASY
HRRZ CH,M.ARG2 ;ADDRESS OF %TEMP
ADDI CH,1 ;STORE CC IN 2ND WORD
PUSHJ PP,PUTASN
;GEN "POPJ 17," TO END ROUTINE
PUSHJ PP,PUTPPJ ;WRITE OUT THE POPJ
;HERE WHEN DONE GENERATING ROUTINE TO SETUP %TEMP WITH BP AND CC
UNSG76: HRRZ TA,CURUS
ADD TA,TEMLOC
LDB TE,TAG.SD ;STORE DELIM AWAY FROM OU.TMP
JUMPE TE,UNSG78 ;JUMP IF NO
PUSH PP,TE ;SAVE TAG
PUSHJ PP,PUTJMP ; JUMP OVER ROUTINE, IF NECESSARY
POP PP,CH ;RESTORE TAG
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;PUT IT OUT
HRRZ TA,CURUS
ADD TA,TEMLOC
SKIPN TC,.USPTD(TA) ;GET OPERAND
$CERR ;?MUST BE THERE
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRLM TC,OPERND
PUSHJ PP,SETOPB ;SET IT UP AS "B"
;OPERAND IS SUPPOSEDLY NUMERIC. ALSO %LIT HAS BEEN SETUP ALREADY
; TO POINT TO OU.TMP.
TSWT FBNUM ;MAKE SURE
$CERR ;; ?IMPLEMENTER ERROR
;FAKE "A" AS OU.TMP
;SAME SIZE AS "B", BUT NO DECIMAL PLACES
MOVE TA,[^D36,,OU.TMP##]
MOVEM TA,EBASEA
SETZM EINCRA
SETZM EDPLA
SWOFF FASUB!FASIGN ;NOT SUBSCRIPTED, OR SIGNED
SWON FANUM ;BUT NUMERIC
SETZM ETABLA
SETZM EBYTEA
SETZM EFLAGA
HRRZ TE,ESIZEB
HRRZM TE,ESIZEA
HRRZ TE,USENII ;BSI OF SENDING ITEM
HRRZM TE,EMODEA ;IS BSI OF THE DELIMITER STORE
PUSHJ PP,MXX. ;GENERATE THE MOVE
TSWF FERROR ;IF ERRORS,
POPJ PP, ;RETURN
;GEN "POPJ 17," TO END ROUTINE
PUSHJ PP,PUTPPJ ;WRITE OUT THE POPJ
;HERE WHEN DONE WITH THE DELIMITER-STORE ROUTINE GEN.
UNSG78: HRRZ TA,CURUS
ADD TA,TEMLOC
LDB TE,TAG.CT ;TAG TO STORE COUNT ITEM?
JUMPE TE,UNSG84 ;NO, WE ARE DONE
PUSH PP,TE ;SAVE TAG
PUSHJ PP,PUTJMP ; JUMP OVER ROUTINE, IF NECESSARY
POP PP,CH ;RESTORE TAG
HRRZ TA,CH ;REFERENCE IT
PUSHJ PP,REFTAG
PUSHJ PP,PUTTAG ;PUT IT OUT
;GEN CODE TO STORE THE "COUNT" ITEM
HRRZ TA,CURUS
ADD TA,TEMLOC
SKIPN TC,.USPTC(TA) ;GET OPERAND POINTER
$CERR ;?MUST BE THERE
ADD TC,TEMLOC
PUSHJ PP,CPYOPP ;COPY OPERAND TO A SAFE PLACE
HRRM TC,CUREOP
HRRM TC,OPERND
PUSHJ PP,SETOPB ;SET IT UP AS "B"
;FAKE AN "A" OPERAND TO BE CT.VAL
PUSHJ PP,FAKCTV
PUSHJ PP,MXX. ;MOVE 'A' TO 'B'
TSWF FERROR
POPJ PP, ;DIE IF ERRORS
;GEN "POPJ 17," TO END ROUTINE
PUSHJ PP,PUTPPJ ;WRITE OUT THE POPJ
; JRST UNSG84 ;DONE WITH THIS UNSTRING-SERIES ENTRY
;HERE WHEN DONE WITH THIS UNSTRING-SERIES ENTRY
;LOOP IF ANY MORE TO DO
UNSG84: HRRZ TA,CURUS
ADD TA,TEMLOC
SKIPE TA,.USLNK(TA) ;GET LINK IF ANY
JRST UNSG71 ;GOT ONE, GEN ROUTINES IF NECESSARY
;HERE WHEN DONE GENERATING ALL ROUTINES.
; GENERATE %TAG IF NECESSARY TO START OFF UNSTRING STMT.
UNSG85: SKIPN CH,M.ARG1 ;"JRST" GENERATED?
JRST UNSG86 ;NO
PUSHJ PP,PUTTAG ;YES, GENERATE %TAG:
;GENERATE THE ARG LIST IN THE LITERALS
UNSG86: HRRZ TE,ELITPC ;SET M.ARG4 TO POINT TO START OF
HRRZM TE,M.ARG4 ; LITERALS, INCASE WE DON'T POOL
;FIRST WORD OF ARG LIST: -N,,FLAGS
; WHERE N= # OF "INTO" ITEMS
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
HRRZ TA,ARGCTR ;# OF "INTO" ITEMS
MOVN TA,TA ;GET -#
HRLE TA,TA ;PUT IN LH
HRRI TA,AS.CNB ; LARGE CONSTANT
PUSHJ PP,STASHQ
HRL TA,UNSFLG ;RH= FLAGS
HRRI TA,AS.CNB
PUSHJ PP,STASHQ ;PUT OUT RH OF XWD
AOS ELITPC
;2ND WORD OF ARG LIST: ID-1 ITEM INFO
; ACTUALLY JUST THE BSI.
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
SETZ TA, ;LH=0
PUSHJ PP,STASHQ
HRRZ TA,USENII ;BSI OF SOURCE IN RH
PUSHJ PP,STASHQ
AOS ELITPC
;3RD WORD OF ARG LIST (OPTIONAL -- ONLY IF THERE WAS A 'POINTER' ITEM.
SKIPN STPTO ;SKIP IF THERE WAS A POINTER ITEM
JRST UNSG87 ;NO, SKIP THIS
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
SETZ TA, ;0 IF LH
PUSHJ PP,STASHQ
HLRZ TA,STPTO ;AS.TAG+N
PUSHJ PP,STASHQ
AOS ELITPC
;4TH WORD OF ARG LIST (OPTIONAL -- ONLY IF THERE WAS A 'TALLYING' ITEM.
UNSG87: SKIPN UNSTLY ;SKIP IF THERE WAS A TALLYING ITEM
JRST UNSG88 ;NO, SKIP THIS
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
SETZ TA, ;0 IN LH
PUSHJ PP,STASHQ
HLRZ TA,UNSTLY ;AS.TAG+N
PUSHJ PP,STASHQ
AOS ELITPC
;5TH WORD OF ARG LIST: OCT M
; WHERE M= # OF DELIMITER ITEMS.
UNSG88: MOVE TA,[OCTLIT,,1]
PUSHJ PP,STASHP
HLRZ TA,ARGCTR ;GET # DELIMS
PUSHJ PP,STASHQ ;WRITE IT OUT
AOS ELITPC
;FOR EACH DELIMITER ITEM, STORE
; FLAGS+BSI.DI,,%LIT
; %TAG OR 0
HLRZ TA,ARGCTR ;GET # TO DO
JUMPE TA,UNSG90 ;JUMP IF NONE
SKIPN TA,UNSDLE ;POINT TO 1ST DELIMITER ENTRY
$CERR ;? BUT THERE WAS AT LEAST ONE!
;HERE WITH TA POINTING TO NEXT DELIMITER ENTRY
UNSG89: MOVEM TA,CURDE ;MAKE IT THE "CURRENT" ENTRY
ADD TA,TEMLOC ;POINT TO ENTRY
MOVE TE,.DEFLG(TA) ;GET FLAG WORD
MOVEM TE,M.ARG3 ; STORE IN M.ARG3 FOR A SECOND.
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP ;READY TO WRITE AN XWD
HLLZ TA,M.ARG3 ;GET LH
HRRI TA,AS.CNB ; A LARGE CONSTANT
PUSHJ PP,STASHQ
HRLZ TA,M.ARG3 ;GET RH
SKIPE TA
HRRI TA,AS.MSC ;%LIT OR %TEMP
PUSHJ PP,STASHQ ;WRITE %LIT OR %TEMP OR 0
AOS ELITPC
;MORE DELIMITER INFO: %TAG OR 0
HRRZ TA,CURDE
ADD TA,TEMLOC
LDB TE,DE.TAG
JUMPE TE,UNS89A ;NO TAG, WRITE OCT 0
MOVEM TE,M.ARG3 ;SAVE %TAG FOR A SEC.
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP ;WRITE AS AN XWD 0,%TAG
SETZ TA,
PUSHJ PP,STASHQ
HRRZ TA,M.ARG3
PUSHJ PP,STASHQ
JRST UNS89B ;SKIP OVER "NO TAG" CODE
UNS89A: MOVE TA,[OCTLIT,,1]
PUSHJ PP,STASHP
SETZ TA,
PUSHJ PP,STASHQ
UNS89B: AOS ELITPC
;SEE IF ANY MORE DELIMITER ITEMS
HRRZ TA,CURDE
ADD TA,TEMLOC
SKIPE TA,.DELNK(TA) ;ANY MORE?
JRST UNSG89 ;YES, LOOP FOR 'EM
;HERE WHEN DONE DELIMITER ITEMS
; STORE THE "INTO" ITEM ENTRIES
;
UNSG90: HRRZ TA,ARGCTR ;HOW MANY "INTO" ITEM ENTRIES
SKIPN TA ;MUST BE AT LEAST 1
$CERR
;FOR EACH INTO ITEM, STORE:
; FLAGS+BSI.UR,,%LIT
; %TAG1,,%TAG2
; FLAGS+BSI.DELSTORE,,%LIT ;(ONLY PRESENT IF A DELIM-STORE ITEM)
; %TAG1,,%TAG2 ;..
; %TAG ;(ONLY PRESENT IF A COUNT ITEM)
SKIPN TA,STSETP ;GET PTR TO FIRST
$CERR ;?? MUST BE THERE
;HERE WITH TA POINTING TO NEXT 'INTO' ITEM ENTRY
UNSG91: MOVEM TA,CURUS
ADD TA,TEMLOC ;POINT TO IT
MOVE TE,.USFLG(TA) ;GET FLAGS FOR DELIMITER
MOVEM TE,M.ARG3 ;SAVE IN M.ARG3
;WRITE OUT FLAG WORD
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
HLLZ TA,M.ARG3 ;LEFT HALF
HRRI TA,AS.CNB
PUSHJ PP,STASHQ
HRLZ TA,M.ARG3
SKIPE TA ;IF 0, LEAVE IT 0
HRRI TA,AS.MSC ; "MISC" FOR %TEMP OR %LIT
PUSHJ PP,STASHQ
AOS ELITPC
;WRITE OUT %TAG1,,TAG2 OR 0'S
HRRZ TA,CURUS
ADD TA,TEMLOC
MOVE TE,.USRTG(TA) ;GET %TAG1,%TAG2
MOVEM TE,M.ARG2 ;STORE IN M.ARG2 FOR A SEC..
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
HLRZ TA,M.ARG2 ;LH TAG OR 0
PUSHJ PP,STASHQ
HRRZ TA,M.ARG2 ;RH TAG OR 0
PUSHJ PP,STASHQ
AOS ELITPC ;BUMP LITERAL PC
;DONE WITH THE 'INTO' ITEM.. SEE IF OPTIONAL 'DELSTORE' ITEM
UNSG93: MOVE TE,M.ARG3 ;GET FLAGS FROM THE 'INTO' ITEM ENTRY
TXNN TE,US%GDS ;SKIP IF WE GOT A DELSTORE ITEM
JRST UNSG94 ;NO, SKIP THIS
MOVEM TE,M.ARG2 ;SAVE FLAGS IN M.ARG2 NOW
HRRZ TA,CURUS
ADD TA,TEMLOC ;FIND FLAG WORD FOR THE 'DELSTORE' ITEM
MOVE TE,.USDSF(TA) ; GET IT
MOVEM TE,M.ARG3 ;SAVE IN M.ARG3
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
HLLZ TA,M.ARG3
HRRI TA,AS.CNB ;LARGE CONSTANT
PUSHJ PP,STASHQ
HRLZ TA,M.ARG3
SKIPE TA
HRRI TA,AS.MSC
PUSHJ PP,STASHQ ;%LIT, OR %TEMP, OR 0
AOS ELITPC
HRRZ TA,CURUS
ADD TA,TEMLOC
MOVE TE,.USDTG(TA) ;GET TAG WORD FOR DELIMITER STORE
MOVEM TE,M.ARG3 ;COULD BE %TAG,,%TAG
MOVE TA,[XWDLIT,,2]
PUSHJ PP,STASHP
HLRZ TA,M.ARG3 ;LH TAG OR 0
PUSHJ PP,STASHQ ;WRITE TAG OR 0
HRRZ TA,M.ARG3 ;RH TAG
PUSHJ PP,STASHQ ;WRITE TAG OR 0
AOS ELITPC
SKIPA TE,M.ARG2 ;GET 'INTO ITEM' FLAGS AGAIN
;CHECK FOR COUNT ITEM.. IF PRESENT, WRITE THE %TAG
UNSG94: MOVE TE,M.ARG3 ;GET FLAGS FROM THE 'INTO' ITEM ENTRY
TXNN TE,US%GCT ;SKIP IF WE GOT A 'COUNT' ITEM
JRST UNS94D ;NOPE, DONE
MOVE TA,[XWDLIT,,2] ;READY TO GENERATE A %TAG
PUSHJ PP,STASHP
SETZ TA,
PUSHJ PP,STASHQ
HRRZ TA,CURUS ;FIND THE %TAG
ADD TA,TEMLOC
LDB TA,TAG.CT ;GET TAG FOR COUNT ITEM
SKIPN TA ;MUST BE THERE
$CERR
PUSHJ PP,STASHQ ;WRITE IT OUT
AOS ELITPC ;BUMP LITERAL PC
;HERE WHEN DONE WITH THIS 'INTO' ENTRY
UNS94D: HRRZ TA,CURUS
ADD TA,TEMLOC
SKIPE TA,.USLNK(TA) ;ANY MORE?
JRST UNSG91 ;YES, LOOP
;HERE WHEN DONE WRITING THE ARG LIST TO TEMTAB.
; SEE WHAT WE GOT
UNSG95: PUSHJ PP,POOL ;TRY TO POOL IT
;GENERATE "MOVEI 16,ARG.LIST"
; "PUSHJ 17,UNS. OR UNS.O"
SKIPN TE,PLITPC ;DID WE POOL?
HRRZ TE,M.ARG4 ;NO, GET STARTING LITERAL
MOVEM TE,LITNN ;STORE ADDRESS OF ARG LIST
SKIPE PLITPC ;DID WE POOL?
JRST [HRRZ TE,M.ARG4 ;YES, RESTORE START OF LITERALS
MOVEM TE,ELITPC
JRST .+1]
MOVEI TA,UNS.## ;GENERATE "MOVEI" AND "PUSHJ"
TLNE W1,(GWFL9) ; HAVE AN "OVERFLOW" CLAUSE?
MOVEI TA,UNS.O## ;YES, CALL OTHER ROUTINE
PJRST CSEQGN ;RETURN FROM 'UNSTRING' CODE GEN.
SUBTTL ERROR ROUTINES.
STRE1: MOVEI DW,E.373 ;[604] ?IMPROPER USAGE
JRST OPNFAT
STRE2: MOVEI DW,E.264 ;?NOT AN INTEGER DATA ITEM
JRST OPNFAT
;GIVE ERROR IF THE "POINTER" OR "TALLY" ITEM IS EDITED
STRGT3: HRRZ TA,ETABLA
PUSHJ PP,LNKSET
LDB TE,DA.EDT
JUMPN TE,STRE3
LDB TE,DA.BWZ
JUMPE TE,CPOPJ
STRE3: MOVEI DW,E.464 ;?CANNOT BE AN EDITED ITEM
JRST OPNFAT
;SEE IF ITEM IS BIG ENOUGH TO HOLD ALL THE CHARACTERS IN THE SOURCE.
STRT4P: HLRZ TE,SDSTIN ;MAX SIZE OF RECEIVING ITEM
TRNA
STRGT4: HLRZ TE,USENII ;SIZE OF SENDING ITEM
ADDI TE,1
HRRZ TD,ESIZEA ; SIZE OF PTR
CAIL TD,^D10 ;TEN OR MORE DIGITS IS ALWAYS ENOUGH
POPJ PP,
MOVE TD,POWR10##(TD) ;SEE WHAT THE LARGEST NUMBER IT WILL HOLD IS
CAMLE TD,TE ;SKIP IF NOT BIG ENOUGH
POPJ PP,
STRE4: MOVEI DW,E.465 ;?PTR/CTR TOO SMALL
JRST OPNWRN##
STRE5: MOVEI DW,E.577 ;?RECEIVING ITEM MAY NOT BE EDITED OR JUSTIFIED.
JRST OPNFAT
STRE6: MOVEI DW,E.635 ;"MUST REPRESENT AN INTEGER"
JRST OPNFAT
SUBTTL SUBROUTINES
;FIXOPS - ROUTINE TO PROCESS BOTH UNSDES OPERATOR AND UNSTR OPERATOR
; EACH HAS 1 REQUIRED OPERAND AND 2 OPTIONAL OPERANDS
;CALL:
; ARGSTR/ PTR TO THE REQUIRED OPERAND
; W1 CONTAINS THE CURRENT OPERATOR (WHICH MUST BE PRESERVED)
; IF BIT 34 OF TB IS 0 THE FIRST OPTIONAL OPERAND IS MISSING.
; IF BIT 35 OF TB IS 0 THE SECOND OPTIONAL OPERAND IS MISSING.
FIXOPS: CAIN TB,3 ;BOTH OPERANDS PRESENT?
POPJ PP, ;YES, RETURN
PUSH PP,W1 ;NO, SAVE OPERATOR
MOVNI W1,2 ;GET -2
TRNN TB,3 ;ARE BOTH OPERANDS MISSING?
JRST FIXOP2 ;YES, GO STORE TWO [-2 + 0]'S.
SOJN TB,FIXOP3 ;IF THE 2ND OPERAND IS MISSING,
; GO STORE ONE [-2 + 0]
;FIRST OPERAND IS MISSING.
;MAKE ROOM FOR 2 WORDS IN EOPTAB AND MOVE IT UP
PUSHJ PP,PUSH12 ;MAKE ROOM FOR 2 WORDS
HRRZ TC,ARGSTR## ;GET ADDR OF THE REQUIRED OPERAND
MOVE TE,1(TC) ;GET ITS SUBSCRIPT COUNT
LDB TB,TESUBC
LSH TB,1
ADDI TC,2(TB) ;SKIP TO 2ND
MOVE TE,1(TC) ;2ND WORD OF 2ND OPERAND
LDB TB,TESUBC ;GET 2ND'S SUBSCRIPT COUNT
MOVNI TB,1(TB) ; GET -# OF 2-WORD ENTRIES TO MOVE UP
HRLZI TB,(TB) ;-#,,0
HRRI TB,(TC) ;STARTING WITH THIS WORD
MOVE TA,(TB) ;GET 1ST TWO WORDS
MOVE TD,1(TB)
FIXOP1: EXCH TA,2(TB) ;MOVE UP A WORD PAIR
EXCH TD,3(TB)
AOJ TB,
AOBJN TB,FIXOP1
MOVEM W1,(TC) ;CAN'T USE PUSH%T, CAUSE WE'RE IN THE
SETZM 1(TC) ; MIDDLE OF THE TABLE.
JRST FIXOP4
FIXOP2: PUSHJ PP,PUSH%T ;STORE [-2 + 0] ON EOPTAB AS 1ST OPERAND.
FIXOP3: PUSHJ PP,PUSH%T ;STORE [-2 + 0] ON EOPTAB AS 2ND OPERAND.
FIXOP4: POP PP,W1 ;RESTORE OPERATOR
POPJ PP, ;RETURN
PUSH%T: JFFO W1,PUSH12##
;TLNKDE -- GET A DELIMITER ENTRY AND PUT IN LINKED LIST.
;CALL: PUSHJ PP,TLNKDE
; <RETURN HERE>
;INPUT:
; UNSDLE/ POINTS TO FIRST DE ENTRY, OR 0
; CURDE/ POINTER TO PREVIOUS ENTRY, UNLESS C(UNSDLE) = 0
;RETURNS:
; TEMTAB ENTRY GENERATED, AND ZEROED
; UNSDLE SET UP IF NOT ALREADY
; LINK SET UP IN PREVIOUS ENTRY TO POINT TO THIS ONE
; CURDE SET UP TO POINT TO THIS ENTRY
;ACS USED: TA-TE
TLNKDE: MOVEI TA,.DEHLN ;# WORDS TO GET
PUSH PP,TA ;SAVE # WORDS
PUSHJ PP,GETTEM ;GET (TA) LOCS IN TEMTAB
;LINK TO LAST ENTRY
SKIPN UNSDLE ;IS THIS 1ST DE?
JRST STRTDE ;YES
HRRZ TB,CURDE ;NO, LINK LAST ENTRY TO THIS ONE
ADD TB,TEMLOC
MOVEM TA,.DELNK(TB)
TRNA ;LEAVE INITIAL PTR ALONE
STRTDE: MOVEM TA,UNSDLE ;1ST ARG--SETUP INITIAL POINTER
MOVEM TA,CURDE ;MAKE THIS ENTRY THE CURRENT ONE
;ZERO OUT THIS TEMTAB ENTRY
POP PP,TD ;TD:= # WORDS TO CLEAR
ADD TA,TEMLOC ;TA POINTS TO FIRST WORD
SETZM (TA) ;CLEAR 1ST WORD
HRL TA,TA
HRRZ TB,TA
ADDI TB,-1(TD)
ADDI TA,1
BLT TA,(TB)
POPJ PP, ;DONE, RETURN
;TLNKUS - GET AN UNSTRING-SERIES ENTRY AND PUT IN LINKED LIST.
;CALL: PUSHJ PP,TLNKUS
; <RETURN HERE>
;INPUT:
; STSETP/ POINTS TO FIRST US ENTRY, OR 0
; CURUS/ POINTER TO PREVIOUS ENTRY, UNLESS C(STSETP) = 0
;RETURNS:
; TEMTAB ENTRY GENERATED, AND ZEROED
; STSETP SET UP IF NOT ALREADY
; LINK SET UP IN PREVIOUS ENTRY TO POINT TO THIS ONE
; CURUS SET UP TO POINT TO THIS ENTRY
;ACS USED: TA-TE
TLNKUS: MOVEI TA,.USHLN ;# WORDS TO GET
PUSH PP,TA ;SAVE # WORDS
PUSHJ PP,GETTEM ;GET (TA) LOCS IN TEMTAB
;LINK TO LAST ENTRY
SKIPN STSETP ;IS THIS 1ST U-S?
JRST STRTUS ;YES
HRRZ TB,CURUS ;NO, LINK LAST ENTRY TO THIS ONE
ADD TB,TEMLOC
MOVEM TA,.USLNK(TB)
TRNA ;LEAVE INITIAL PTR ALONE
STRTUS: MOVEM TA,STSETP ;1ST ARG--SETUP INITIAL POINTER
MOVEM TA,CURUS ;MAKE THIS ENTRY THE CURRENT ONE
;ZERO OUT THIS TEMTAB ENTRY
POP PP,TD ;TD:= # WORDS TO CLEAR
ADD TA,TEMLOC ;TA POINTS TO FIRST WORD
SETZM (TA) ;CLEAR 1ST WORD
HRL TA,TA
HRRZ TB,TA
ADDI TB,-1(TD)
ADDI TA,1
BLT TA,(TB)
POPJ PP, ;DONE, RETURN
;$CERR MACRO GENERATES A JSP TE,SIMPER.
; IF THIS MESSAGE EVER COMES OUT, THE PERSON WHO WISHES
;TO FIND OUT HOW IT GOT HERE MERELY HAS TO LOOK AT "TE",
;WHICH WILL CONTAIN THE PC OF THE INSTRUCTION AFTER THE $CERR.
SIMPER: OUTSTR [ASCIZ/? Internal compiler error in STRGEN
/]
JRST KILL##
END