Annotation of researchv10no/cmd/spitbol/mintok.spt, revision 1.1

1.1     ! root        1: -IN80
        !             2: -TITLE MINTOK: PHASE 1 TRANSLATION FROM MINIMAL TO TOKENS
        !             3: -STITL INTRODUCTIONS
        !             4: *
        !             5: *       This program takes MINIMAL statements and busts them up into
        !             6: *       individual pieces.
        !             7: *
        !             8: -STITL Initialization
        !             9: *
        !            10: *       Keyword initialization
        !            11: *
        !            12:        &ANCHOR = 1;    &STLIMIT = -1;  &TRIM   = 1
        !            13: *
        !            14: *       Useful constants
        !            15: *
        !            16:         MINLETS = 'ABCDEFGHIJKLMNOPQRSTUVWXY$'
        !            17:         NOS     = '0123456789'
        !            18:        TAB     = SUBSTR( &ALPHABET,10,1 )
        !            19:         REGNAME = ('X' ANY('LSTR')) | ('W' ANY('ABC')) | 'IA' | 'RA' | 'CP'
        !            20: *
        !            21: *       Zero the counts
        !            22: *
        !            23:         LABCNT = NOUTLINES = NLINES = NSTMTS = NTARGET = NERRORS = 0
        !            24: *
        !            25: *       Get file name
        !            26: *
        !            27:         FILENAMI = INPUT
        !            28:        TERMINAL = 'Input MINIMAL file: ' FILENAMI
        !            29:         TERMINAL =
        !            30:         FILENAMO = INPUT
        !            31:        TERMINAL = 'Output TOKEN file: ' FILENAMO
        !            32:         TERMINAL =
        !            33:         FLCFLAG  = REPLACE( INPUT,'y','Y' )
        !            34:        TERMINAL = 'Full line comments passed to TOKEN file? ' FLCFLAG
        !            35: *
        !            36: *       No page ejects without full line comments
        !            37: *
        !            38:         TERMINAL = DIFFER(FLCFLAG,'N')
        !            39:         EJCFLAG  = REPLACE( (DIFFER(FLCFLAG,'N') INPUT, 'N'),'y','Y' )
        !            40:        TERMINAL = 'EJCs passed to TOKEN file? ' EJCFLAG
        !            41: -STITL XFER FUNCTIONS
        !            42: *       CRACK parses STMT into a STMT data plex and returns it.
        !            43: *       It fails if there is a syntax error.
        !            44: *
        !            45:         DEFINE('CRACK(LINE)LABEL,OPCODE,OPERANDS,COMMENT,OPERAND,CHAR')
        !            46: *
        !            47: *       STMT is the common data plex used to hold the components of
        !            48: *       a statement (either Minimal or VAX) during processing.
        !            49: *
        !            50:         DATA('STMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)')
        !            51: *
        !            52: *       MINLABEL is a pattern matching a valid Minimal Source Label.
        !            53: *
        !            54:         MINLABEL = ANY(MINLETS) ANY(MINLETS) ANY(MINLETS NOS)
        !            55: +                  ANY(MINLETS NOS) ANY(MINLETS NOS)
        !            56: *
        !            57: *       CSPARSE parses out the components of the input line in STMT,
        !            58: *       and puts them into the locals: LABEL, OPCODE, OPERANDS, COMMENT
        !            59: *
        !            60:         CSPARSE = (((MINLABEL . LABEL) | ('     '  '' . LABEL)) '  '
        !            61: +                  LEN(3) . OPCODE
        !            62: +                  (('  ' (BREAK(' ') | RTAB(0)) . OPERANDS
        !            63: +                   (SPAN(' ') | '') RTAB(0) . COMMENT)  |
        !            64: +                   (RPOS(0) . OPERANDS . COMMENT)))  |
        !            65: +                 ('.'  '' . LABEL  MINCOND . OPCODE
        !            66: +                  ((TAB(7)  '.'  LEN(4) . OPERANDS) | (RPOS(0) . OPERANDS))
        !            67: +                  '' . COMMENT)
        !            68: *
        !            69: *       CSOPERAND breaks out the next operand in the OPERANDS string.
        !            70: *
        !            71:         CSOPERAND = (BREAK(',') . OPERAND  ',')  |  ((LEN(1) RTAB(0)) . OPERAND)
        !            72: *
        !            73: *       CSDTC is a pattern that handles the special case of the Minimal DTC op
        !            74: *
        !            75:         CSDTC   = ((MINLABEL . LABEL)  |  ('     '  '' . LABEL))
        !            76: +                 LEN(7) (LEN(1) $ CHAR  BREAK(*CHAR)  LEN(1)) . OPERAND
        !            77: +                 (SPAN(' ') | '')  RTAB(0) . COMMENT
        !            78: *
        !            79: *      equ.rip is a pattern that parses out the components of an EQU
        !            80: *      expression.
        !            81: *
        !            82:        equ.rip  = ( span(nos) . num1 | minlabel . sym1 )
        !            83: +                 ( any('+-') . oprtr | '' )
        !            84: +                 ( span(nos) . num2 | minlabel . sym2 | '' )
        !            85: +                 rpos(0)
        !            86: -EJECT
        !            87: *       DOSTMT is the driver routine that causes processing of the
        !            88: *       statement plex in THISSTMT.
        !            89: *
        !            90:         DEFINE('DOSTMT()LABEL,OPCODE,OP1,OP2,OP3,COMMENT,T')
        !            91: -SPACE 3
        !            92: *
        !            93:         DEFINE('TINIT(STR)POS,CNT,INDEX,VAL,LASTVAL')
        !            94:         H_EQU.DEFS = TINIT(
        !            95: +               'CFP$A[256]CFP$B[4]CFP$C[4]CFP$F[8]'
        !            96: +               'CFP$I[1]CFP$M[^X7FFFFFFF]CFP$N[32]'
        !            97: +               'NSTMX[10]CFP$R[1]CFP$S[6]CFP$X[2]'
        !            98: +              'CFP$U[128]'
        !            99: +               'E$SRS[50]E$STS[512]E$CBS[512]E$HNB[253]'
        !           100: +               'E$HNW[3]E$FSP[20]'
        !           101: +               'CH$LA[065]CH$LB[066]CH$LC[067]CH$LD[068]'
        !           102: +               'CH$LE[069]CH$LF[070]CH$LG[071]CH$LH[072]'
        !           103: +               'CH$LI[073]CH$LJ[074]CH$LK[075]CH$LL[076]'
        !           104: +               'CH$LM[077]CH$LN[078]CH$LO[079]CH$LP[080]'
        !           105: +               'CH$LQ[081]CH$LR[082]CH$LS[083]CH$LT[084]'
        !           106: +               'CH$LU[085]CH$LV[086]CH$LW[087]CH$LX[088]'
        !           107: +               'CH$LY[089]CH$L$[090]'
        !           108: +               'CH$D0[048]CH$D1[049]CH$D2[050]CH$D3[051]'
        !           109: +               'CH$D4[052]CH$D5[053]CH$D6[054]CH$D7[055]'
        !           110: +               'CH$D8[056]CH$D9[057]'
        !           111: +               'CH$$A[097]CH$$B[098]CH$$C[099]CH$$D[100]'
        !           112: +               'CH$$E[101]CH$$F[102]CH$$G[103]CH$$H[104]'
        !           113: +               'CH$$I[105]CH$$J[106]CH$$K[107]CH$$L[108]'
        !           114: +               'CH$$M[109]CH$$N[110]CH$$O[111]CH$$P[112]'
        !           115: +               'CH$$Q[113]CH$$R[114]CH$$S[115]CH$$T[116]'
        !           116: +               'CH$$U[117]CH$$V[118]CH$$W[119]CH$$X[120]'
        !           117: +               'CH$$Y[121]CH$$$[122]'
        !           118: +               'CH$AM[038]CH$AS[042]CH$AT[064]CH$BB[060]'
        !           119: +               'CH$BL[032]CH$BR[124]CH$CL[058]CH$CM[044]'
        !           120: +               'CH$DL[036]CH$DT[046]CH$DQ[034]CH$EQ[061]'
        !           121: +               'CH$EX[033]CH$MN[045]CH$NM[035]CH$NT[126]'
        !           122: +               'CH$PC[037]CH$PL[043]CH$PP[040]CH$RB[062]'
        !           123: +               'CH$RP[041]CH$QU[063]CH$SL[047]CH$SM[059]'
        !           124: +               'CH$SQ[039]CH$UN[095]CH$OB[091]CH$CB[093]'
        !           125: +               'CH$HT[009]CH$VT[012]IODEL[000]')
        !           126: *
        !           127: *       EQUATES is used by H_EQU and XOP.  It contains a directory of
        !           128: *       all labels that were defined by EQU instructions.  This allows
        !           129: *       XOP to properly translate operands of the DLBL(X) category.
        !           130: *
        !           131:         EQUATES = TABLE(257)
        !           132: -space 3
        !           133: *      BSW is a flag that indicates whether or not a BSW...ESW range
        !           134: *      is being processed.
        !           135: *
        !           136:        bsw     = 0
        !           137: -EJECT
        !           138: *       Error is used to report an error for THISSTMT
        !           139: *
        !           140:         DEFINE('ERROR(TEXT)')
        !           141: -SPACE 3
        !           142: *       OUTSTMT is used to send a target statement to the target code
        !           143: *       output file (OUTFILE <=> LU2)
        !           144: *
        !           145:         DEFINE('OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)T,STMTOUT')
        !           146: *
        !           147: *       Associate output file
        !           148: *
        !           149:         OUTPUT(.OUTFILE,2,(IDENT(FILENAMO) '', FILENAMO))
        !           150: *       READLINE is called to return the next non-comment line from
        !           151: *       the Minimal input file (INFILE <=> LU1).   Note that it will
        !           152: *       not fail on EOF, but it will return a Minimal END statement
        !           153: *
        !           154:         DEFINE('READLINE()')
        !           155: *
        !           156: *       Associate input file to LU1
        !           157: *
        !           158:         INPUT(.INFILE,1,(IDENT(FILENAMI) '', FILENAMI))
        !           159: -EJECT
        !           160: *       XOP is called to translate a Minimal Operand to a VAX Macro Operand.
        !           161: *
        !           162:         DEFINE('XOP(XOP)VAL,PREFIX')
        !           163: *
        !           164: *       XOP.REGS is a pattern to match out register names for translation.
        !           165: *
        !           166:         XOP.REGS = (*REGNAME . VAL  RPOS(0) . PREFIX)  |
        !           167: +                  (BREAK('(') LEN(1)) . PREFIX   LEN(2) . VAL
        !           168: *
        !           169: *       XOP.XREGS is a table with register translations
        !           170: *
        !           171:         XOP.XREGS = TINIT('IA[R5]RA[R2]CP[R3]WA[R6]WB[R7]WC[R8]XR[R9]'
        !           172: +                   'XL[R10]XT[R10]XS[SP]')
        !           173: *
        !           174: *       XPINTX is a pattern that will match the INT(X) type operand
        !           175: *
        !           176:         XPINTX  = SPAN(NOS) . VAL  '('
        !           177: *
        !           178: *       XPDLBLX is a pattern that will match the DLBL(X) type operand
        !           179: *
        !           180:         XPDLBLX = MINLABEL . VAL  '('
        !           181: -STITL MAIN PROGRAM
        !           182: *       Here follows the driver code for the "main" program.
        !           183: -SPACE 3
        !           184: *
        !           185: *       Loop until program exits via H_END
        !           186: *
        !           187: MN03    DOSTMT()                                        :(MN03)
        !           188: -STITL CRACK(LINE)
        !           189: *       CRACK is called to create a STMT plex containing the various
        !           190: *       entrails of the Minimal Source statement in LINE.  For
        !           191: *       conditional assembly ops, the opcode is the op, and OP1
        !           192: *       is the symbol.  Note that DTC is handled as a special case to
        !           193: *       assure that the decomposition is correct.
        !           194: *
        !           195: *       CRACK will print an error and fail if a syntax error occurs.
        !           196: *
        !           197: CRACK   NSTMTS  = NSTMTS + 1
        !           198:         LINE    CSPARSE                                 :F(CS03)
        !           199:         CRACK   = STMT(LABEL,OPCODE,,,,COMMENT)
        !           200:         IDENT(OPCODE,'DTC')                             :S(CS02)
        !           201: *
        !           202: *      Now pick out operands until none left
        !           203: *
        !           204:        OPERANDS  CSOPERAND =                           :F(CS01)
        !           205:        OP1(CRACK) = XOP(OPERAND)
        !           206:        OPERANDS  CSOPERAND =                           :F(CS01)
        !           207:        OP2(CRACK) = XOP(OPERAND)
        !           208:        OPERANDS  CSOPERAND                             :F(CS01)
        !           209:        OP3(CRACK) = XOP(OPERAND)
        !           210: *
        !           211: *      Operands all parsed out.  That's all folks.
        !           212: *
        !           213: CS01   :(RETURN)
        !           214: *
        !           215: *      DTC - Special case
        !           216: *
        !           217: CS02   LINE    CSDTC                                   :F(CS03)
        !           218:        OP1(CRACK) = OPERAND
        !           219:        COMMENT(CRACK) = COMMENT                        :(CS01)
        !           220: *
        !           221: *      Here on syntax error
        !           222: *
        !           223: CS03   ERROR('SOURCE LINE SYNTAX ERROR')               :(FRETURN)
        !           224: -STITL DOSTMT()
        !           225: *       DOSTMT is invoked to initiate processing of the next line from
        !           226: *       READLINE.  For efficient access
        !           227: *       DOSTMT puts name values corresponding to the components in
        !           228: *       variables with the same names (LABEL, OPCODE, OP1,OP2,OP3 and
        !           229: *       COMMENT) which allows the various handlers to $var to store/fetch
        !           230: *       the values of the statment.
        !           231: *
        !           232: *       After doing this, DOSTMT branches to the handler routine indicated
        !           233: *       for this opcode in the HANDLER table (there must be an entry or
        !           234: *       an error results).  The handlers all have entry points beginning
        !           235: *       with "H_", and can be considered a logical extension of the
        !           236: *       DOSTMT routine.  The handlers have the choice of branching back
        !           237: *       to DSGEN to cause the THISSTMT plex to be sent to OUTSTMT, or
        !           238: *       of RETURNing themselves, in which case the handler must output
        !           239: *       all needed code itself.
        !           240: *
        !           241: *       The handlers are listed in a separate section below.
        !           242: *
        !           243: DOSTMT  THISLINE = READLINE()
        !           244:         THISSTMT = CRACK(THISLINE)              :F(DOSTMT)
        !           245:         LABEL   = .LABEL(THISSTMT)
        !           246:         OPCODE  = .OPCODE(THISSTMT)
        !           247:         OP1     = .OP1(THISSTMT)
        !           248:         OP2     = .OP2(THISSTMT)
        !           249:         OP3     = .OP3(THISSTMT)
        !           250:         COMMENT = .COMMENT(THISSTMT)
        !           251: *
        !           252: *      ONLY NEED TO PROCESS 5 INSTRUCTIONS:
        !           253: *
        !           254: *      BSW,END,EQU,ESW,IFF
        !           255: *
        !           256:         LEQ( $OPCODE,'EQU' )                    :s(h_equ)
        !           257:        leq( $opcode,'IFF' )                    :s(h_iff)
        !           258:        leq( $opcode,'BSW' )                    :s(h_bsw)
        !           259:        leq( $opcode,'ESW' )                    :s(h_esw)
        !           260:        leq( $opcode,'END' )                    :s(h_end)
        !           261: *
        !           262: *       GENERATE TOKENS.
        !           263: *
        !           264: DSGEN   OUTSTMT($LABEL,$OPCODE,$OP1,$OP2,$OP3,$COMMENT) :(RETURN)
        !           265: -STITL ERROR(TEXT)
        !           266: *       This module handles reporting of errors with the offending
        !           267: *       statement text in THISLINE.  Comments explaining
        !           268: *       the error are written to the listing (including error chain), and
        !           269: *       the appropriate counts are updated.
        !           270: *
        !           271: ERROR   OUTFILE = '* *???* ' THISLINE
        !           272:         OUTFILE = '*       ' TEXT
        !           273: +                 (IDENT(LASTERROR),'. LAST ERROR WAS LINE ' LASTERROR)
        !           274:         LASTERROR = NOUTLINES
        !           275:         NOUTLINES = NOUTLINES + 2
        !           276:         NERRORS = NERRORS + 1
        !           277: +                       :(RETURN)
        !           278: -STITL OUTSTMT(LABEL,OPCODE,OP1,OP2,OP3,COMMENT)
        !           279: *       This module writes the components of the VAX MACRO statement
        !           280: *       passed in the argument list to the formatted .MAR file
        !           281: *
        !           282: OUTSTMT
        !           283: *
        !           284: *       Send text to OUTFILE
        !           285: *
        !           286:         OUTFILE = '{' LABEL '{' OPCODE '{' OP1 '{' OP2 '{' OP3 '{' COMMENT
        !           287:         NTARGET = NTARGET + 1
        !           288:         NOUTLINES = NOUTLINES + 1
        !           289: +                       :(RETURN)
        !           290: -STITL READLINE()
        !           291: *       This routine returns the next statement line in the input file
        !           292: *       to the caller.  It never fails.  If there is no more input,
        !           293: *       then a Minimal END statement is returned.
        !           294: *       Comments are passed through to the output file directly.
        !           295: *
        !           296: *
        !           297: READLINE READLINE = INFILE                      :F(RL02)
        !           298:         NLINES  = NLINES + 1
        !           299:        ident( readline )                       :s(readline)
        !           300:         LEQ( SUBSTR( READLINE,1,1 ),'*' )       :F(RL01)
        !           301: *
        !           302: *       Only print comment if requested.
        !           303: *
        !           304:         OUTFILE = IDENT(FLCFLAG,'Y') READLINE   :F(READLINE)
        !           305:         NOUTLINES = NOUTLINES + 1               :(READLINE)
        !           306: *
        !           307: *       Here if not a comment line
        !           308: *
        !           309: RL01    :(RETURN)
        !           310: *
        !           311: *       Here on EOF
        !           312: *
        !           313: RL02    READLINE = '       END'
        !           314:                         :(RL01)
        !           315: -STITL TINIT(STR)
        !           316: *       This routine is called to initialize a table from a string of
        !           317: *       index/value pairs.
        !           318: *
        !           319: TINIT   POS     = 0
        !           320: *
        !           321: *       Count the number of "[" symbols to get an assessment of the table
        !           322: *       size we need.
        !           323: *
        !           324: TIN01   STR     (TAB(*POS) '[' BREAK(']') *?(CNT = CNT + 1) @POS)
        !           325: +                                       :S(TIN01)
        !           326: *
        !           327: *       Allocate the table, and then fill it. Note that a small memory
        !           328: *       optimisation is attempted here by trying to re-use the previous
        !           329: *       value string if it is the same as the present one.
        !           330: *
        !           331:         TINIT   = TABLE(CNT)
        !           332: TIN02   STR     (BREAK('[') $ INDEX LEN(1) BREAK(']') $ VAL LEN(1)) =
        !           333: +                                       :F(RETURN)
        !           334:         VAL     = CONVERT( VAL,'INTEGER' )
        !           335:         VAL     = IDENT(VAL,LASTVAL) LASTVAL
        !           336:         LASTVAL = VAL
        !           337:         TINIT[INDEX] = VAL              :(TIN02)
        !           338: -STITL XOP(OPERAND)
        !           339: *       XOP is called to Translate a Minimal Source Operand into
        !           340: *       a semantically equivalent VAX/Macro Operand.  Most of the
        !           341: *       Minimal Operands are basically OK,  the following transformations
        !           342: *       must be applied:
        !           343: *
        !           344: *               - All operands beginning with "=" have the "=" changed
        !           345: *                 to a VAX immediate mode beginning with "#"
        !           346: *               - Byte immediate "*..." is changed to "#4*..."
        !           347: *               - INT(X) is changed to "4*INT(X)"
        !           348: *               - DLBL(X) is changed to "4*DLBL(X)"
        !           349: *               - CLBL(X) and WLBL(X) are changed to L^XLBL(X)
        !           350: *
        !           351: *
        !           352: *       Check for immediate mode
        !           353: *
        !           354: XOP     XOP  '='        = '#'                   :S(XP01)
        !           355: *
        !           356: *       Else check for byte immediate
        !           357: *
        !           358:         XOP  ('*'  LEN(1) . VAL)  =  '#4*' VAL  :S(XP01)
        !           359: *
        !           360: *       Else check for INT(X)
        !           361: *
        !           362:         XOP  XPINTX  =  (IDENT(VAL,'0'), '4*' VAL) '('  :S(XP01)
        !           363: *
        !           364: *       Else check for DLBL(X), CLBL(X) or WLBL(X)
        !           365: *
        !           366:         XOP  XPDLBLX  =  (DIFFER(EQUATES[VAL]) '4*', 'L^') VAL '('
        !           367: *
        !           368: *       Merge here with XOP containing syntax fixes.  Now map registers
        !           369: *
        !           370: XP01    XOP     XOP.REGS        = PREFIX XOP.XREGS[VAL]         :(RETURN)
        !           371: -stitl Handle instructions
        !           372: *
        !           373: *      BSW processing begins by building an array that can hold all
        !           374: *      IFF operands and comments.
        !           375: *
        !           376: h_bsw  ub = ( integer( $op2 ) $op2, equates[$op2] )
        !           377:        iffar = integer( ub )
        !           378: +              array( '0:' ub - 1,'{{' )               :f(error)
        !           379:        dplbl = $op3
        !           380:        bsw   = 1                                       :(dsgen)
        !           381: -space 3
        !           382: *
        !           383: *      IFF processing sets the iffar[] element to the current
        !           384: *      value, plbl, and comment.
        !           385: *
        !           386: h_iff  eq( bsw )                                       :s(error)
        !           387:        iffval = ( integer( $op1 ) $op1, equates[$op1] )
        !           388:        iffar[iffval] = integer( iffval ) 
        !           389: +              $op1 '{' $op2 '{' $comment              :f(error)s(return)
        !           390: *
        !           391: *      In order to support translation of MINIMAL operands and
        !           392: *      BSW/IFF/ESW preprocessing, all EQU expressions must be
        !           393: *      evaluated and kept in a symbol table.
        !           394: *
        !           395: h_equ  equates[$label] = ident($op1,'*')
        !           396: +                      h_equ.defs[$label]              :s(dsgen)
        !           397: *
        !           398:        num1 = num2 = sym1 = sym2 = oprtr = 
        !           399:        $op1 equ.rip                                    :f(error)
        !           400:        num1    = differ(sym1) equates[sym1]
        !           401:        num2    = differ(sym2) equates[sym2]
        !           402:        val     = eval( num1 ' ' oprtr ' ' num2 )               :f(error)
        !           403:        equates[$label] = val                           :(dsgen)
        !           404: -space 3
        !           405: *
        !           406: *      ESW processing generates an IFF for every value in the
        !           407: *      BSW range.
        !           408: *
        !           409: h_esw  eq( bsw)                                        :s(error)
        !           410:        iffindx = 0
        !           411: h_esw1 iffar[iffindx] break('{') $ val len(1)
        !           412: +              break( '{' ) $ plbl len(1)
        !           413: +              rem $ cmnt
        !           414: +                                                      :f(h_esw2)
        !           415:        val = ident( val ) 'DUMMY'
        !           416:        plbl = ident( plbl ) dplbl
        !           417:        outstmt(,'IFF',val,plbl,,cmnt)
        !           418:        iffindx = iffindx + 1                           :(h_esw1)
        !           419: h_esw2  iffar =                                                :(dsgen)
        !           420: -SPACE 3
        !           421: *       END prints statistics on terminal then exits program
        !           422: *
        !           423: H_END   OUTSTMT(,'END',,,,$COMMENT)
        !           424:         TERMINAL = '*** TRANSLATION COMPLETE ***'
        !           425:         TERMINAL = NLINES ' LINES READ.'
        !           426:         TERMINAL = NSTMTS ' STATEMENTS PROCESSED.'
        !           427:         TERMINAL = NTARGET ' TARGET CODE LINES PRODUCED.'
        !           428:         TERMINAL = NERRORS ' ERRORS OCCURRED.'
        !           429:         TERMINAL = DIFFER(LASTERROR) 'THE LAST ERROR WAS IN LINE ' LASTERROR
        !           430:         &CODE   = NE(NERRORS) 2001
        !           431:        terminal = collect() ' free words'
        !           432:         :(END)
        !           433: *
        !           434: END
        !           435: spitv35.ppmin
        !           436: spitv35.tok
        !           437: y
        !           438: y

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.