GEN: Parse and semantic analysis phase.
GEN: Parse and semantic analysis phase.
1 .=member intro 2 $ !$&'()*+,-./0123456789:;<=>abcdefghijklmnopqrstuvwxyz^_ 3 $ the above line contains, in order of ascii codes, the 56 4 $ characters of the little language, starting in column 7. 5 6 7 8 9 /* 10 11 $$ $$$$$$$$$$ $$$$$$$$$$ $$$$$$$$$$ $$ $$$$$$$$$ 12 $$ $$$$$$$$$$ $$$$$$$$$$ $$$$$$$$$$ $$ $$$$$$$$$ 13 $$ $$ $$ $$ $$ $$ 14 $$ $$ $$ $$ $$ $$ 15 $$ $$ $$ $$ $$ $$$$$$ 16 $$ $$ $$ $$ $$ $$$$$$ 17 $$ $$ $$ $$ $$ $$ 18 $$ $$ $$ $$ $$ $$ 19 $$$$$$$$$$ $$$$$$$$$$ $$ $$ $$$$$$$$$$ $$$$$$$$$ 20 $$$$$$$$$$ $$$$$$$$$$ $$ $$ $$$$$$$$$$ $$$$$$$$$ 21 22 $$$$$$$$ $$$$$$$$$$ $$ $$ 23 $$$$$$$$$$ $$$$$$$$$$ $$$ $$ 24 $$ $$ $$ $ $$ 25 $$ $$ $$ $$ $$ 26 $$ $$$$$ $$$$$$ $$ $$ $$ 27 $$ $$$$$ $$$$$$ $$ $$ $$ 28 $$ $$ $$ $$ $$ $$ 29 $$ $$ $$ $$ $ $$ 30 $$$$$$$$$$ $$$$$$$$$$ $$ $$$ 31 $$$$$$$$$ $$$$$$$$$$ $$ $$ 32 33 34 this software is part of the little programming system. 35 address queries and comments to 36 37 little project 38 department of computer science 39 new york university 40 courant institute of mathematical sciences 41 251 mercer street 42 new york, ny 10012 43 44 this is the second phase of the little compiler. it performs 45 the parse and semantic analysis, and is known as 'gen'. 46 47 the principal authors of the little compiler are 48 robert abes, edith deak, richard kenner, david shields 49 and aaron stein. 50 51 52 53 */ 54 55 56 57 1 .=member chars 2 /* little character set and ascii representation 3 4 !$&'()*+,-./0123456789:;<=>abcdefghijklmnopqrstuvwxyz^_ 5 the above line contains, in order of ascii codes, the 56 6 characters of the little language, starting in column 7. 7 8 the little language requires 56 distinct characters. 9 these include the 26 upper case letters, the 10 digits, 10 and the following special characters: 11 12 blank 13 = equal sign, assignment symbol 14 + plus 15 - minus 16 * times, asterisk 17 / divide, slash 18 ( left parenthesis 19 ) right parenthesis 20 , comma 21 . period, point 22 ; semicolon 23 : colon 24 $ dollar sign, comment character 25 ^ not 26 & and 27 ! or 28 < less than 29 > greater than 30 ' apostrophe, string delimiter 31 _ underline, break character 32 33 the following table gives the standard ascii encoding 34 for the little character set. 35 36 little character ascii ascii ascii ascii character 37 (hex) (oct) (dec) 38 39 space 20 40 32 space 40 ! or 21 41 33 exclamation mark 41 $ dollar sign 24 44 36 dollar sign 42 & and 26 46 38 ampersand 43 ' apostrophe 27 47 39 apostrophe 44 ( left parenthesis 28 50 40 left parenthesis 45 ) right parenthesis 29 51 41 right parenthesis 46 * asterisk 2a 52 42 asterisk 47 + plus 2b 53 43 plus 48 , comma 2c 54 44 comma 49 - minus 2d 55 45 minus 50 . period 2e 56 46 period 51 / slash 2f 57 47 slant 52 0 digit 0 30 60 48 digit 0 53 1 digit 1 31 61 49 digit 1 54 2 digit 2 32 62 50 digit 2 55 3 digit 3 33 63 51 digit 3 56 4 digit 4 34 64 52 digit 4 57 5 digit 5 35 65 53 digit 5 58 6 digit 6 36 66 54 digit 6 59 7 digit 7 37 67 55 digit 7 60 8 digit 8 38 70 56 digit 8 61 9 digit 9 39 71 57 digit 9 62 : colon 3a 72 58 colon 63 ; semicolon 3b 73 59 semicolon 64 < less than 3c 74 60 less than 65 = equals 3d 75 61 equals 66 > greater than 3e 76 62 greater than 67 a letter a 41 101 65 letter a 68 b letter b 42 102 66 letter b 69 c letter c 43 103 67 letter c 70 d letter d 44 104 68 letter d 71 e letter e 45 105 69 letter e 72 f letter f 46 106 70 letter f 73 g letter g 47 107 71 letter g 74 h letter h 48 110 72 letter h 75 i letter i 49 111 73 letter i 76 j letter j 4a 112 74 letter j 77 k letter k 4b 113 75 letter k 78 l letter l 4c 114 76 letter l 79 m letter m 4d 115 77 letter m 80 n letter n 4e 116 78 letter n 81 o letter o 4f 117 79 letter o 82 p letter p 50 120 80 letter p 83 q letter q 51 121 81 letter q 84 r letter r 52 122 82 letter r 85 s letter s 53 123 83 letter s 86 t letter t 54 124 84 letter t 87 u letter u 55 125 85 letter u 88 v letter v 56 126 86 letter v 89 w letter w 57 127 87 letter w 90 x letter x 58 130 88 letter x 91 y letter y 59 131 89 letter y 92 z letter z 5a 132 90 letter z 93 ^ not 5e 136 94 circumflex 94 _ underline 5f 137 95 underline 95 96 */ 97 1 .=member modform 2 $ every change is to include a description after the card mods.2 in 3 $ the mods deck below. 4 $ mod description is to contain name starting in column 7, author 5 $ name starting in column 17, date starting in column 37, and 6 $ new level established starting in column 57, as follows. 7 $ 1 2 3 4 5 6 8 $ 7890123456789012345678901234567890123456789012345678901234567 9 $ modname author name 10 february 1976 level 76041 10 $ 11 $ the 'level' is the julian date of the change and the macro 12 $ 'compilerlevel' should be changed whenever level is changed, so 13 $ that level printed on listing (cf routine genini) will be correct. 14 $ the title is followed by blank line (with $ in column 2), then 15 $ description of purpose of change, and finally list of code 16 $ affected, in following form. 17 $ decks affected - list of decks(routines) affected by this mod. 18 19 20 1 .=member mods 2 $ - - - all changes are to include self-description after mods.2 rbko 1$ rbko 2$ rbko r. kenner 6 june 1982 level 82158 rbko 3$ rbko 4$ print three blanks instead of four in -lstlin- so that tabs imbedd rbko 5$ in lines being listed come out correctly. rbko 6$ rbko 7$ decks affected: lstlin rbko 8$ utsc 1 utsc 2 $ utsc d. shields 18-dec-81 level 81352 utsc 3 $ utsc 4 $ extend ebcasc option so ebcasc=2 folds input to lower case. utsc 5 $ deck affected - cnvcon. utsc 6 utsa 1 utsa 2 $ utsa d. shields 29-nov-81 level 81333 utsa 3 $ utsa 4 $ support s47: amdahl uts (universal timesharing system). utsa 5 $ this implementation runs on s37 architecture using an operating utsa 6 $ system very close to unix (v7), and uses the ascii character set. utsa 7 $ utsa 8 $ 1. add option 'ebcasc=0/1' to s37 such that ebcasc=1 causes utsa 9 $ character string to be converted from ebcdic to ascii. utsa 10 $ this is needed for uts bootstrap from s37, and would be needed utsa 11 $ to bootstrap nyu ada/ed to s37. utsa 12 $ 2. change layout of strings for s37 so same structure for s32, utsa 13 $ s37 and s47 (.sl.=16, .so.=16). utsa 14 $ deck added - ebcasc (s37) utsa 15 eaa 1 eaa 2 $ eaa d. shields 31-aug-81 level 81243 eaa 3 $ eaa 4 $ support new target machine s20 (s10 with extended addressing) eaa 5 $ by recognizing 'tm=20'. this is s10 except pointer size is 30. eaa 6 $ decks affected - macros, genini eaa 7 ldse 1 ldse 2 $ ldse d. shields 24-sep-80 level 80268 ldse 3 $ ldse 4 $ add program parameter 'expire=0/366' such that if expire has ldse 5 $ non-zero value, then program is to expire (cease execution) ldse 6 $ the given number of days after compilation. expiration check ldse 7 $ done by ltllib procedure 'ltlced', parameterized as 'proc_expire'. ldse 8 $ decks affected - macros, start, genini, gensub. ldse 9 ldsd 1 ldsd 2 $ ldsd d. shields 30-jul-80 level 80212 ldsd 3 $ ldsd 4 $ 1. do dim offline for s32 to avoid asm problem. ldsd 5 $ this adds new library function 'mth$dim' for s32. ldsd 6 $ 2. do aint and amod offline for s32 to avoid problems ldsd 7 $ in unsupported rtr and rmo t32 operations. ldsd 8 $ this adds new library functions 'mth$aint' and ldsd 9 $ 'mth$amod' for s32. ldsd 10 $ 3. identify s32 dialect in listing header. ldsd 11 $ 4. increase tlistmax so can compile s32 asm. ldsd 12 $ 5. check for invalid or out-of-range real constant. ldsd 13 $ decks affected - macros, start, genini, cnvcon, ermes. ldsd 14 ldsc 1 ldsc 2 $ ldsc d. shields 21-jul-80 level 80203 ldsc 3 $ ldsc 4 $ 1. fix error (fr139) that caused problems if lcp=0 specified. ldsc 5 $ 2. avoid needless copy to terminal. ldsc 6 $ 3. enable pt parse trace for unix checkout. ldsc 7 $ decks affected - macros, genini, genexit. ldsc 8 ldsb 1 ldsb 2 $ ldsb d. shields 10-jul-80 level 80192 ldsb 3 $ ldsb 4 $ 1. fix problem (fr135) in setting of termination code. ldsb 5 $ now issue code 0 if no warnings or errors, code 4 if warnings ldsb 6 $ and no errors, code 8 if any errors detected. ldsb 7 $ 2. do not generate 'no errors detected' message. ldsb 8 $ 4. add conditional symbol -unix- for the unix operating system. ldsb 9 $ use iset=unix to obtain unix variant. ldsb 10 $ want listing terse, make lcp=0 and lcs=0 the defaults. ldsb 11 $ for initial checkout, delete special env code (mova, etc.). ldsb 12 $ ldsb 13 $ decks affected - macros, genini, genexit. ldsb 14 ldsa 1 ldsa 2 $ ldsa d. shields 25-mar-80 level 80085 ldsa 3 $ ldsa 4 $ add option 'rep=0/pg' to permit generation of 'report' file on ldsa 5 $ unit 6. each line on the file is in a format acceptable to ldsa 6 $ most macro assemblers - columns 1-8 are blank, column 9 ldsa 7 $ contains a one character opcode and the operands, separated ldsa 8 $ by commas, begin in column 17. opcodes and operands are ldsa 9 $ c caller_name,called_name,number_args ldsa 10 $ g var_name,size,dimension,nameset_name,address_offset ldsa 11 $ n nameset_name,nameset_length ldsa 12 $ p proc_name,proc_type,proc_args ldsa 13 $ (type is 1 for subr, 2 for fnct, 3 for prog) ldsa 14 $ the rep= parameter string may contain letters c, g or p. ldsa 15 $ if -g- appears in rep parameter string, both -n- and -g- opcodes ldsa 16 $ are written. ldsa 17 $ this feature replaces (and extends) the previous pcr feature. ldsa 18 $ text conditioned by -rep-. ldsa 19 $ decks affected - macros, start, gensub, sortvars, emcall, ldsa 20 $ genexit, putrep (new). ldsa 21 dsz 1 dsz 2 $ dsz d. shields 29-feb-80 level 80060 dsz 3 $ dsz 4 $ report error if function name is unsized in function definition. dsz 5 $ deck affected - closer. dsz 6 dsy 1 dsy 2 $ dsy d. shields 29-jan-80 level 80029 dsy 3 $ dsy 4 $ fix error (fr2.3.129) that caused problems if function call dsy 5 $ and unary operator hashed to same location in basic block. dsy 6 $ deck affected - emcall. dsy 7 dsx 1 dsx 2 $ dsx d. shields 10-jan-80 level 80010 dsx 3 $ dsx 4 $ 1. increase hamax from 787 to 937. this requires corresponding dsx 5 $ change to asm, as ha written to voa file. dsx 6 $ 2. add (experimental) option pcr (procedure call report) such dsx 7 $ that pcr=1 causes creation of report on unit 6. each call of dsx 8 $ subroutine or function is indicated by line with name of dsx 9 $ caller, a blank and name of procedure called. dsx 10 $ use conditional assembly option pcr for this. dsx 11 $ decks affected - macros, start, genini, emcall. dsx 12 dsw 1 dsw 2 $ dsw d. shields 14-dec-79 level 79348 dsw 3 $ dsw 4 $ extend maximum permitted dimension for s10, s32 and s37 up dsw 5 $ to 2**n-1 with n=17, 30 and 22, respectively. this involves dsw 6 $ change to voa, nl, mba and xha, so that voa file format changed. dsw 7 $ decks affected - macros, start. dsw 8 dsv 1 dsv 2 $ dsv d. shields 19-nov-79 level 79323 dsv 3 $ dsv 4 $ 1. rewind token file and voa file for s66 only. dsv 5 $ 2. use getapp (new lib procedure provided by mod dsc) to dsv 6 $ obtain and list actual parameter string specified by user. dsv 7 $ 3. delete code to read term= parameter and possibly open dsv 8 $ terminal file, as this now done by lib (mod dsc). dsv 9 $ decks affected - macros, genini. dsv 10 dsu 1 dsu 2 $ dsu d. shields 10-sep-79 level 79253 dsu 3 $ dsu 4 $ fix bug that caused pdir option to work only if lcr option dsu 5 $ selected (fr2.3.120). dsu 6 $ deck affected - genini. dsu 7 mgfc 1 mgfc 2 $ mgfc m.g. ford 15-aug-79 level 79227 mgfc 3 $ mgfc 4 $ issue standard warning and error characters for s10. mgfc 5 $ decks affected - macros, gtoflo, ermet, ermes, closer, genexit. mgfc 6 mgfb 1 mgfb 2 $ mgfb m.g. ford 05-jul-79 level 79186 mgfb 3 $ mgfb 4 $ revise s10 to use 9-bit ascii. this mod affects s10 version only. mgfb 5 $ decks affected - macros, start, genini mgfb 6 dst 1 dst 2 $ dst d. shields 29 mar 79 level 79088 dst 3 $ dst 4 $ 1. fix errors in mbchain, vbegl fields for s10, s32 (fr2.3.100). dst 5 $ 2. report error if operand to arithmetic comparison multi-word. dst 6 $ decks affected - macros, start, ermes, emit2, sortvars. dst 7 dss 1 dss 2 $ dss d. shields 30 jan 79 level 79030 dss 3 $ r. kenner dss 4 $ dss 5 $ 1. make data structures for -monitor- features more dss 6 $ machine-independent (fr2.3.75). dss 7 $ 2. add -isuse- calls in genioit (fr2.3.78). dss 8 $ 3. move warning message processing for overlong temporaries dss 9 $ from -blkend- to -ermes-. dss 10 $ 4. add program parameter 'cis=0/n' to check index size. if dss 11 $ option value is nonzero, then any instance of a(e) where size dss 12 $ of e is greater than option value is reported as warning. dss 13 $ the default value n is chosen according to pointer size. dss 14 $ this option added to assist in setl debugging. dss 15 $ 5. adjust some field definitions for s32. dss 16 $ decks affected - start, genini, blkend, ermes, genioit, dss 17 $ emit2, emass, gendebug. dss 18 dsr 1 dsr 2 $ dsr d. shields 27 dec 78 level 78361 dsr 3 $ dsr 4 $ 1. fix error (fr2.3.72) in unpacking tokens in -parse- if dsr 5 $ -unpk_env- not enabled. dsr 6 $ 2. fix error (fr2.3.74) in arith in that comparisons dsr 7 $ of multi-word items with constants wrongly folded by dsr 8 $ arith in some cases. dsr 9 $ 3. expand functions aint, amod, float, ifix and int in-line dsr 10 $ for s10 and s32. dsr 11 $ decks affected - genini, parse, arith. dsr 12 dsq 1 dsq 2 $ dsq d. shields 18 dec 78 level 78352 dsq 3 $ dsq 4 $ correct error (fr2.3.66) reported in -gencfi- in that dsq 5 $ call to -gendfi- did not specify argument zero. dsq 6 $ deck affected - gencfi dsq 7 meal 1 meal 2 $ dsp d. shields 27 nov 78 level 78331 meal 3 $ meal 4 $ add program option 'meal=1/0' (m-onitor e-ntry a-rgument l-ist) meal 5 $ such that zero value causes monitor procedure entry code not meal 6 $ to include print of argument values. this effected by adding meal 7 $ new global vlariable -trentrargs- which must be nonzero if gensiz meal 8 $ is to emit trace code to print argument values. meal 9 $ this feature requested by setl group. meal 10 $ decks affected - start, genini, gensiz. meal 11 vax 1 vax 2 $ vax d. shields 21 nov 78 level 78325 vax 3 $ r. kenner vax 4 $ vax 5 $ add configuration values for s32: dec vax-11. vax 6 $ decks affected - macros, start, genini, parse, squeeze, sortvars. vax 7 dso 1 dso 2 $ dso d. shields 25 sep 78 level 78268 dso 3 $ dso 4 $ 1. add code for resident s10 compiler. dso 5 $ 2. add tm=40 (prime 400) target machine. dso 6 $ decks affected - macros, start, genini. dso 7 rbkn 1 rbkn 2 $ rbkn r. kenner 19 jun 78 level 78170 rbkn 3 $ rbkn 4 $ reported bug - .len. = causes compilation error if option rbkn 5 $ help selected. rbkn 6 $ fix - missing data entry in trstorr. rbkn 7 $ deck affected - trstorr. rbkn 8 3 4 $ chars d. shields 30 may 78 level 78150 5 $ 6 $ include deck chars to describe character set to assist in 7 $ correct translation of source text for new machines. 8 $ correct error in use of cdc character set so that apostrophe 9 $ represented by cdc display code 3b'70' (up arrow). 10 $ decks affected - all (source resequenced). 11 12 13 $ dsn d. shields 15 may 78 level 78135 14 $ 15 $ 1. correct target machine parameters for s10. 16 $ 2. fix error message for negative dimension. 17 $ 3. list current procedure name if abnormal termination. 18 $ decks affected - genini, gendim, genexit. 19 20 21 $ rbkm r. kenner 01 mar 78 level 78060 22 $ d. shields 23 $ 24 $ 1. correct error in haprobe macro. 25 $ 2. correct -fidtab- entry for .sne. 26 $ 3. fix bug if .ch. and .f. in same statement. 27 $ 4. fix listing control. 28 $ 5. fix sizing of r-tokens in cnvcon. 29 $ 6. correct field definitions for s37. 30 $ decks affected - start, parse, ptdata, cnvcon, nextok, arith. 31 32 33 $ dsm d. shields 04 jan 78 level 78004 34 $ 35 $ give error message if size of zero specified. 36 $ decks affected - gensiz, ermes. 37 38 39 $ rbkl r. kenner 29 dec 77 level 77363 40 $ 41 $ 1. fix errors in s37 conditional text. 42 $ 2. install s-type tokens. see lex mod rbkg. 43 $ 3. change 'subr start' to 'prog start' on s37 since phases 44 $ are not part of one large overlay. 45 $ 4. fix bug in flow trace which causes if-true and if-false not 46 $ to be paired at run-time. 47 $ 5. have store trace call different routine depending on how many 48 $ parameters it must pass. 49 $ 6. have size of internally generated variables for -do- be mws if 50 $ the value being assigned to them has size greater than mps. 51 $ 7. fix dimension of -fidtab- in -arith-. 52 $ 8. fix bug in -marith- folding of .not. which caused constants 53 $ of size zero to be generated. 54 $ 9. fix error which caused -setq- to loop printing error messages 55 $ if it detected an item of size zero. 56 $ 10. do not have -ha- dump attempt to print -names- array for strin 57 $ 11. test for -arglist- overflow in -gengosl-. 58 $ 12. -syntab- was replaced because at least one -pt- entry differs 59 $ from what assembly of -ltlgrmr- should be. 60 $ decks affected - macros, start, genini, ptdata, gtoflo, nextok, 61 $ cnvcon, ermes, arith, marith, gendo, gengosl, 62 $ gensiz, getdovar, sortvars, trflowr, trstorr, 63 $ hadump, voadump, genexit 64 65 66 $ dsl d. shields 08 dec 77 level 77342 67 $ 68 $ 1. assign correct (integer) arithmetic mode to -idim-. 69 $ 2. fix error in flow trace for compound if with no else part. 70 $ 3. do not collect function names for assert statement list. 71 $ 4. compile no code for assert with nonzero constant expression. 72 $ 5. make operator precedence levels consistent with guide. 73 $ 6. fix error so truncate if .pad. string longer than desired 74 $ length. 75 $ 7. compute size of .not. of constant correctly. 76 $ decks affected - start, trflowr, gensert, genpad, marith. 77 78 79 $ dsk d. shields 08 nov 77 level 77312 80 $ 81 $ detect zero length .e. and .f. extracts, returning zero on 82 $ extraction, and treating as no-op on assignment. 83 $ decks affected - genextr, emass. 84 85 86 $ dsj d. shields 03 nov 77 level 77307 87 $ 88 $ 1. add conditional option pack_env, and modify cnvcon to call 89 $ pack$li directly if environment pack procedure available. 90 $ 2. reported bug - unable to compile real function invocations 91 $ with expression arguments. 92 $ cause - emcall incorrectly setting amode (bug uncovered by mod 93 $ rbkj). 94 $ 3. give better message for mixed-mode expressions. 95 $ 4. delete code in emit2 made dead by mod rbkj. 96 $ decks affected - macros, cnvcon, ermes, emcall, emit2. 97 98 99 $ rbkk r. kenner 28 oct 77 level 77301 100 $ 101 $ this mod is needed for lex mod rbkf to keep the line counts 102 $ correct. 103 $ deck affected - nextok 104 105 106 $ rbkj r. kenner 11 oct 77 level 77284 107 $ 108 $ this mod is an mostly an internal cleanup of gen. the 109 $ major areas of change are listed below. 110 $ 1. conditional text has been added for s10. 111 $ 2. field definitions have changed, especially for s37. 112 $ 3. the parser has been speed up by putting in a bit 113 $ more special cases and by slightly recoding certain 114 $ statements and reordering some tests. 115 $ 4. the handling of -end- statements has been changed 116 $ in the case of errors. if the next token does not 117 $ match any opener, the -end- is ignored and only if 118 $ the next token matches will it be processed. if the 119 $ next few tokens exactly match an opener but not the last 120 $ opener, the previous ones will be closed with an error 121 $ message. this sould reduce the number of 'runaway' error 122 $ cases. 123 $ 5. the scan for next semicolon in the case of error has been 124 $ fine-tuned to also check for a 'then' in the case of an 'if'. 125 $ 6. the text, format, and content of the syntactic error 126 $ messages have been redone and the error message numbers have 127 $ been re-ordered. 128 $ 7. a bug which caused gen to loop if the current routine was a 129 $ function and the function name was unsized has been fixed. 130 $ 8. the drop bits for variables are now set when it is the last 131 $ use before a (simple) assignment even if it is not the last 132 $ use in the basic block. the same goes for a variable or 133 $ constant referenced in a subroutine or function call. 134 $ 9. the usage count for constants are not incremented in cases 135 $ where asm would normally not use the values (like .f. indices) 136 $ 10. gen will ensure that enough space exists in the machine 137 $ block for element zero of an array. (370 asm and maybe some 138 $ others in the future need this). 139 $ 11. namesets are now openers and entered in the -csa-. this 140 $ allows other openers in namesets and allows nameset statements 141 $ to be nested. 142 $ 12. detection of when something is a function has been redone. 143 $ something is now concidered a function only when it is not 144 $ dimensioned, has never been used as a simple variable, and 145 $ does not have the same name as a built-in function. error 146 $ messages are issued in the cases in which something which was 147 $ probably erroneous would have previously been treated as a 148 $ function. also, a global variable can be treated as a functio 149 $ so that functions which are used a lot can be sized in start 150 $ and need not be sized in every other routine which calls it. 151 $ 152 $ decks affected - (most) source has been resequenced. 153 $ decks added - findcsa, closer, pfind (also some routines have been 154 $ put in their own decks) 155 $ decks deleted - findloop, comptok, pushr 156 157 158 $ dsi d. shields 02 aug 77 level 77214. 159 $ 160 $ this mod fixes a few minor problems and installs a new parser. 161 $ 162 $ 1. reported bug - arithmetic mode not set for real temporaries. 163 $ fix - set type field of temporaries. 164 $ (this only caused problems on s37 implementation.) 165 $ 2. reported bug - real constants incorrectly folded on s16. 166 $ fix - gen will no longer attempt to fold real constant 167 $ expressions if the host and target machines differ. 168 $ 3. reported bug - notrace monitor directive not working correctly 169 $ fix - error in grammar in setting of codes to pass to gentrace 170 $ has been fixed. 171 $ 172 $ this mod also modifies the parse procedure -parse- to use 173 $ the parsing strategy supported by the program -syn-. the 174 $ parse now detects expressions which consist of a single name 175 $ or constant more efficiently, and also does a more efficient 176 $ job parsing terms in expressions. 177 $ 178 $ the new procedure lstlin is used to list input lines. 179 $ 180 $ decks affected - parse, nextok, ermet, arith, blkend, 181 $ lstlin (new), and procedures which formerly called nextok to 182 $ list input lines. 183 184 185 $ dsh d. shields 20 may 77 level 77140. 186 $ 187 $ 1. support unary plus. 188 $ 2. permit use of 'err' as synonym for 'error' in filestat query. 189 $ 3. do not print trailer strings (io, monitor) in parameter 190 $ list as user cannot alter them. 191 $ 4. make size of integer multiply ws on s16. 192 $ decks affected - start, genini, parse, arith, marith, emit2. 193 194 195 $ rbki r. kenner 30 apr 77 level 77120 196 $ 197 $ fix a bug in the handling of 'monitor' statements which caused 198 $ all such statements which did not have an explicit 'limit' 199 $ paramater to set the monitor line limit to infinite. 200 $ deck affected - gendebug 201 202 203 $ dsg d. shields 22 apr 77 level 77112. 204 $ 205 $ 1. change -cursor- to -column- in filestat inquiry, so now use 206 $ filestat(fileexpr, column) to get current column. 207 $ 2. avoid reference to zero-th element of littab in nextok. 208 $ decks affected - parse, nextok. 209 210 211 $ dsf d. shields 14 mar 77 level 77073. 212 $ 213 $ 1. avoid popping csa if error seen. 214 $ 2. declare negative constants to be 'safe' and give them size 215 $ word size. 216 $ decks affected - inscon, ermet, arith. 217 218 219 $ dse d. shields 04 february 1977 level 77035. 220 $ 221 $ 1. fix error in conversion of real constants in cnvcon. 222 $ 2. fix computation of subtitle in gensub so strings aligned 223 $ on word boundaries. 224 $ 3. move misplaced test in gensize that caused problems in trace 225 $ stores list processing in gensize. 226 $ 4. correct gencall and emcall to manipulate arglist pointer 227 $ correctly, so that unsized variable in argument list does 228 $ 5. remove duplicate data statement for prhd in monitor setup. 229 $ not cause problems. 230 $ 6. correct calculation of size of string concatenation. 231 $ decks affected - cnvcon, gencall, gensize, gensub, emcall, emit2. 232 233 234 $ dsd d. shields 7 january 77 level 77007. 235 $ 236 $ convert to use new library and support only new language level. 237 $ 238 $ 1. drop support of 'old' tokens: h, z, d, l and octal b. 239 $ 2. use 'monitor' instead of 'debug'. 240 $ 3. drop support of multiword arithmetic. 241 $ (new definition and implementation due soon.) 242 $ 4. use -getipp- and -getspp- to get program parameters. 243 $ 5. on s66, place certain arrays in blank common to 244 $ reduce size of absolute overlay. 245 246 $ the source has been resequenced. 247 $ decks affected - all. 248 249 $ dsc d. shields 15 november 76 level 76320. 250 $ 1. support new language level, indicated by 'lev' compiler 251 $ option. the new level renames math library functions for 252 $ s66, does not support .c., and supports .pad. operator. 253 $ the new level also sorts namesets so storage allocated in 254 $ order of declaration, not in 'reverse' order of old level. 255 $ 2. add '.pad.' operator, of form 'str .pad. int' where -str- 256 $ is a character string constant and -int- is integer constant. 257 $ the result is the string padded to right with blanks to have 258 $ length -int-. 259 $ 3. fix debugging package reported by brooklyn college, as a 260 $ test was out of place in gensiz. 261 $ 4. support main program unit, or -prog- statement. 262 $ 5. do not require 'return' at end of procedure, and 263 $ compile 'end subr' or 'end fnct' statement into 'return'. 264 $ a return from main program terminates execution. 265 $ 6. support character string comparison operators .seq. and .sne. 266 $ decks affected - most (source has been resequenced). 267 268 269 $ dsb d. shields 6 october 1976 level 76280. 270 $ 271 $ 1. enable 'ncfopt' by default. 272 $ 2. eliminate references to file name strings and buffer lengths 273 $ since files now represented by unit numbers. 274 $ 3. add 'read' and 'write' literals and process binary io. 275 $ 4. revise processing of io. 276 $ decks affected - start, parse, io routines. 277 278 279 $ rbkh r. kenner 10 august 76 level 76223 280 $ 281 $ 1. remove input format -f- from list of i/o routine because 282 $ it is the same as input format -e-. 283 $ 2. add a field to the -voa- to count the number of uses of 284 $ a variable or constant within a routine. 285 $ 3. set drop bits for variables and constants in addition to 286 $ temporaries. 287 $ 4. for all machines other than s66, have -cont do- compile 288 $ as a -go to- test label rather than as an increment 289 $ and test at the site of the -cont-. 290 $ 5. special case -if (e) cont- and -if (e) quit- so as not 291 $ to end a basic block and to use the -ifgo- operation. 292 $ this is not done in the case of a -cont do- on s66. 293 $ 6. defer allocation of address for variables until end of 294 $ a routine and sort each nameset in order to have the smaller 295 $ variables at the start of the nameset. this aids in base 296 $ register allocation on s37 and will help on machines which 297 $ use paged virtual storage. 298 $ 7. change the name of the default nameset to have a dollar sign 299 $ in column one followed by the rest of the routine name instead 300 $ of using the routine name. this change is needed for machines 301 $ (like s37 and s11) for which a common block and routine may 302 $ not have the same name. 303 $ 8. set up a mechanism to re-use internal variables defined for 304 $ -do- statements in the same manner as is done for itterators 305 $ in i/o statements. 306 $ 9. fix bug in freeing internal variables in i/o statements. 307 $ 10. dont end basic block on some i/o calls. 308 $ 11. give error message on assignment to function parameter. 309 $ 12. give error message on indexed assignment to variable that 310 $ is not an array. (no -dims- statement for it) 311 $ 13. change text of some more error messages. 312 $ 14. add -seblk- field to -voa- to indicate which subroutine 313 $ calls end a basic block. 314 $ 15. add -bytaln- field to -voa- to indicate which extractions 315 $ or assignments are done on character-aligned data. 316 $ 16. install new -voa- field layout for s37. 317 $ 17. make dimension of some arrays dependent on machine and 318 $ install dimensions for s37. 319 $ 18. remove code in -emit2- to bypass common multi-word indexed 320 $ loads on s66 because bug fixed in s66 -asm-. 321 322 $ rbkg r. kenner 30 july 76 level 76212 323 $ 324 $ fix miscellaneous bugs detected upon s37 bootstrap of 325 $ last level. also, fix two bugs in parsing new i/o. 326 327 $ rbkf r. kenner 22 july 76 level 76204 328 $ 329 $ 1. fix reported bugs. 330 $ 1. 'notrace'/'nocheck' do not work - error in grammar. 331 $ 2. 'debug entry' is not recognized as valid due to error in 332 $ -keycode- call. 333 $ 3. some error messages do not appear in terminal file. 334 $ 4. bad formatting of listing if 'pdir' set. 335 $ 5. last few token list does not intialize correctly. 336 $ 6. trace or check statements for global variables occuring 337 $ after the -size- statements for those variables, do not 338 $ work correctly. 339 $ 2. change iotype=storage to iotype=string 340 $ decks affected - parse, genend, gensub, squeeze, geniost, pdsort 341 $ gentrace 342 343 $ rbke r. kenner 16 july 76 level 76198 344 $ d. shields 345 $ 346 $ 1. insert blank lines around error notices to make them more 347 $ noticable. 348 $ 2. have 'possibly illnested loop..' message be an error rather 349 $ than a warning and change the text. 350 $ 3. correctly process 'voa=0'. 351 $ 4. change handling of constant expression to just check if 352 $ the final result is a safe constant (i.e., 'i-i+1' is a safe 353 $ constant). remove -cexpress- and -cexperr- and change grammar. 354 $ 5. have -genexit- recieve its parameter globally to avoid problem 355 $ in s37 when overlaying compiler. 356 $ 6. allow 'term' option to have error messages written to a 357 $ separate file for use in some interactive systems. 358 $ 7. install code to parse and process new 'little i/o'. 359 $ 8. miscellaneous code changes. 360 361 362 $ rbkd r. kenner 09 july 76 level 76191 363 $ 364 $ 1. allow .len. as abbreviation for '.f. 1, .sl.,'. 365 $ 2. the -quit- and -cont- statements are no longer restricted 366 $ to the innermost loop; the tokens following the quit and 367 $ cont determine the loop. 368 $ 3. unary operations on constants are done at compile time, if 369 $ possible. 370 $ 4. continue work on error handling. 371 $ 5. require constant expressions use only 'safe' constants. 372 $ 6. value in data statement must be constant, but not necessarily 373 $ constant expression. 374 $ 7. begin implementation of revised (yet again) little io. drop 375 $ support of io as defined in little newsletter 34. 376 $ 8. the -debug- statement is used for run time control of 377 $ debug package. the statement consists of -debug- followed 378 $ by a list of parameters, separated by commas. parameters are 379 $ as follows: 380 $ limit = expr set line limit to expr. 381 $ nolimit suppress debug line limit check. 382 $ flow (noflow) enable (disable) print for -flow-. 383 $ stores (nostores) enable (disable) print for -stores-. 384 $ entry (noentry) enable (disable) print for -entry-. 385 $ byte (nobyte) include (suppress) print of value as 386 $ byte constant. 387 $ 388 $ default is 'debug flow, stores, entry, nobyte;' . 389 $ the debug line limit is initially 9/10 of print line limit. 390 $ 9. implement new rules for scope of debugging statements. 391 $ 10. support 'autotitle' option in list directive which uses 392 $ 11. have first line of proceedure list as line 1 by defering 393 $ the listing of a card until the next is read. 394 $ first line of each procedure as subtitle text. 395 396 397 $ rbkc r. kenner 02 july 76 level 76184 398 $ d. shields 399 $ 400 $ 1. improve error handling by rewording some error messages 401 $ and attempting to avoid the 'runaway' errors that occured 402 $ previously. 403 $ 2. add a field -hainuse- to the -ha- to avoid multi-word 404 $ comparisons on s37. 405 $ 3. rename -labintern- to -namintern- and set for internal 406 $ variables also instead of just labels. 407 $ 4. remove old format octal and bit constants and convert 408 $ to new format byte constants. 409 $ 5. insert conditional text -oldtoks- to continue support 410 $ of old token types. this is set on for s66 because of 411 $ the large number of existing programs which would have to 412 $ be converted, but is set off for s37. 413 $ 6. generate labels of the form 'l(n)' instead of 'l.nnn' 414 $ for subscripted labels. 415 $ 7. if .cc. is done on constants, do at compile time. 416 $ 8. allow '!!' in place of '.cc.' (as in pl/1) 417 $ 9. implement .voapart. to give dump of just voa, xarg, and csa. 418 $ 10. increase dimensions of -xarg- and -lablist-. 419 $ 11. miscellaneous changes to code style and come size statments 420 $ to improve (hopefully) efficiency and improve readability 421 $ and machine-independance. 422 423 424 $ rbkb r. kenner 28 jun 76 level 76180. 425 $ d. shields 426 $ 427 $ 1. modify identification of builtin functions to allow module 428 $ names which differ from names in source. 429 $ select functions to be done inline accodring to target 430 $ machine. 431 $ 2. support paged, titled listing and new directives for 432 $ list control. 433 $ 3. eliminate 'version number' approach to identifying voa file 434 $ and use only julian date of last change to voa file structure. 435 $ 4. require label subscripts l to be in range 0 <= l <= 999. 436 $ 5. extend lablistlen from 300 to 400. 437 $ 6. support option 'pdir' which produces list of procedures sorted 438 $ by name and with page number of first line if input listing on 439 $ when first line seen. 440 $ implementation: raise cross reference option and write page 441 $ number in ref entry. at end of input, read ref file and sort 442 $ using routines pdsort and pdcomp modelled on detect and ibigr 443 $ in the lex phase. 444 $ 7. redo debugging package in more machine-independent fashion. 445 $ this change includes a revision of the run-time interface. 446 $ at user level, effect of change is as follows: 447 $ 1. -help- parameter is now list of codes which correspond 448 $ to initial debug statements; the codes are as follows: 449 $ c - check index; 450 $ e - trace entry; 451 $ f - trace flow; 452 $ s - trace stores; 453 $ 454 $ the default is 'help=0' which gives no initial debug options. 455 $ if a code list is given but includes '0', the codes are 456 $ ignored. 'help' alone is the same as 'help=cefs'. 457 $ 458 $ 2. the -debug- parameter selects the level of debug support: 459 $ 0 - ignore all debug statements. 460 $ 1 - process only assert statements; terminate if assert 461 $ fails. 462 $ 2 - process all debug statements; do not terminate if 463 $ assert fails. 464 $ if -help- is specified, the debug level is set to two 465 $ and the -debug- parameter is ignored. 466 $ 3. debug statements in the -prelude- (before start of first 467 $ procedure) are global; other debug statements are local to 468 $ the routine in which they occur. 469 470 471 $ cra d. shields 04 may 76 level 76125 472 $ 473 $ support revised cross-reference generation as follows. 474 $ if cross reference option 'lcr' on, then write reference file 475 $ 3 which contains line numbers and names of subroutine definition 476 $ lines. use library procedure -crfnam- and parameter 'rf' to 477 $ determine name of reference file. 478 $ each routine is represented by several entries, as follows. 479 $ 1. line number of start of routine (0 ends file). 480 $ 2. number of characters in routine name. 481 $ 3. variable number of entries, containing routine name, 482 $ right adjusted with cpw characters per entry. 483 $ 484 $ also, change ps to 24 for s37, and initialize littab using arglist 485 $ to avoid multi-word data values for ha. 486 $ decks affected - start, genini, gensub, genexit. 487 488 489 $ dsa d. shields 19 apr 76 level 76110 490 $ r. kenner 491 $ 492 $ 1. allow reals to occupy more than one machine word (needed for 493 $ s16) by defining global variable -rlsz- which gives size of 494 $ real quantity. 495 $ 2. define size of real comparisons to be 1. 496 $ 3. include csadump in standare table dump (tabdump). 497 $ 4. avoid negative division in sdsnamr. 498 $ 5. initialize nstouse to localblock in case unsized variables. 499 $ encountered at start of program. 500 $ 6. replace macro 'notrealcomp' with 'realcomparison' to avoid 501 $ 'negative' logic and to increase readability. 502 $ 7. correct mispunched apostrophes in glossary. 503 $ decks affected - gloss, start, genini, arith, gencall, genreal, 504 $ cnvcon, emit1, emit2, sdsnamr 505 506 507 $ rbka r. kenner 24 march 1976 level 76085085 508 $ 509 $ continue work on system/370 version, as follows: 510 $ 1. use lctime to get time and date. 511 $ 2. restructure table dumps to permit overlaying. main table 512 $ dump is now -tabdump-, which calls voadump, etc. 513 $ 3. add variable nwarnings to count warnings, and call setcc 514 $ to report condition code on gen termination. 515 $ 4. clean up some of error-message handling. 516 $ 5. give initial values for some previously uninitialized vars. 517 $ ( the source has been resequenced ) 518 519 520 $ (none) d. shields 10 february 1976 level 76041 521 $ 522 $ the source has been cleaned up and some variables have been 523 $ renamed. the parser and code formerly in deck -blocken- have been 524 $ extensively rewritten. 525 $ this version supports all language features, including the 526 $ recent extensions to support subscripted labels and an 527 $ elseif clause in if statements. 528 $ the voa layout is basically the same except that the field 529 $ -dboup- has been added for drop bit for those operations in 530 $ which oup field is used to hold input. 531 $ the field 'free' is no longer used by gen. 532 $ 533 $ the entire source has been resequenced, so this mod has no 534 $ name. future mods should have a name based on logical function 535 $ if the mod adds or repairs a feature, or a name based on author 536 $ initials for miscellaneous corrections not related to any 537 $ one feature. 538 $ decks affected - (all) 539 1 .=member gloss 2 $ glossary (m denotes macro, v variable, r routine) 3 $ ':name' indicates item is field of structure named. 4 5 $v accesstab. bit vector of mba-indexes of accessed namesets. 6 $r advstr. advance string in lexicograhic order:'aa','ab',...'az',etc. 7 $m amode_real. code for amode of real (floating point) item. 8 $m amode. arithmetic mode (/=normal,1=real) :voa 9 $r arastar. collect and list array usage statistics.(cf. genexit) 10 $m arb. 'is this argument of current routine' :voa(var) 11 $m argbeg. starting index in -xarg- of extra values. :voa(op) 12 $v argct. number of formal arguments of current routine. 13 $m arglen. number of -xarg- entries used. :voa(op) 14 $v arglist. parser /generator common stack, codes and ha indices. 15 $m argmax. dims of arglist. 16 $m argno. if arb set, then argument index. :voa(var) 17 $v argptr. top of arglist. 18 $r arith. process binary operation. 19 $m asmhdr_vn. (voa file) version number of header block 20 $v asmvoadupmp. flag set by 'ad' option to get voa dump of each proc. 21 $r assembl. write tables for assembler use. 22 $m assertdim. dims of assert stack ('assert' debug request) 23 $v assertfg. flag, on when inside 'assert' statement expression. 24 $v assertst. stack of names seen in 'assert' expression. 25 $v assertstp. top of assertst. 26 $v bifatrtab. array giving names and attributes of builtin functions. 27 $m bifofop(op). maps opcode of builtin op into bifatrtab index 28 $m bifresmode(op). arithmetic mode of result of builtin function 29 $v bifxhasearch. flag, on to indicate xha search for function name,n. 30 $m bintok. lexical type of binary constant. 31 $r blkend. terminate basic block. 32 $v blkendreset. number of times blkend reset deflev field. 33 $m blockmax. maximum number of voa entries in basic block 34 $m bodylbl. -ha- index of 'body' label. :csa 35 $v buildreal. flag, on when constructing real variable. 36 $m builtin(op). is op a builtin function. 37 $m call_noparms. -gencall- code for call with no parameter list. 38 $m call_parms. -gencall- code for subroutine call with parameters. 39 $m call_value. -gencall- code for function call or indexed load. 40 $m calldebug(routnam). call offline debug routine. 41 $v cca. array of characters of constant to convert (cf. cnvcon) 42 $v ccaptr. position of last character in cca. 43 $v cclt. lexical type for constant conversion. 44 $v ccnchars. number of characters if inserting string const. 45 $v ccsyze. number of bits in converted constant value. (cf. cnvcon) 46 $v ccval. array containing converted constant value. (cf. cnvcon) 47 $v ccvalptr. number of words used in ccval. (cf. cnvcon) 48 $v cexpress. flag, on when parse must obtain constant expression. 49 $m charl(c). print character. 50 $r charpak(pa,ua,n). (library) pack n chars in ua into pa. 51 $m charofdig(d). map digit into character code. 52 $m chinxf. is 'check index' debug request in effect. :ha 53 $v chinxfg. debug, type of check index trace in effect. 54 $r chinxr. process debug indexed stores check statement. 55 $v chinxrp. debug, global parameter to routine chinxr. 56 $r cnvcon. convert constants. 57 $m commutes(op). 'does this operator commute' 58 $r comptok. compare opening and closing tokens in compound statement. 59 $m const. is this item a constant. :voa 60 $m constok. code of lowest constant. 61 $m conval(hap). first word of constant value with ha index hap 62 $m countup(var,lim,msg). set var=var+1. fatal error if var.gt.lim 63 $m cpw. (ws/cs). number of characters in word. 64 $m cs. number of bits in character. 65 $v csa. c-ompound s-statement a-rray, tracks compound statements. 66 $m csacountup(msg). increment csa top pointer. 67 $r csadump. list contents of csa. 68 $m csamax. dims of csa (c-ompound s-tatement a-rray) 69 $v csaptr. top of csa. 70 $m csasz. size of csa entry. 71 $v csatok. stack of opening tokens of pending compount statements. 72 $m csatokmax. dims of array used for saving tokens for csa 73 $v csatokptr. top of csatok. 74 $m csiftype_else. csa cstype code for else clause. 75 $m csiftype_sif. csa cstype code for simple if statement 76 $m csiftype_then. csa cstype code for then clause. 77 $m csiftype. type of -if- clause. :csa 78 $m cstype_do. csa cstype code for do statemett group. 79 $m cstype_fnct. csa cstype code for function. 80 $m cstype_if. csa cstype code for if statement group. 81 $m cstype_subr. csa cstype code for subroutine. 82 $m cstype_while. csa cstype code for while statement group 83 $m cstype. compound statement type. :csa 84 $v curblock. voa index of first entry in current basic block. 85 $v currsubrname. name of current routine in sds format. 86 $v daopt. flag, set by 'da' option, to grant 'default access'. 87 $m db1. 'is this last use of first operand (inp1)' :voa(op) 88 $m db2. 'is this last use of second input (inp2)' :voa(op) 89 $m db3. 'is this last use of third input (inp3)' :voa(op) 90 $v debugfg. flag, on when debug option(s) in effect. 91 $v debugsttus. flag, on if any debug option seen. 92 $v debugtab. stack used to communicate with rum-time debugging procs. 93 $m dectok. lexical type of decimal integer. 94 $m defaulttokenfilename. default name for token file. 95 $m defaultvoafilename. default name for voa file. 96 $m deflev. definition level of item. :voa 97 $v defnstouse. mba index of nameset to be used. 98 $v deind. index in debugtab. 99 $v denwd. number of words in debugtab entry. 100 $v deparm. global for macro 'callrout'. 101 $m digofchar(c). map character codefor digit into numeric value 102 $m dims. dimension value (0 if no dimension) :voa(var) 103 $m dimsmax. maximum allowed value for dims. 104 $v docontrace. flag, on when constant values to be listed. 105 $m dohip. -ha- index of -hi- exprssion in -do- :csa 106 $m doincp. -ha- index of 'increment' expression for 'do' :csa 107 $m dolop. -ha- index of 'lo' variable in -do- :csa 108 $m dosignp. 'is this descending do loop (by -)' :csa 109 $m dovarp. -ha- index of -do- loop variable. :csa 110 $m dsetoconst(i,c). debugtab(i) = c (c a constant) 111 $m dsetolvar(i,hap,nw). debugtab(i) = hap, ww words in hap 112 $m dsetovar(i,hap). set debuttab(i) = hap. 113 $v echoline. flag, on when nextok is to list line only. 114 $m elseiftype. csa cstype code for elseif clause. 115 $r emass. construct assignment representation. 116 $v emassrest. number of times emass reset deflev field. 117 $r emcall. construct call representation. 118 $r emit1. construct unary operation representation. 119 $r emit2. construct binary operation representation. 120 $r emit3. construct extractor representation. 121 $v endblock. flag, on if next call seen is to end basic block. 122 $m endl. end current print line, start new one. 123 $m endlbl. -ha- index of 'end' label ending group. :csa 124 $m entrend. code for return trace. 125 $m entrrout. code for entry traee. 126 $v entrrouts. debug, stack of routines to have entry traced. 127 $v entrroutsp. top of entrrouts. 128 $m eos_code. (voa file) code for end of routine. 129 $m ep. index of corresponding boa entry. :ha 130 $r ermes. report semantic error. 131 $v ermesarg. auxiliary argument to ermes, usually ha index. 132 $r ermet. report syntactic error. 133 $v ermflag. flag, on to suppress 'unsized external' diagnostic. 134 $r ermlst. list boilerplate of syntactic error message. 135 $v ermsgno. syntactic error number. 136 $v everdebug. flag, set when debugging routines initialized. 137 $m filenamelen. maximum length of file names used by compiler 138 $m firstbuiltin. opcode of first intrinsic (builtin) function 139 $m firstst. line number of first statement in group. :csa 140 $v fivtoks. flag, on if opener tokens in compount statement must match 141 $m flowdo. flowp code for do. 142 $m flowend. flowp code for return statemett processing 143 $v flowgen. debug, flow number generator. 144 $m flowgenlim. maximum number of blocks traced by 'flow' debug option 145 $m flowhil. flowp code for while. 146 $m flowiff. flowp code for -f - false. 147 $m flowifgt. flowp code for if...go - true. 148 $m flowifnsf. flowp code for if...then...edd - if - false 149 $m flowifsf. flowp code for if - simple case - false. 150 $m flowift. flowp code fo it - true. 151 $m flowiftyp. trflowp field giving if typ. 152 $m flowlab. flowp code for label. 153 $m flowp. type of flow call. 154 $v flowrouts. debug, stack of routines to have flow traced. 155 $v flowroutsp. debug, top of flowrouts. 156 $m flowtil. flowp code for while. 157 $v fswitch. flag, on when compiling 'fnct', not 'subr'. 158 $m functyp. code for ha type 'function' 159 $r genacc. process access declaration. 160 $r genarg. process argument in routine declaration. 161 $r genasin. process assignment statement. 162 $r gencall. process call (or indexed load) 163 $r gencfi. process control format specification. 164 $r gencont. process continue statement. 165 $r gendat. process data declaration. 166 $r gendfi. process data format specification. 167 $r gendim. process dimension declaration. 168 $r gendo. process do statement. 169 $r genend. process end statement. 170 $r genexit. terminate gen compilation phase. 171 $r genextr. process extractor (.e., .f., .s., .ch.) 172 $r genfile. process file declaration. 173 $r genfnm. generate file name. 174 $r gengdi. process -get- data transmission request. 175 $r gengoby. process goby statement. 176 $r gengol. process go to or label definition (not subscripted). 177 $r gengosl. process subscripted label (go to or definition). 178 $r genif. process if statement clauses. 179 $r genifgo. process 'if(a1) go to a2'. 180 $r genini. initialize. 181 $r genioar. process implicit array transmission request. 182 $r genioit. process io data item specification. 183 $r geniost. process various clauses of io statements. 184 $r geniotr. process item for io transmission. 185 $r genns. process nameset declaration. 186 $r genpdi. process -pup- data transmission request. 187 $r genquit. process quit statement. 188 $r genreal. process real declaration. 189 $r genret. process return statement. 190 $r gensert. process debug assert statement. 191 $r gensiz. process size declaration. 192 $r gensub. process subroutine delaration (subr/fnct). 193 $r gentrac. process debug trace statement. 194 $r genuntl. process until statement. 195 $r genwhil. process while statement. 196 $r getdebug. initialize for debug package use. 197 $r getiov. get local variable for use in io. 198 $m getlpos(p). store current print line position in p. 199 $r getxsds. get execution time form of sds object (dense form) 200 $m globalblock. index in mba of first global variable block 201 $v gsopt. 'gs' option flag, on for globals in start. 202 $r gtoflo. increment pointer, abort on overflow. 203 $m ha_code. (voa file) code for ha block. 204 $m ha_vn. (voa file) version number of ha. 205 $v ha. common hashed array, symbols known by ha index. 206 $m hacont. continue ha search. 207 $r hadump. list contents of ha. 208 $m haend $ end of ha search. 209 $r haerr(a). print contents of ha(a) as diagnostic aid 210 $m hamax. dims of ha (must be prime) 211 $v ha_0. ha index of constant '0'. 212 $v ha_1. ha index of constant '1'. 213 $m haprobe(j, hcode). start ha search. j is index, hcode is hash. 214 $m haquit $ terminate ha search. 215 $m hascon. 'is this ha entry that of safe (short) constant'. :ha 216 $m hasz. size of ha. 217 $m hermax. maximum acceptable level for deflev check. 218 $m hostmachine. index of host machine. 219 $m ifaglob(xhap,nam). if ha(nam) corresponds to global,set xhap to xha 220 $r ifaglor. implement ifaglob macro, see if name in xha (with access). 221 $v ifaglorname. global parameter for macro 'ifaglob'. 222 $v ifcongoto. number of 'if' statements converted to 'go to'. 223 $v ifcontot. number of 'if' statements with constant expression. 224 $m ifnum. block number (used by debug) :csa 225 $m indebug. $ see if debug requests in effect. 226 $m inloc. 'register containing item address' (asm use) :voa(var) 227 $m inp1. voa index of first input. :voa(op) 228 $m inp2. voa index of second input. :voa(op) 229 $m inp3. voa index of third input. :voa(op) 230 $m inreg. register holding item value (asm use) :voa(var) 231 $r inscon. insert converted constant into ha. 232 $m insglob(glohc, namea). insert name from ha(namea) into xha, setting 233 $r insglor. implement insglob macro, put name into xha. 234 $r insname. locate name in ha (insnarg, insnchars global args). 235 $v insnarg. array containing name used by macro insname. 236 $m intl(i). print integer in five columns. 237 $m intlp(i,p). list integer i in p columns. 238 $v iobufforgm1. size of status block needed for io on file. 239 $v iodfitems. array of parameters for formatted transmission. 240 $v ioerror. flag, set when error in io to skip rest of statement. 241 $v iofilekeys. array of attributes given in file statement. 242 $v iofilename. ha index of filename for io statement. 243 $m ioformats. number of io formats. 244 $v ioformatted. flag, on when generating formatted io fragment. 245 $v iofts. string appended to file names to isolate them. 246 $v iohi. ha index of last, or high, subrscript ot array for io. 247 $v iokey. code of io keyword, (cf. parse) 248 $v iokonst. length of generated array for io file nameset. 249 $v iolo. ha index of first, or low, subscript of array for io. 250 $v ionameflag. flag, on in 'namelist' io item transmission. 251 $v ionames. array of names of run-time io support routines. 252 $m ionamesptr. number of io routines , dims of ionames 253 $m ior_adrf:ior_vfmt. internal codes for io library functions 254 $v iorts. string appended to io run-time routine names to isolate them 255 $v iota. stack of items that io is to transmit. 256 $m iotahi. (iota field) ha index of last array element to transmit 257 $m iotalo. (iota field) ha index of first array element to transmit 258 $m iotamax. dims of iota. 259 $v iotaptr. top of iota. 260 $m iotavar. (iota field) ha index of item to transmit. 261 $v iova. stack of local variables used by io. 262 $v iovabusy. string of iova indices of variables currently 'busy'. 263 $m iovaha. (iova field) ha index of variable. 264 $m iovamax. dims of iova. 265 $v iovaptr. top of iova. 266 $v iovar. ha index of item io is to transmit. 267 $m iovasize. (iova field) variab. 268 $m iovasize. (iova field) voa index of entry giving vraiable size 269 $m iovasz. size of iova array (io v-ariable a-rray) 270 $v iowriting. flag, on if compiling 'put' type statement. 271 $m isafnct. 'is this name used as external functon' :voa(var) 272 $m isareal(x). 'is this real item', just 'amode x = amode_real' 273 $v isnchars. global parameter used by macro insname. 274 $r isusep. implement isuse macro, note use of input. 275 $m keeb. 'must this temporary be kept till end of block :voa 276 $v keeptok. flag, set to force nextok to return current token again. 277 $r keycode. get io code of current token. 278 $m labdef(l). indicate definition point of label. 279 $v labgen. string giving name of last generated label. 280 $m labget(l). generate new label name, return lablist index in l 281 $m labha. index in ha of label name. :lablist 282 $m labintern. 'is this compiler generated label' :ha 283 $m labldef(v, labnum). note label definition. 284 $v lablist. stack of label information. 285 $m lablistlen. maximum number of allowed labels (dims of lablist) 286 $v lablistptr. top of lablist. 287 $m labluse(labnum). note use of label in lablist(labnum) 288 $m labno. lablist index if name used as label. :ha 289 $m labsz. size of lablist entry. 290 $m labuses. number of label uses. :lablist 291 $m labvoa. voa index of label definition. :lablist 292 $m lastbuiltin. opcode of last intrinsic (builtin) function 293 $m lastuse. 'offset of last op in block to use this value':voa(op) 294 $m lbtok. lexical type of h-format string constant. 295 $v lcp_opt. list compilation parameters option value. 296 $v lcs_opt. list compilation statistics option value. 297 $m lc_. this prefix indicates literal code value used for keywords 298 $m lenmax. maximum number of temporaries watched by gettemp 299 $m levmax. maximum definition level. 300 $v levmin. level used in redundant expression optimization. 301 $v levnow. minimum acceptable definition level for redundant comps. 302 $v lexlist. circular array of recent tokens seen. 303 $m lexlistfew. number of recent tokens listed after error 304 $m lexlistmax. number of recent tokens saved (must be power of 2) 305 $v lexlistptr. current position in lexlist. 306 $m lextype. lexical type of constant. :voa(var) 307 $v listsw. flag, on to list input text. 308 $m litclassz. size of entry in littab. 309 $m litcodes. number of literal codes. 310 $m lithasz. size of literal hash table. 311 $m litmax. dims of littab and litha (must be prime) 312 $m litsz. maximum size of literals (as sds) 313 $v littab. array of literal attributes (cf. macro littabl) 314 $m littabl(class,indx) -bronlit- codeing for ... 315 $m littabsz. size of littab. 316 $m littokorg. origin of sds littok used to hold literals as sds 317 $v loadha...loadxha. max. no. of entries used in arrays. 318 $v loadrha...loadrxha. routines with max. usage. 319 $m localblock. mblk code for local variable block. 320 $v localforce. flag, on to force allocation in local block. 321 $v lvgen. sds naming last generated local variable. 322 $m lztok. lexical type of l-format string constant. 323 $m macdef(text). define inner macro with body text. 324 $m macdrop(name). drop macro status of name. 325 $m madr. machine address, offset in machine block. :voa(var) 326 $r marith. process unary operation. 327 $m maxxam. max. number of repetitions of syntactic construct allowed 328 $m mba_vn. (voa file) version number of mba. 329 $v mba. m-achine b-lock a-rray with nameset attributes. 330 $m mbacode. (voa file) code for mba block. 331 $m mbalen. length of machine block in words. :mba 332 $v mbaptr. top of mba. 333 $m mbdef. 'is this nameset being defined in this routine' :mba 334 $m mbha. ha index of nameset name. :mba 335 $m mblk. machine block (mba index) of item. :voa(var) 336 $m mbused. 'is this nameset used in current routine' :mba 337 $m mbxha. -xha- index of nameset name. :mba 338 $m mcs. number of bits in target machine character. 339 $m minus. csa dosignp code for downward loop (by - ...) 340 $m modesize. length of amode field in voa. 341 $m mps. number of bits in target machine pointer or address 342 $m msl. length of length field for sds on target machine 343 $m mso. length of origin field on target machine sds. 344 $m mws. number of bits in target machine word. 345 $m m16. code for machine honeywell series 16 minicomputers 346 $m m37. code for machine ibm system/370. 347 $m m66. code for machine cdc 6600. 348 $m nameblockorg. origin of name block. 349 $m nameorg. sorg value for nam. 350 $m names_code. (voa file) code for names block. 351 $m names_vn. (voa file) version number of names. 352 $v names. stack giving characters of names. 353 $m namesmax. dims of names array. 354 $v namesptr. next available location in names. 355 $m nametok. code for lexical type of 'name' token. 356 $m nametok. lexical type of name. 357 $m naml(hap). print name of item in ha(hap) 358 $m namsz. size of strings used to hold sds names built internally 359 $m naym. ha index for this item. :voa 360 $m nayme. index in -names- of characters in name. :ha 361 $m nblocks. maximum number of machine blocks. 362 $v ncards. number of source cards processed so far. 363 $v ncfopt. option flag, on if can fold to get negative constants. 364 $v ncftot. number of constant foldings that gave negative result. 365 $m nchars. number of characters in name or constant. :ha 366 $v nerrors. number of detected errors. 367 $r nextok. get next token. 368 $v nl. n-ames l-ist stack giving attributes of global vars. 369 $m nlamode. saves 'amode' :nl 370 $m nlblk. saves 'mblk' value. :nl 371 $m nlchinx. saves 'check/nocheck' state. :nl 372 $m nldimn. holds 'dims' value. :nl 373 $r nldump. list contents of nl. 374 $m nlha. xha index for this variable. :nl 375 $m nlmadr. saves 'madr' value. :nl 376 $m nlmax. dims of nl. 377 $m nlno. -nl- index of variable. :xha 378 $m nlsize. saves 'syze' value. :nl 379 $m nlsz. size of nl entry. 380 $m nltrac. saves 'trace/notrace' status. :nl 381 $m no. 0 (for readability) 382 $m noopb. 'is this operation to be suppressed' :voa(op) 383 $m nopcodes. number of opcodes (in voa) 384 $m notraceall. code for 'o. 385 $m notracesome. code for 'no trace some' debug request 386 $v nsflag. flag, set when inside nameset definition block. 387 $v nstouse. mba index of nameset to use for next size statement. 388 $v nsubrs. number of routines compiled. 389 $m numfncts. total number of library and builtin functions 390 $v nwarnings. number of warnings. 391 $m octl(i). list contents of i in octal. 392 $m octtok. lexical type of octal constant. 393 $m opb. 'is this an operation' :voa 394 $m opcode. operation code (names by macros of form 'op_') :voa(op) 395 $v opkind. table of operator attributes. 396 $m oplev. operation level for precedence parse. :opstack 397 $m opofbif(op). maps bifatrtab index into opcode of builtin function 398 $m opstackmax. dims of opstack ,max. allowed nesting in expressions) 399 $v opstackp. depth of operator precedence parse. 400 $m optyp. operation type. :opstack 401 $m oup. voa index of item holding result. :voa(op) 402 $r parse. the parser proper. 403 $v parseok. flag, on when parse automaton in 'success' state. 404 $v parsetrace. flag, on to trace parser in action. 405 $m pdotok. lexical code for period delimited operator. 406 $m plus. csa dosignp code for upward do loop (by +...) 407 $m pop(a). retrieve a from arglist. 408 $v proclineno. line number relative to start of current routine. 409 $m ps. number of bits in address or pointer. 410 $r psdstok. get sds form of current token. 411 $r pshnamr. implement pushname macro to hash name, put on arglist. 412 $r ptdata. data statements for parse table pt. 413 $r purge. cleanse tables, prepare for next routine. 414 $m push(hap) $ push hap onto arglist. 415 $r pshintr. implement pushint macro, hash const, put on arglist. 416 $m pushint(pcon). push short integer onto arglist 417 $m pushname(hc, r). push name on arglist. 418 $r pushr. implement push macro, push item onto arglist. 419 $r putvofa. put array slice onto voa file. 420 $m qstok. lexical type of q-format string constant. 421 $m quant. code for ha type 'quantity' 422 $m q3(a,b,c). used to define macros in macros. 423 $m rbtok. lexical type of d-format string constant. 424 $m realopcd(x). 'is opcdde that of real operation' 425 $m realcomparison(op). 'is this real comparison.' 426 $m realtok. lexical type of floating point constant. 427 $m rztok. lexical type of r-format string constant. 428 $v safeconst(a). 'is ha(a) a safe(short) constant.' 429 $v savetoks. number of tokens to be saved in compound statement opener 430 $m sds(n). size of sds item of n characters. 431 $m sdslit. convert token into sds form in littok. 432 $m sdsname(sdsnam, hap). convert ha(hap) item into sds form in sdsnamr 433 $r sdsnamr. implement macro sdsname, used to get sds format. 434 $v sdsnamstr. global scratch area for constructing strings(cf sdsname) 435 $r setcall. debug auxiliary, generate call to run-time debug routine. 436 $r setcons. debug auxiliary, set 'debugtab(deind)=deparm'.(constant) 437 $r setlabl. implement macro setlab, note use of label. 438 $m setlpos(p). set current line position to p. 439 $r setlvar. debug auxiliary, set 'debugtab(deind)=deparm'.(multi-word) 440 $r setq. verify acceptability as value-returning item. 441 $r setvar. debug auxiliary, set 'debugtab(deind)=deparm'. 442 $v sfp_opt. option flag, if on then first routine not put on voa file. 443 $m signbit. 'is this negatibe constant' :voa(var) 444 $v signofcon. flag, on when processing negative constant. 445 $m skipl(i). skip i columns on print line. 446 $m slabbias. upper bound on absolute value of label subscripts 447 $m slen. length field of sds. 448 $m sorg. origin field of sds. 449 $m spectok. code for lexical token of type special. 450 $r squeeze. list most recent tokens seen. 451 $r start. define global variables, initiate execution. 452 $m strtok. lexical type of sds format token. 453 $v subinfo. array of miscellaneous attributes passed to asm. 454 $m subrtyp. code for ha type 'subroutine' 455 $m syze. item size in bits. :voa 456 $m szmax. largest acceptable value in size specification 457 $m tabl(i). move to column i on print line. 458 $v targetmachine. integer code for target machine. 459 $m temb. 'is this a temporary' :voa(var) 460 $m tent. size of temporary. :tlist 461 $m testlbl. -ha- index of 'test' label. :csa 462 $m textl(s). print string. 463 $m tintl(s,i). print string s and integer i. 464 $v tlist. stack of temporary attributes. (cf. blkend) 465 $m tlistmax. dims of tlist. 466 $v tlistptr. top of tlist. 467 $v tmara. array of target machine parameters. 468 $m tmparams. number of parameters in target machine specification 469 $v tmtokara. array of values for converting target machine attributes. 470 $m tmvardef. string giving machine parameters. 471 $m tnext. tlist index of next temporary of same size. :tlist 472 $v tokara. array with token as received from scanner. 473 $m tokaradims. dims of tokara. 474 $m tokarasz. size of tokara. 475 $v toklc. literal code value of current token. 476 $v toklen. token length in characters. 477 $m toklenmax. maximum token length in characters. 478 $v toklt. lexical type of current token. 479 $m toknum. number of tokens saved from opener. :csa 480 $m tokorg. starting token in token list. :csa 481 $v tokrbuf. buffer for reading token file produced by scanner. 482 $m tokrbuflim. dims of tokrbuf (buffer used to read token file) 483 $v tokrbufp. current position in tokrbuf. 484 $m tokrcard. code for card image record on token file. 485 $m tokreof. code for end-of-data on token file. 486 $m tokrlc. token file field giving literal code of token 487 $m tokrlen. token file field giving token length in characters 488 $m tokrtyp. token file field giving token lexical type 489 $m tokrval. token file field giving first few hharacters of token 490 $v tokwords. number of tokara entries used for token. 491 $v tothaexam. number of ha entries examined. 492 $v tothaprobe. number of times ha search initiated. 493 $m totmachines. number of known host, target machines. 494 $v totwaste. number of unused machine words in tables.(cf. genexit) 495 $m traceall. code for 'trace all' debug reqest. 496 $m tracef. is 'trace stores' request in effect. :ha 497 $m tracesome. code for 'trace some' debug reques. 498 $v trentrfg. debug, type of trace entry in effect. 499 $v trentrp. global for macro trentry. 500 $r trentrr. process debug trace entry statement. 501 $m trentry(t). callto debugging generator. 502 $m trflow(t). call to debuggigg generator. 503 $v trflowfg. debug, type of flow trace in effect. 504 $v trflowl. debug, point to ha index of label. 505 $v trflowp. global for macro trflow. 506 $r trflowr. process debug flow trace statement. 507 $m trroutsdim. array dims of array used to coollect subr names 508 $v trstorfg. debug, type of store trace in effect. 509 $v trstori. debug flag, on for indexing. 510 $v trstorp. global argument for routine trstorr. 511 $r trstorr. process debug assignment trace statement. 512 $v trstors. debug, ptr to assignment source. 513 $v trstor1...trstor5. globals for debug assignment trace. 514 $m type. quantity type. :voa(var) 515 $m untiltyp. csa cstype code for until statemett group 516 $m val_code. (voa file) code for val block. 517 $v val. stack of converted constant values. 518 $v valptr. next free position in val. 519 $m val_vn. (voa file) version number of val. 520 $m valmax. dims of val. 521 $m var. 'is this not an operation' :ha 522 $m varpos(i). 'mblen mba(i)', current position in i-th machine block 523 $m vbeg. first word of constant value in -val- :voa(var) 524 $m vlen. number of -val- entries used for constant value :voa(var) 525 $v voa. v-ariable and o-perations a-rray. ha and voa form symbol table 526 $m voa_code. (voa file) code for voa block. 527 $m voa_vn. ,voa file) version number of voa. 528 $m voaasm_code. (voa file) code for routine header block 529 $r voadump. list contents of voa. 530 $m voaeof_code. (voa file) code for end of file. 531 $m voahdr_code. (voa file) code for header block. 532 $m voasz. size of voa. 533 $m voaup. increment voptr (top of voa) 534 $v vof. scratch area used to build frames for voa file. 535 $m vof_asmarg. (voa file header field) asmarg values. 536 $m vof_code. (voa header field) item code. 537 $m vof_debugtab. (voa file header field) value of -debugtab- 538 $m vof_es. (voa file header field) entry size in bits. 539 $m vof_hamax. (voa file header field) -hamax- (ha dims) known to gen 540 $m vof_ha0. (voa file header field). ha_0 value. 541 $m vof_ha1. (voa file header field). ha_1 value. 542 $m vof_hi. (voa file header field) -hi- index of array to transmit 543 $m vof_init. (voa file header field) -init- value. 544 $m vof_lablistptr. (voa file header field) vluue of lablistptr 545 $m vof_lo. (voa file header field) -lo- index for array 546 $m vof_subrargs. (voa file header field) no. of arguments of routine 547 $m vof_sub1. (voa file header field) subinfo(1) 548 $m vof_sub2. (voa file header field) subinfo(2) 549 $m vof_sub3. (voa file header field) subinfo(3) 550 $m vof_tf. (voa file header field) number of trailing data frames 551 $m vof_vn. (voa file header field) - version number. 552 $m vofsz. size of frame on voa file. 553 $m vomax. dims of voa. 554 $v voptr. next free position in voa. 555 $m wordl(w). print all characters in machine word w. 556 $m wpc. number of words for card image. 557 $m ws. number of bits in machine word. 558 $m xarg_code. (voa file) code for xarg block. 559 $m xarg_db. drop bit for this entry in xarg. :xarg 560 $m xarg_rep. replication value for 'data' value. :xarg 561 $m xarg_vn. (voa file) version number of xarg. 562 $m xarg_voa. voa index of item. :xarg 563 $v xarg. extra arguments array used for voa items with many inputs. 564 $m xargmax. dims of xarg. 565 $v xargptr. next free position in xarg. 566 $m xargsz. size of xarg. 567 $v xha. ha for global symbols. 568 $m xhabif. 'is this name of builtin function' :xha 569 $r xhadump. list contents of xha. 570 $m xhasz. size of xha. 571 $m xlink. next -xha- entry with same hash code. :xha 572 $m xnameptr. -xnames- index of characters in name. :xha 573 $v xnames. names array for xha, holds names of globals. 574 $m xnamesmax. dims of xnames. 575 $v xnamesptr. next free position in xha. 576 $m xnchars. length of name in characters. :xha 577 $m xnsblk. machine block (-mba- index) of nameset. :xha 578 $m yes. 1 (for readability) 579 $m zerents. number of zero ha entries before this one. :ha 580 581 1 .=member macros 2 3 $ compilerlevel is the date of last compiler change, 4 $ and must be updated when compiler changed. 5 +* compilerlevel = rbko 9 'gen(82158)' $ 6 jun 1982 7 ** 8 9 +* voafilelevel = $ julian date of last change which alters 10 $ structure of voa file. 11 $ subtract 76000 from date to permit representation in 16 bits 12 76289 $ 15 october 1976. 13 -76000 ** 14 $ conditional text options. 15 16 $ the conditional fragments which collect statistics may be of 17 $ interest when bootstrapping the compiler and to periodically 18 $ monitor compiler performance. these fragments are usually 19 $ omitted in a production compiler as users may be confused by 20 $ statistics. 21 22 $ select haprobes to compute statistics on ha searches. 23 .-set haprobes 24 25 $ select ifconstat to compute and list statistics of number 26 $ of -if- statements with constant inputs. 27 .-set ifconstat 28 29 $ select ncfstat to print number of negative constants seen. 30 .-set ncfstat 31 32 $ select realsc to obtain constant folding of expressions in 33 $ real constants (cf. arith). if realsc is enabled, the 34 $ compiler must process real constants and expressions. 35 $ at present, code contained in realsc text is the only use 36 $ of real contants and operations in this program. 37 .+set realsc 38 ldsa 23 $ select rep to enable option to produce report file. ldsa 24 $ report written to unit repfile (nominally 6). ldsa 25 ldsa 26 .+set rep ldsa 27 dso 9 .+s10. dso 10 .+set movea_env dso 11 .+set movw_env dso 12 .+set unpk_env dso 13 .+set pack_env dso 14 ..s10 utse 1 .+s32. utse 2 .+set s32v $ assume vms. utse 3 ..s32 utse 4 utse 5 .+s32u. utse 6 .+s32. utse 7 .-set s32v $ do not want vms. utse 8 .+set s32u $ want unix os. utse 9 ..s32 utse 10 .+set mcl $ want primary case to be lower. utse 11 ..s32u vax 9 .+s32. mgfc 8 .+set movea_env,movw_env,unpk_env,pack_env vax 11 ..s32 39 .+s37. 40 .+set movea_env,movw_env,unpk_env,pack_env 41 ..s37 utsa 16 .+s47. utsa 17 .-set movea_env,movw_env,unpk_env,pack_env utsa 18 ..s47 42 .+s66. 43 .+set movw_env,unpk_env,pack_env 44 ..s66 45 utse 12 .+s32u. $ delete env special code for checkout. ldsb 18 .-set movea_env,movw_env,unpk_env,pack_env utse 13 ..s32u 46 47 $ define macros giving machine parameters, codes, and oft-used 48 $ code sequences not related to any particular data structure. 49 $ (information relevant to a particular data structure is 50 $ given alphabetically by structure/variable name in the 51 $ routine -start- that immediately follows the macros.) 52 53 $ target machine parameters 54 +* ws = .ws. ** $ machine word size. 55 +* ps = .ps. ** $ machine pointer (address) size. 56 +* cs = .cs. ** $ machine character size. 57 +* cpw = (ws/cs) ** $ characters per machine word 58 59 60 $ fields of self-defining strings 61 +* sorg = .e. (.sl.+1), .so., ** $ origin field of sds. 62 +* slen = .len. ** $ length field of sds. 63 64 +* wpc = $ number of words in card image 65 .+s66 09 vax 12 .+s32 20 $ 80 columns 66 .+s37 20 $ 80 columns utsa 19 .+s47 20 $ 80 columns mgfb 8 .+s10 20 68 ** 69 70 $ target machine specification and identification. 71 72 +* tmparams = 5 ** $ number of parameters in machine specificatio 73 $ the previous variables -mws-, -mps-, and -mcs- 74 $ are equated to elements in tmara to simplify initialization a 75 $ and to ease addition of new parameters. 76 +* mws = tmara(1) ** $ target machine word size 77 +* mps = tmara(2) ** $ target machine pointer size 78 +* mcs = tmara(3) ** $ target machine character size 79 +* msl = tmara(4) ** $ target machine length of slen field 80 +* mso = tmara(5) ** $ length of target machine sorg field 81 82 +* tmvardef = $ default tm specification taken by compiler 83 .+s66 '6017061113' dso 15 .+s40 '1615081616' vax 13 .+s32 '3230081616' utsa 20 .+s37 '3224081616' utsa 21 .+s47 '3224081616' mgfb 9 .+s10 '3618091818' 86 ** 87 88 $ macros for machine encodings utsa 22 +* totmachines = 8 ** $ number of known host, target machines 90 +* m66 = 1 ** $ cdc 6600 91 +* m37 = 2 ** $ ibm system/370 92 +* m16 = 3 ** $ honeywell series 16 93 +* m11 = 4 ** $ pdp-11. 94 +* m10 = 5 ** $ dec system/10 dso 18 +* m40 = 6 ** $ prime 400 vax 15 +* m32 = 7 ** $ dec vax-11 utsa 23 +* m47 = 8 ** $ amdahl uts 95 96 +* hostmachine = $ machine on which compiler runs 97 .+s66 m66 dso 19 .+s40 m40 vax 16 .+s32 m32 98 .+s37 m37 utsa 24 .+s47 m47 99 .+s10 m10 100 ** 101 102 +* blankword = $ word of blank chars (see insname). vax 17 .+s32 4r 103 .+s37 4r utsa 25 .+s47 4r dso 20 .+s40 2r 104 .+s66 10r mgfb 10 .+s10 4r 106 ** 107 108 109 $ macros related to file names 110 +* filenamelen = 20 ** $ max. length of file name in chars. dsu 9 .+s32 +* filenamelen = 64 ** utsa 26 .+s47 +* filenamelen = 64 ** 111 dsv 12 $ getapp_len is length of actual parameter string (cf. lexini). dsv 13 +* getapp_len = 128 ** dsv 14 .+s32 +* getapp_len = 240 ** utsa 27 .+s47 +* getapp_len = 240 ** dsv 15 112 +* tokenfile = 3 ** $ token file number. 113 114 +* voafile = 4 ** $ voa file number. 115 116 +* crfile = 5 ** $ cross reference file number. 117 ldsa 28 .+rep +* repfile = 6 ** $ file if rep option enabled. dsx 22 118 $ io access codes. 119 +* access_read = 4 ** 120 +* access_write = 6 ** 121 122 $ macros for listing generation (routines in run-time library). 123 124 +* textl(s) = call textlr(s); ** $ output text 125 +* intl(i) = call intlr(i); ** $ output integer (5 digits) 126 +* intlp(i,p) = call intlpr(i,p); ** $ integer i in p columns 127 +* tintl(s,i) = call tintlr(s,i); ** $ output text+integer 128 +* wordl(w) = call wordlr(w); ** $ output word 129 +* charl(c) = call charlr(c); ** $ output single character 130 +* endl = call endlr; ** $ end line 131 +* getlpos(p) = call contlpr(1,p);** $ get current line pos 132 +* setlpos(p) = call contlpr(2,p);** $ set line position 133 +* skipl(i) = call contlpr(3,i);** $ skip -i- columns 134 +* tabl(i) = call contlpr(4,i);** $ tab to column -i- 135 +* listl(n) = call contlpr(26,n);** $ set listing flag 136 +* terml(n) = call contlpr(27,n);** $ set terminal flag 137 +* ejectl = call contlpr(5,0);** $ eject to new page. 138 +* ejectlp(n) = call contlpr(5,n);** $ eject to new page 139 $ if less than n lines remain on current page. 140 141 +* digofchar(c) = $ value of character digit. 142 (c-1r0) $ use if codes for numbers in order. 143 ** 144 +* charofdig(c) = $ maps digit into character code 145 (c+1r0) $ use if codes for numbers in order. 146 ** 147 148 $ countup macro for incrementing and testing variable 149 +* countup(var,lim,msg) = 150 var = var+1; 151 if (var>lim) call gtoflo(var,lim,msg); ** 152 153 154 $ q3 and macdef are used to define macros in macros. macdrop 155 $ releases macro from macro status 156 157 +* q3(a,b,c) = a b c ** 158 +* macdef(text) = q3(+,*text*,*) ** 159 +* macdrop(mname) = macdef(mname=) ** 160 161 162 $ yes and no macros used for logical expressions to clarify 163 $ logical intent. 164 +* yes = 1 ** 165 +* no = 0 ** 166 167 +* blockmax = 3b'777' ** $ max length of basic block dsw 10 +* dimsmax = $ maximum dimension dsw 11 .+s10 3b'377777' dsw 12 .+s32 4b'3fffffff' dsw 13 .+s37 4b'3fffff' utsa 28 .+s47 4b'3fffff' dsw 14 .+s40 3b'177777' dsw 15 .+s66 3b'177777' dsw 16 ** 169 +* levmax = 63 ** $ maximum definition level, which is the 170 $ largest value that can be held in -deflev- field. 171 +* toklenmax = 150 ** $ maximum length of token in characters 172 173 +* keylenmax = 20 ** $ maximum length of 'key' in io clause. 174 +* namsz = .sds. toklenmax ** 175 +* nameorg = (namsz+1) ** 176 177 $ szmax is the maximum acceptable item size. if a larger size 178 $ item is requested, an error message is issued and the size 179 $ is reduced to szmax (see routine -gensiz-). szmax also 180 $ occurs in the run-time library text, and both values should 181 $ be the same. 182 +* szmax = $ maximum item size in bits 183 2047 184 ** 185 $ codes for type of call as used by generator -gencall-. 186 +* call_noparms = 1 ** $ no parameters, hence subroutine call 187 +* call_parms = 2 ** $ subroutine call with parameter list. 188 +* call_value = 3 ** $ call with value returned, must have 189 $ parameter list. may be function call or array reference. 190 191 $ the following macros assign codes to literals 192 $ these codes must be identical to the literal codes in lex 193 +* lc_if = 1 ** 194 +* lc_while = 2 ** 195 +* lc_until = 3 ** 196 +* lc_do = 4 ** 197 +* lc_end = 5 ** 198 +* lc_else = 6 ** 199 +* lc_size = 7 ** 200 +* lc_dims = 8 ** 201 +* lc_data = 9 ** 202 +* lc_semicolon= 10 ** 203 +* lc_nameset = 11 ** 204 +* lc_access = 12 ** 205 +* lc_real = 13 ** 206 +* lc_call = 14 ** 207 +* lc_goby = 15 ** 208 +* lc_return = 16 ** 209 +* lc_elseif = 17 ** 210 +* lc_goin = 18 ** $ 'in', not '.in.' 211 +* lc_sdsop = 19 ** $ .sds. 212 +* lc_voapart = 20 ** $ .voapart. $ for partial voa dmump 213 +* lc_rewind = 21 ** 214 +* lc_filestat = 22 ** 215 +* lc_go = 23 ** 216 +* lc_cont = 24 ** 217 +* lc_quit = 25 ** 218 +* lc_fext = 26 ** $ .f. 219 +* lc_eext = 27 ** $ .e. 220 +* lc_sext = 28 ** $ .s. 221 +* lc_chext = 29 ** $ .ch. 222 +* lc_ccat = 31 ** $ .cc. 223 +* lc_to = 32 ** 224 +* lc_or = 33 ** $ .or. 225 +* lc_ex = 34 ** $ .ex. 226 +* lc_exor = 35 ** $ .exor. 227 +* lc_orsym = 36 ** $ ! 228 +* lc_and = 37 ** $ .and. 229 +* lc_andsym = 38 ** $ & 230 +* lc_andbrev = 39 ** $ .a. 231 +* lc_eq = 40 ** $ .eq. 232 +* lc_ne = 41 ** $ .ne. 233 +* lc_gt = 42 ** $ .gt. 234 +* lc_lt = 43 ** $ .lt. 235 +* lc_ge = 44 ** $ .ge. 236 +* lc_le = 45 ** $ .le. 237 +* lc_eqsym = 46 ** $ = 238 +* lc_ltsym = 47 ** $ < 239 +* lc_gtsym = 48 ** $ > 240 +* lc_notsym = 49 ** $ ^ 241 +* lc_plus = 50 ** $ + 242 +* lc_minus = 51 ** $ - 243 +* lc_times = 52 ** $ * 244 +* lc_divide = 53 ** $ / 245 +* lc_in = 54 ** 246 +* lc_not = 55 ** $ .not. 247 +* lc_notbrev = 56 ** $ .n. 248 +* lc_fb = 57 ** 249 +* lc_nb = 58 ** 250 +* lc_check = 59 ** 251 +* lc_trace = 60 ** 252 +* lc_assert = 61 ** 253 +* lc_nocheck = 62 ** 254 +* lc_notrace = 63 ** 255 +* lc_subr = 64 ** 256 +* lc_fnct = 65 ** 257 +* lc_monitor = 66 ** 258 +* lc_lparen = 67 ** $ ( 259 +* lc_rparen = 68 ** $ ) 260 +* lc_comma = 69 ** 261 +* lc_colon = 70 ** 262 +* lc_then = 71 ** 263 +* lc_by = 72 ** 264 +* lc_index = 73 ** 265 +* lc_flow = 74 ** 266 +* lc_stores = 75 ** 267 +* lc_entry = 76 ** 268 +* lc_voadump = 77 ** 269 +* lc_len = 78 ** 270 +* lc_pad = 79 ** $ .pad. 271 +* lc_file = 80 ** 272 +* lc_nocontr = 81 ** 273 +* lc_toktr = 82 ** 274 +* lc_notoktr = 83 ** 275 +* lc_contr = 84 ** 276 +* lc_get = 85 ** 277 +* lc_put = 86 ** 278 +* lc_mws = 87 ** $ .ws. 279 +* lc_mps = 88 ** $ .ps. 280 +* lc_mcs = 89 ** $ .cs. 281 +* lc_msl = 90 ** $ .sl. 282 +* lc_mso = 91 ** $ .so. 283 +* lc_limit = 92 ** 284 +* lc_read = 93 ** 285 +* lc_write = 94 ** 286 +* lc_prog = 95 ** 287 +* lc_seq = 96 ** $ .seq. 288 +* lc_sne = 97 ** $ .sne. 289 290 +* litcodes = 97 ** 291 292 293 $ macros related to parser and lexical token processing 294 295 296 $ (codes must agree with those assigned by lex phase.) 297 $ the codes used in token reader routine -nextok- 298 $ codes for lexical types assigned in lexical scan 299 +* toktypes = 14 ** $ no. of token types below 300 +* nametok = 1 ** $ name 301 +* spectok = 2 ** $ special token, e.g. ( 302 +* pdotok = 3 ** $ type of period delimited operators 303 +* dectok = 4 ** $ type of decimal integers, e.g. 100 304 +* sstok = 5 ** $ special string token, e.g., 6s...mcr 305 +* strtok = 6 ** 306 +* bittok = 8 ** 307 +* rztok = 12 ** $ right-zero type string constant (r) 308 +* realtok = 14 ** $ real token 309 +* listcontroltok = 27 ** $ '.=list' directive. 310 +* listejecttok = 28 ** $ '.=eject' list directive. 311 +* listtitletok = 29 ** $ '.=title' directive. 312 +* tokrcard = 30 ** $ code for card image 313 +* tokreof = 31 ** $ code for end-token-file 314 315 .+s66. 316 +* tokrtyp = .f. 1, 5, ** $ token type (lex type or code) 317 +* tokrlen = .f. 7, 7, ** $ length of token in chars 318 +* tokrlc = .f. 14, 9, ** $ token literal code 319 .-s66. 320 +* tokrtyp = .f. 1, 8, ** 321 +* tokrlen = .f. 9, 8, ** 322 +* tokrlc = .f. 17, 8, ** 323 ..s66 324 325 +* tokrval = $ first few characters of short token. 326 .+s66 .f. 25, 36, dso 21 .+s40 .f. 25, 8, vax 18 .+s32 .f. 25, 8, dso 22 .+s37 .f. 25, 8, utsa 29 .+s47 .f. 25, 8, mgfb 11 .+s10 .f. 28, 9, 329 ** 330 331 +* cpstr = $ character per short token record 332 .+s66 6 dso 23 .+s40 1 vax 19 .+s32 1 dso 24 .+s37 1 utsa 30 .+s47 1 mgfb 12 .+s10 1 335 ** 336 337 +* constok = 4 ** $ code of first constant type 338 339 $ macros initializing machine blocks 340 +* nblocks = 63 ** $ number of loader machine blocks 341 +* localblock = 8 ** $ local variable block 342 +* globalblock = 10 ** $ global variable block 343 344 $ macros for ha-quantity type values 345 346 +* quant = 2 ** 347 +* subrtyp = 0 ** 348 349 350 +* nopcodes = 76 ** $ number of voa opcodes. 351 352 +* commutes(op) = $ is this operator commutative. 353 .f. 1, 1, opkind(op) ** 354 355 +* blkendtype(op) = $ gross type used by blkend. 356 .f. 3, 6, opkind(op) ** 357 358 $ macros defining opcodes of voa-operations 359 +* op_add = 1 ** 360 +* op_sub = 2 ** 361 +* op_gt = 3 ** 362 +* op_lt = 4 ** 363 +* op_ge = 5 ** 364 +* op_le = 6 ** 365 +* op_eq = 7 ** 366 +* op_ne = 8 ** 367 +* op_mul = 9 ** 368 +* op_div = 10 ** 369 +* op_or = 11 ** 370 +* op_seq = 12 ** $ .seq. character string equality. 371 +* op_and = 13 ** 372 +* op_exor = 14 ** 373 +* op_sne = 15 ** $ .sne. character string inequality. 374 +* op_nb = 16 ** $ number of bits operation 375 +* op_fb = 17 ** $ first bit operation 376 +* op_not = 18 ** $ not operation 377 +* op_fcall = 19 ** 378 +* op_usub = 19 ** $ unary minus 379 +* op_call = 20 ** $ call-type operation 380 +* op_scall = 20 ** 381 +* op_pad = 20 ** $ .pad. (not in -voa-) 382 +* op_asin = 21 ** $ simple assignment operation 383 +* op_data = 22 ** $ data operatio 384 +* op_fasin = 23 ** $ field assignment .f. 385 +* op_io = 24 ** $ binary transput 386 +* op_return = 25 ** $ return 387 +* op_fext = 26 ** $ extraction operation 388 +* op_if = 27 ** $ if (...) go to 389 +* op_lab = 28 ** $ label definition 390 +* op_goto = 29 ** $ go to 391 +* op_goby = 30 ** 392 +* op_xload = 31 ** $ indexed (array) load 393 +* op_xasin = 32 ** $ indexed store 394 +* op_xfasin = 33 ** $ indexed field store 395 +* op_ifnot = 34 ** $ if not 396 +* op_ccat = 35 ** $ .cc. operation 397 +* op_in = 36 ** $ .in. operation 398 +* op_eext = 37 ** $ .e. extract op 399 +* op_sext = 38 ** $ .s. extract operation 400 +* op_easin = 39 ** $ .e. field assignment 401 +* op_sasin = 40 ** $ .s. field assignment 402 +* op_xeasin = 41 ** $ .e. indexed field store 403 +* op_xsasin = 42 ** $ .s. indexed field store 404 +* rop_add = 43 ** $ real add 405 +* rop_sub = 44 ** $ real subtract 406 +* rop_gt = 45 ** $ real greater than 407 +* rop_lt = 46 ** $ real less than 408 +* rop_ge = 47 ** $ real greater than or equal to 409 +* rop_le = 48 ** $ real less than or equal to 410 +* rop_eq = 49 ** $ real equal to 411 +* rop_ne = 50 ** $ real not equal to 412 +* rop_mul = 51 ** $ real multiplication 413 +* rop_div = 52 ** $ real division 414 +* rop_usub = 53 ** $ real unary minus 415 +* bop_first = 54 ** $ first built-in function 416 +* bop_float = 54 ** $ integer to real 417 +* bop_ifix = 55 ** $ real to integer 418 +* bop_abs = 56 ** $ absolute value 419 +* bop_iabs = 57 ** $ absolute value 420 +* bop_aint = 58 ** $ sign of a * (largest integer <= abs(a)) 421 +* bop_int = 59 ** $ sign of a * (largest integer <= abs(a)) 422 +* bop_amod = 60 ** $ a1 mod a2 423 +* bop_mod = 61 ** $ a1 mod a2 424 +* bop_sign = 62 ** $ sign of a2 with abs(a1) 425 +* bop_isign = 63 ** $ sign of a2 with abs(a1) 426 +* bop_dim = 64 ** $ if a1 > a2 then a1-a2 else 0 427 +* bop_idim = 65 ** $ if a1 > a2 then a1-a2 else 0 428 +* bop_exp = 66 ** $ exponential 429 +* bop_alog = 67 ** $ natural log 430 +* bop_alog10 = 68 ** $ common log 431 +* bop_sin = 69 ** $ sine 432 +* bop_cos = 70 ** $ cosine 433 +* bop_tanh = 71 ** $ hyperbolic tangent 434 +* bop_sqrt = 72 ** $ square root 435 +* bop_atan = 73 ** $ arc tangent 436 +* bop_atan2 = 74 ** $ atan(a1/a2) 437 +* bop_last = 74 ** $ last builtin. 438 +* op_list = 75 ** $ list directive for asm. 439 440 441 +* proc_initiate = 'ltlini' ** $ initiation routine for program. 442 +* proc_terminate = 'ltlfin' ** $ program termination procedure. ldse 11 +* proc_expire = 'ltlced' ** $ check expiration date. 443 444 445 446 +* conval(hap) = (val(vbeg voa(ep ha(hap)))) ** $ constant value 447 448 $ macros to pop arguments from arglist 449 450 +* isuse(hap) = $ note use of ha(hap) as input to computation 451 call isusep(hap); ** 452 +* ifaglob(xhap, nam) = $ see if name is global 453 ifaglorname = nam; call ifaglor(xhap); ** 454 +* insglob(glohc, namea) = $ insert name in globals list 455 insgarg = namea; $ ptr to name in ha 456 call insglor(glohc); ** 457 458 459 +* sds(n) = .sds. (n) ** $ size of sds of n characters. 460 461 +* sdsname(sdsnam, hap) = $ converts name indicated by 'hap' 462 $ to sds stored in sdsnam by calling routine sdsnamr 463 call sdsnamr(hap); 464 sdsnam = sdsnamstr; ** 465 466 +* naml(hap) = $ print name of ha item 467 call sdsnamr(hap); 468 textl(sdsnamstr) ** $ sdsnamr puts char string in sdsnamstr 469 470 $ member synmac 471 $ syn run on fri 17 feb 78 10:51:46 472 +* parsearamax = 818 ** 473 +* parselitaramax = 0 ** 474 +* parselexaramax = 0 ** 475 +* parseactmax = 39 ** 476 +* parseerrloc = 814 ** 477 +* parseerrmax = 103 ** 478 $ end member synmac 479 +* ptmax = parsearamax ** 480 481 482 483 +* push(hap) = $ push ptr onto arglist. 484 arglist(argptr) = hap; $ put onto stack. 485 argptr = argptr + 1; $ advance pointer. 486 ** 487 488 +* pop(hap) = $ retrieve hap from arglist. 489 argptr = argptr-1; hap = arglist(argptr); ** 490 491 +* pushint(pcon) = $ push integer on arg stack after 492 $ hashing it into ha and inserting value in val array via 493 call pshintr(pcon); ** 494 495 +* pushname(hc, r) = $ hash name into ha and names array 496 $ push result on arglist 497 call pshnamr(hc, r); ** 498 499 500 501 $ macros pertaining to real quantities 502 +* amode_real = 1 ** 503 +* realopcd(x) = (.f. 2, 1, opkind(x)) ** $ real operation. 504 +* realcomparison(op) = $ is this real comparison. 505 ((op >= rop_gt) & (op <= rop_ne)) ** 506 dst 9 +* arithcomparison(op) = $ is this arithmetic comparison. dst 10 ((op >= op_gt) & (op <= op_le)) ** dst 11 507 $ define headers for message classes. 508 +* error_notice = '*****error**** ' ** 509 +* system_notice = '*system error* ' ** 510 +* warning_notice = '****warning*** ' ** 511 512 mgfc 9 .+s10. $ s10 wants special characters at start of error mgfc 10 $ and warning lines. mgfc 11 +* warn_s10 = charl(37) ** $ per cent for warnings. mgfc 12 +* error_s10 = charl(63) ** $ question mark for errors. mgfc 13 ..s10 ldsa 29 ldsa 30 .+rep. $ initialize rep option codes ldsa 31 ldsa 32 +* rep_typ = 1 ** $ type ldsa 33 +* rep_int = 2 ** $ integer ldsa 34 +* rep_nam = 3 ** $ name ldsa 35 +* rep_end = 4 ** $ end (of report line) ldsa 36 ldsa 37 +* rep_typ_c = 1 ** $ call ldsa 38 +* rep_typ_g = 2 ** $ global variable ldsa 39 +* rep_typ_n = 3 ** $ nameset ldsa 40 +* rep_typ_p = 4 ** $ procedure ldsa 41 ldsa 42 +* rep_typ_max = 4 ** $ number of rep types ldsa 43 ldsa 44 ..rep ldsa 45 1 .=member start dso 25 .+s10 prog start; vax 20 .+s32 prog start; dso 26 .+s37 prog start; utsa 31 .+s47 prog start; dso 27 .+s66 subr start; 4 size proclist(1); $ on to list procedure names and pages. 5 data proclist = no; 6 7 $ define global variables and structures, in alphabetical order. 8 $ it is assumed that this text compiled with 'default access' 9 $ option so that every routine may refer to globals defined in 10 $ this routine. 11 12 $ accesstab has bit -i- set if user is to be granted 13 $ access to nameset at mba(i). 14 size accesstab(nblocks); $ access table, indexed by blocks 15 16 $ argct is number of formal arguments of current routine. 17 size argct(ps); data argct = 0; 18 19 $ a data statement is used in initialization of -littab- below. 20 $ a r g l i s t - parser/generator communication array. 21 $ argmax is the dimension of arglist. as the data values in 22 $ the value list of a data statement and the labels of a goby 23 $ statement are stacked on arglist, argmax thus gives the 24 $ maximum length of these lists. 25 +* argmax = 500 ** $ dims of arglist 26 size argptr(ps); data argptr = 1; $ ptr to arglist 27 size arglist(ps); $ operand push down stack 28 dims arglist(argmax); 29 30 $ the compiler option -ad- sets asmvoadump to request symbol 31 $ table dump at end of every routine compiled. 32 size asmvoadump(ps); data asmvoadump=0; $ on for asm voa write 33 34 $ b u i l t i n f u n c t i o n s. 35 +* numfncts = 21 ** $ total number of library and builtin fncts 36 $ macro to test for built in fnct op 37 +* builtin(op) = ((op >= bop_first)&(op <= bop_last)) ** 38 $ -bifofop(op) maps opcodes for builtin operations into code 39 $ giving position of attributes in -bifatrtab-. 40 +* bifofop(op) = (op-(bop_first-1)) ** 41 +* opofbif(x) = (x +(bop_first-1)) ** $ inverse of -bifofop- 42 43 size bifatrtab(ws); dims bifatrtab(numfncts); $ attribute table 44 data bifatrtab = 0(numfncts); $ filled in by -genini- 45 46 $ fields of -bifatrtab- 47 +* bfmode = .f. 1, 01, ** $ mode of return value 48 +* bfext = .f. 2, 01, ** $ 'function is off-line' 49 +* bfargs = .f. 3, 02, ** $ number of arguments 50 +* bfalias = .f. 5, 10, ** $ -xha- index of function actually 51 $ called (or zero if user name is to be used) 52 53 54 $ flag turned on when searching for possible builtin function 55 $ name in xha using -ifaglob- macro. 56 size bifxhasearch(1); data bifxhasearch = no; 57 58 .+haprobes. 59 $ blkendreset is number of times blkend had to reset deflev fld. 60 size blkendreset(ws); data blkendreset=0; 61 ..haprobes 62 63 $ buildreal is set when -real- declaration seen. 64 size buildreal(1); data buildreal = 0; 65 66 $ constant conversion. 67 $ constants are converted by the routine cnvcon and inserted 68 $ into the ha by the routine inscon. 69 $ cnvcon takes the array of characters in array cca, from 70 $ positions 1 through ccaptr. if the lexical type, as given 71 $ cclt, is that of a 'safe' constant, the constant is converted 72 $ into internal form in array -ccval-, in locations 1 through 73 $ ccvalptr. cnvcon sets -ccsyze- to the correct size. 74 $ if the constant cannot be converted, it is kept in character 75 $ form in ccval. 76 $ string constants should be passed to cnvcon then inscon 77 $ and not to cnvcon directly so that character count 78 $ ccnchars computed by cnvcon will be available to inscon. 79 $ 80 $ inscon locates the ha index of the constant in ccval, building 81 $ a new ha entry if necessary. 82 83 size ccaptr(ps); $ position of last character in cca. 84 size cca(cs); dims cca(toklenmax); 85 size cclt(ps); data cclt=0; $ lexical type of constant 86 size ccnchars(ps); $ character count if string-type token. 87 size ccsyze(ps); $ length of constant in bits 88 size ccvalptr(ps); $ entries used in ccval. 89 size ccval(ws); $ value array for converted constant. 90 dims ccval(toklenmax); 91 92 $ flags to indicate character extractions or assigments. 93 size chasflg(1); data chasflg = no; $ character assignments 94 size chexflg(1); data chexflg = no; $ character extractions 95 dss 20 $ cis_opt is cis option value. if nonzero, then instances dss 21 $ of a(e) where size of e is greater than cis_opt are reported dss 22 $ as warnings. dss 23 size cis_opt(ps); $ cis option value. 96 97 +* crefput(i) = $ write entry to reference file. 98 crbuffptr = crbuffptr + 1; 99 crbuff(crbuffptr) = i; 100 if crbuffptr = crbuffmax then $ write full buffer 101 call wtrwsio(crfile, iorc, crbuff, 1, crbuffptr); 102 crbuffptr = 0; 103 end if; 104 ** 105 +* crbuffmax = 256 ** 106 $ cross-reference variables. 107 nameset gencrf; 108 size crfilename(sds(filenamelen)); $ name of reference file. 109 size crfileparm(sds(filenamelen)); $ skeleton for ref. file name 110 size crbuffptr(ps); data crbuffptr= 0; 111 size crbuff(ws); dims crbuff(crbuffmax); 112 size crossrefoption(1); data crossrefoption = no; 113 end nameset gencrf; 114 115 $ c s a . compound statement array 116 117 $ the csa records the status of open, or pending, compound 118 $ statement groups. its dimension, csamax, gives the maximum 119 $ depth of compound statement nesting. 120 $ the csa fields fall into the following groups. 121 $ flow control - testlbl, endlbl, bodylbl. most of the flow 122 $ constructs may be divided into three parts. a test section 123 $ which computes the loop control expression, a body which 124 $ contains the loop code, and an end label marking the 125 $ start of the first statement after the compount group. 126 $ these fields contain the ha indices of generated labels. 127 $ do group - dovarp, dolop, dohip, dosignp, doincp. 128 $ dovarp is the ha index of the loop variable, dolop(dohip) the 129 $ index of the starting(ending) expression, dosignp is set for 130 $ a descending do(' by -'), and doincp is the ha index of the 131 $ increment expression, or by part. 132 $ gross type - cstype, csiftype. cstype is the type of the 133 $ entry. csiftype is used for if statements only, and gives 134 $ the type of the various member clauses. 135 $ token list - tokorg, toknum. the initial tokens of the 136 $ statement are saved in array csatok. tokorg gives the index 137 $ of the first of the toknum entries. the tokens are checked 138 $ by routine comptok as part of processing for quit, cont, and 139 $ end statements. 140 $ debugging - firstst, ifnum. firstst is the line number, 141 $ relative to the start of the routine, of the start of the 142 $ group. ifnum is the assigned block number used by flow 143 $ trace option. 144 145 +* csamax = 20 ** $ dimension of csa array 146 +* csasz = $ size of csa 147 .+s66 120 vax 21 .+s32 128 148 .+s37 128 utsa 32 .+s47 128 149 .+s10 144 150 ** 151 152 +* csatokmax = csamax*5 ** $ dimension of array for saved opener 153 size csa(csasz); dims csa(csamax); $ compound statement aray 154 size csaptr(ps); data csaptr= 0; $ ptr to csa 155 .+s66. 156 +* bodylbl = .f. 01, 10, ** 157 +* oldmblk = .f. 01, 06, ** 158 +* endlbl = .f. 11, 10, ** 159 +* testlbl = .f. 21, 10, ** 160 +* dovarp = .f. 31, 10, ** 161 +* dolop = .f. 41, 10, ** 162 +* dohip = .f. 51, 10, ** 163 +* dosignp = .f. 61, 01, ** 164 +* doincp = .f. 62, 10, ** 165 +* cstype = .f. 72, 04, ** 166 +* csiftype = .f. 76, 03, ** 167 +* tokorg = .f. 79, 07, ** 168 +* toknum = .f. 86, 03, ** 169 +* firstst = .f. 89, 11, ** 170 +* ifnum = .f. 100, 10, ** 171 ..s66 vax 22 .+s32. vax 23 +* endlbl = .f. 1, 16, ** vax 24 +* testlbl = .f. 17, 16, ** vax 25 +* cstype = .f. 33, 8, ** vax 26 +* tokorg = .f. 41, 8, ** vax 27 +* toknum = .f. 49, 3, ** vax 28 +* dosignp = .f. 52, 1, ** vax 29 +* bodylbl = .f. 55, 10, ** vax 30 +* oldmblk = .f. 57, 8, ** vax 31 +* dovarp = .f. 65, 10, ** vax 32 +* csiftype = .f. 65, 8, ** vax 33 +* dolop = .f. 76, 10, ** vax 34 +* firstst = .f. 86, 11, ** vax 35 +* dohip = .f. 97, 10, ** vax 36 +* ifnum = .f. 108, 11, ** vax 37 +* doincp = .f. 119, 10, ** vax 38 ..s32 172 .+s37. 173 +* endlbl = .f. 1, 16, ** 174 +* testlbl = .f. 17, 16, ** 175 +* cstype = .f. 33, 8, ** 176 +* tokorg = .f. 41, 8, ** 177 +* toknum = .f. 49, 3, ** 178 +* dosignp = .f. 52, 1, ** 179 +* bodylbl = .f. 55, 10, ** 180 +* oldmblk = .f. 57, 8, ** 181 +* dovarp = .f. 65, 10, ** 182 +* csiftype = .f. 65, 8, ** 183 +* dolop = .f. 76, 10, ** 184 +* firstst = .f. 86, 11, ** 185 +* dohip = .f. 97, 10, ** 186 +* ifnum = .f. 108, 11, ** 187 +* doincp = .f. 119, 10, ** 188 ..s37 utsa 33 .+s47. utsa 34 +* endlbl = .f. 1, 16, ** utsa 35 +* testlbl = .f. 17, 16, ** utsa 36 +* cstype = .f. 33, 8, ** utsa 37 +* tokorg = .f. 41, 8, ** utsa 38 +* toknum = .f. 49, 3, ** utsa 39 +* dosignp = .f. 52, 1, ** utsa 40 +* bodylbl = .f. 55, 10, ** utsa 41 +* oldmblk = .f. 57, 8, ** utsa 42 +* dovarp = .f. 65, 10, ** utsa 43 +* csiftype = .f. 65, 8, ** utsa 44 +* dolop = .f. 76, 10, ** utsa 45 +* firstst = .f. 86, 11, ** utsa 46 +* dohip = .f. 97, 10, ** utsa 47 +* ifnum = .f. 108, 11, ** utsa 48 +* doincp = .f. 119, 10, ** utsa 49 ..s47 189 .+s10. 190 +* bodylbl = .f. 1, 18, ** 191 +* oldmblk = .f. 1, 18, ** 192 +* testlbl = .f. 19, 18, ** 193 +* endlbl = .f. 37, 18, ** 194 +* dovarp = .f. 55, 18, ** 195 +* csiftype = .f. 55, 18, ** 196 +* dolop = .f. 73, 10, ** 197 +* dohip = .f. 83, 10, ** 198 +* doincp = .f. 93, 10, ** 199 +* cstype = .f. 103, 4, ** 200 +* dosignp = .f. 107, 1, ** 201 +* firstst = .f. 109, 11, ** 202 +* ifnum = .f. 120, 10, ** 203 +* tokorg = .f. 130, 8, ** 204 +* toknum = .f. 138, 3, ** 205 ..s10 206 207 $ type codes used in cstype field. 208 +* cstypes = 8 ** $ number of compound statement types. 209 +* cstype_subr = 1 ** 210 +* cstype_fnct = 2 ** 211 +* cstype_while = 3 ** 212 +* cstype_until = 4 ** 213 +* cstype_if = 5 ** 214 +* cstype_do = 6 ** 215 +* cstype_prog = 7 ** 216 +* cstype_nameset = 8 ** 217 +* csiftype_else = 3 ** $ special types of if statements 218 +* csiftype_then = 1 ** 219 +* csiftype_sif = 2 ** $ simple if 220 +* csiftype_elseif = 4 ** $ elseif 221 222 +* csacountup(msg) = $ countup csa array 223 countup(csaptr, csamax, 'csa'); $ increment csa top 224 savetoks = 0; ** $ to start saving of tokens. 225 226 $ the tokens following openers and enders are saved in csatok. 227 size csatokptr(ps); data csatokptr=0; $ ptr to csatok 228 size csatok(ws); $ array of opener tokens. 229 dims csatok(csatokmax); 230 231 size curblock(ps); $ ptr to voa for basic block beginning 232 data curblock = 1; 233 234 size currsubrname(namsz); $ current subr name 235 data currsubrname = ' '; 236 237 $ if da (d-efault a-ccess) compiler option on, then each routine 238 $ is to be granted access to all namesets defined 239 $ in the first routine compiled. 240 size daopt(ps); $ on if default access is to be granted ldse 12 size expire(ws); $ days to expiration. 241 242 $ d e b u g f a c i l i t y. 243 244 $ globals relating to debug package. 245 246 $ macros related to debugging package 247 248 +* flowgenlim = 1023 ** $ limit for no. of blocks traced 249 +* assertdim = 25 ** $ dimension of assert stack 250 251 $ values of parm to trentry routine 252 +* entrrout = 1 ** $ entry trace at subr or fnct 253 +* entrend = 2 ** $ trace print for entry at return 254 255 $ calls to debugging generators 256 +* trentry(t) = trentrp = t; call trentrr; ** 257 +* trflow(t) = trflowp = t; call trflowr; ** 258 259 260 $ fields of global variable trflowp which is parameter to 261 $ routine trflowr 262 +* flowp = .f. 1, 3, ** $ type of flow call (while, until, etc) 263 +* flowiftyp = .f. 4, 3, ** 264 +* flowhil = 1 ** $ 'while' statement 265 +* flowtil = 2 ** $ 'until' statement 266 +* flowdo = 3 ** $ 'do' statement 267 +* flowift = 4 ** $ 'if' - true 268 +* flowiff = 5 ** $ 'if' - false 269 +* flowifsf = 3b'15' ** $ 'if' - simple case - false 270 +* flowifnsf = 3b'25' ** $ 'if' ... then ... end - false 271 +* flowifgt = 3b'14' ** $ 'if' ... go to - true 272 +* flowlab = 6 ** $ label 273 +* flowend = 99 ** $ print trace at return 274 275 size assertfg(1); data assertfg = 0; $ assert flag 276 size assertst(ps); dims assertst(assertdim); $ asserstk 277 size assertstp(ps); data assertstp = 0; $ ptr to assert stk 278 size debuglevel(2); data debuglevel = 1; $ debug level 279 $ 0: ignore all debug statements 280 $ 1: process simple assert statements (default) 281 $ 2: process full debug options (set when -help- is specified) 282 283 +* numdebugnames = 16 ** $ number of debug routines 284 +* dbg_prst = 1 ** $ print stores 285 +* dbg_pren = 5 ** $ print entry 286 +* dbg_prex = 6 ** $ print exit 287 +* dbg_prar = 7 ** $ print value of argument 288 +* dbg_prfl = 8 ** $ print flow trace 289 +* dbg_trfl = 9 ** $ trace flow 290 +* dbg_cinx = 10 ** $ check index 291 +* dbg_prhd = 11 ** $ print assert header 292 +* dbg_prvr = 12 ** $ print assert variable 293 +* dbg_asfl = 13 ** $ print assertion failed message in simple c 294 +* dbg_subn = 14 ** $ set subroutine info at entry 295 +* dbg_subx = 15 ** $ inform of subroutine exit 296 +* dbg_setx = 16 ** $ set run-time controls 297 298 size dbgts(sds(4)); $ debug trailer string 299 data dbgts = '$mp'; 300 301 size debugnames(sds(8)); dims debugnames(numdebugnames); 302 data $ initialize to standard four character names 303 $ trailing blanks eliminated when trailer added by -genini-. 304 debugnames(dbg_prst) = 'prs3 ', 'prs4 ', 305 'prs5 ', 'prst ': 306 debugnames(dbg_pren) = 'pren ': 307 debugnames(dbg_prex) = 'prex ': 308 debugnames(dbg_prar) = 'prar ': 309 debugnames(dbg_prfl) = 'prfl ': 310 debugnames(dbg_trfl) = 'trfl ': 311 debugnames(dbg_cinx) = 'cinx ': 312 debugnames(dbg_prhd) = 'prhd ': 313 debugnames(dbg_prvr) = 'prvr ': 314 debugnames(dbg_asfl) = 'asfl ': 315 debugnames(dbg_subn) = 'subn ': 316 debugnames(dbg_subx) = 'subx ': 317 debugnames(dbg_setx) = 'setx '; 318 319 +* testdebug = $ this macro test to see if debugging is ignored 320 if (debuglevel ^= 2) return ** 321 322 size dbgparm(ws), dbgchange(ws); $ for -gendebug- 325 size dbgha(ps); $ used by -gendebug- for ha pointer 326 size trentrp(ps); $ global variable for trentrr 327 size trflowl(ps); $ ptr to ha entry of label 328 size trflowp(ps); $ global for trflowr 329 size trstori(1); $ flag indicating indexing 330 size trstorp(ps); $ global for trsotr 331 size trstors(ps); $ ptr to source of assignemnt 332 size trstor1(ps); $ globals for debug store parametrs 333 size trstor2(ps); 334 size trstor3(ps); 335 size trstor4(ps); 336 size trstor5(ps); 337 +* dbgspcmax = 25 ** $ numbers of vars listed in trace/check 338 $ but not yet sized. 339 size dbgcspc(ps); dims dbgcspc(dbgspcmax); $ 'check' special 340 size dbgcspcf(dbgspcmax); $ 'check' flags 341 size dbgcspcp(ps); $ pointer to -dbgcspc- 342 size dbgtspc(ps); dims dbgtspc(dbgspcmax); $ 'trace' special 343 size dbgtspcf(dbgspcmax); $ 'trace' flags 344 size dbgtspcp(ps); $ pointer to -dbgtspc- 345 size dparm(ps), dval(1); $ parameters to -gendebug-. 346 meal 13 size trentrargs(1); $ trace entry argument list. 347 size trentrfg(1); $ trace entry 348 size trflowfg(1); $ trace flow 349 size trstorfg(1); $ trace stores 350 size chinxfg(1); $ check index 351 data trentrfg = no: trflowfg = no: 352 trstorfg = no: chinxfg = no; 353 354 size trstorsfg(1); $ set if trace/notrace w/o namelist given 355 size chinxsfg(1); $ same but for check/nocheck 356 357 size gtrflowfg(1); $ global flow trace flag 358 size gtrentrfg(1); $ global entry trace flag 359 size gtrstorfg(1); $ global store trace flag 360 size gchinxfg(1); $ global check stores flag 361 data gtrflowfg = no: gtrentrfg = no: 362 gtrstorfg = no: gchinxfg = no; $ flags are off by default 363 size preludefg(1); data preludefg = yes; $ reset by first subr 364 size flowgen(ps); data flowgen = 0; $ flow number generator 365 utsa 50 .+s37. utsa 51 $ ebcascoption is nonzero to translate char strings from utsa 52 $ ebcdic to ascii (used for s47 bootstrap). utsd 1 size ebcascoption(ps); utsa 54 ..s37 366 size endblock(1); data endblock = yes; $ flag to end block 367 $ at subr call 368 369 $ defaccesstab is bitstring with bit i on if nameset i defined 370 $ if first routine, and is used to determine which namesets the 371 $ program can access by deault if 'default access' option on. 372 $ defaccesstab set by gensub. 373 size defaccesstab(nblocks); data defaccesstab = 0; 374 375 size defnstouse(ps); $ 'default' ns to use 376 377 size docontrace(1); data docontrace=no; $ on to trace constants 378 379 $ variables for reusing -do- variables 380 +* dovarmax = 32 ** $ maximum number to be used (for nested -do- 381 size dovars(ps); dims dovars(dovarmax); $ -ha- pointers 382 size dovarsz(ps); dims dovarsz(dovarmax); $ sizes 383 size dovarptr(ps); data dovarptr = 0; $ no. used 384 size dovarbusy(dovarmax); $ busy flags (set when var in use) 385 data dovarbusy = 0; $ initially, all are free 386 $ cardlisted is on after listing current input card. 387 size cardlisted(ps); data cardlisted = yes; 388 389 .+haprobes. 390 size emassreset(ps); data emassreset = 0; 391 ..haprobes 392 393 $ ermesarg is used to pass extra information to ermes, 394 $ usually ha index of item. 395 size ermesarg(ps); 396 397 $ ermflag is on to note calls to unsized external functions. 398 size ermflag(1); data ermflag = yes; 399 400 size ermsgno(ps); $ number of error message 401 402 $ erthis is number of errors detected including current 403 $ routine. erprev is number of detected errors through 404 $ end of previous routine. 405 size erthis(ps); data erthis = 0; 406 size erprev(ps); data erprev = 0; 407 408 size exitcode(ps); $ exit code from -gen- 409 data exitcode = 1; $ default is bad exit (occurs more often) 410 411 size fswitch(1); $ function flag 412 data fswitch = 0; 413 414 415 416 size gsopt(1); $ on to define globals in start 417 418 $ h a . hashed array. 419 420 $ all symbols 421 $ names, constants and expressions are entered in the ha, and 422 $ the ha index is main way item is referenced. the arglist 423 $ consists largely of ha indices. 424 425 $ the fields of the ha are as follows. 426 $ ep. the index of voa for this item. 427 $ var. 'is this a variable (ie. not operation) entry'. 428 $ hainuse. 'is this entry in use' 429 $ nayme. index in names array if variable name. 430 $ nchars. number of characters in name or constant. 431 $ labno. (for names only) lablist index if used as label. 432 $ namintern. 'is this a compiler generated name' 433 $ hascon. (for constants only) 'is this safe (short) constant'. 434 $ zerents. number of preceding empty ha entries (used to 435 $ pack ha when writing voa file). 436 $ varluse. last use in block of variable. (-voa- pointer) 437 $ tracef. 'is store trace in effect.' 438 $ chinxf. 'is check index option in effect.' 439 440 +* hasz = $ size of ha in bits 441 .+s66 60 vax 39 .+s32 64 442 .+s37 64 utsa 55 .+s47 64 443 .+s10 72 444 ** dsx 23 +* hamax = 937 ** $ ha dims - must be a prime 446 .+s66 nameset blank; $ keep in blank common on s66. 447 size ha(hasz); dims ha(hamax); 448 .+s66 end nameset; 449 450 .+s66. 451 +* ep = .f. 01, 12, ** 452 +* hascon = .f. 13, 01, ** 453 +* var = .f. 14, 01, ** 454 +* hainuse = .f. 15, 01, ** 455 +* nayme = .f. 16, 13, ** 456 +* labno = .f. 29, 10, ** 457 +* tracef = .f. 39, 01, ** 458 +* chinxf = .f. 40, 01, ** 459 +* namintern = .f. 41, 01, ** 460 +* zerents = .f. 42, 11, ** 461 +* varluse = .f. 42, 11, ** $ overlays -zerents- 462 +* nchars = .f. 53, 08, ** 463 ..s66 vax 40 .+s32. vax 41 +* hascon = .f. 1, 1, ** vax 42 +* var = .f. 2, 1, ** vax 43 +* tracef = .f. 3, 1, ** vax 44 +* chinxf = .f. 4, 1, ** vax 45 +* ep = .f. 5, 11, ** vax 46 +* namintern = .f. 16, 1, ** vax 47 +* zerents = .f. 17, 16, ** vax 48 +* varluse = .f. 17, 16, ** vax 49 +* nchars = .f. 33, 8, ** vax 50 +* labno = .f. 41, 9, ** vax 51 +* hainuse = .f. 50, 1, ** vax 52 +* nayme = .f. 54, 11, ** vax 53 ..s32 464 .+s37. 465 +* hascon = .f. 1, 1, ** 466 +* var = .f. 2, 1, ** 467 +* tracef = .f. 3, 1, ** 468 +* chinxf = .f. 4, 1, ** 469 +* ep = .f. 5, 11, ** 470 +* namintern = .f. 16, 1, ** 471 +* zerents = .f. 17, 16, ** 472 +* varluse = .f. 17, 16, ** 473 +* nchars = .f. 33, 8, ** 474 +* labno = .f. 41, 9, ** 475 +* hainuse = .f. 50, 1, ** 476 +* nayme = .f. 54, 11, ** 477 ..s37 utsa 56 .+s47. utsa 57 +* hascon = .f. 1, 1, ** utsa 58 +* var = .f. 2, 1, ** utsa 59 +* tracef = .f. 3, 1, ** utsa 60 +* chinxf = .f. 4, 1, ** utsa 61 +* ep = .f. 5, 11, ** utsa 62 +* namintern = .f. 16, 1, ** utsa 63 +* zerents = .f. 17, 16, ** utsa 64 +* varluse = .f. 17, 16, ** utsa 65 +* nchars = .f. 33, 8, ** utsa 66 +* labno = .f. 41, 9, ** utsa 67 +* hainuse = .f. 50, 1, ** utsa 68 +* nayme = .f. 54, 11, ** utsa 69 ..s47 478 .+s10. 479 +* ep = .f. 1, 18, ** 480 +* zerents = .f. 19, 18, ** 481 +* varluse = .f. 19, 18, ** 482 +* nayme = .f. 37, 11, ** 483 +* labno = .f. 48, 9, ** 484 +* nchars = .f. 57, 8, ** 485 +* hascon = .f. 65, 1, ** 486 +* var = .f. 66, 1, ** 487 +* tracef = .f. 67, 1, ** 488 +* chinxf = .f. 68, 1, ** 489 +* namintern = .f. 69, 1, ** 490 +* hainuse = .f. 70, 1, ** 491 ..s10 492 493 $ the following macros are to be used for all ha searches 494 $ they correspond to 'while' over ha. ha search begins with 495 $ macro call of form 496 $ haprobe(j, hcode) , 497 $ where j is variable used to index ha, hcode is hashcode, and 498 $ user must size j, hcode. 499 $ within search-body, write 'haquit', 'hacont', and 'haend' for 500 $ actions similar to 'quit' cont and 'end' in while statements. 501 $ if ha is full, execution will be terminated. 502 503 504 +* haprobe(j, hcode) = $ ha search macro 505 hcode = mod(hcode, hamax) + 1; $ get initial hash code. 506 if (hcode = hamax) hcode = (hamax-2); 507 size zzzp(ps); $ probes this search. 508 zzzp = 0; j = 1; 509 .+haprobes tothaprobes = tothaprobes + 1; $ update probe count if st 510 macdef(haprlbl = zzza) 511 macdef(haquitlbl = zzzc) macdef(haendlbl = zzzd) 512 macdef(hafulllbl = zzze) 513 /haprlbl/ if (zzzp > hamax) go to hafulllbl; $ ha is full 514 zzzp = zzzp + 1; 515 .+haprobes tothaexam = tothaexam + 1; $ update count if ha stats on 516 j = j + hcode; $ add original hashcode for next probe loc 517 if j > hamax then j = j-hamax; end if; 518 ** 519 520 +* hacont = go to haprlbl;**$ continue ha search 521 +* haquit = go to haquitlbl; ** $ quit ha search 522 +* haend = go to haprlbl; $ continue ha probe 523 /hafulllbl/ call ermes(52); call genexit; 524 /haquitlbl/ 525 macdrop(haprlbl) macdrop(haquitlbl) 526 macdrop(haendlbl) macdrop(hafulllbl) 527 ** 528 529 size ha_0(ps); $ ha index of constant '0' (set by gensub) 530 size ha_1(ps); $ ha index of constant '1' (set by gensub) 531 size ifaglorname(ps); $ global arg to ifaglor haptr to name 532 size iorc(ps); $ io return code. 533 534 535 .+ifconstat. 536 $ ifcontot gives number of if's with constant control 537 $ expression; ifcongoto is number chaaged to a go to. 538 size ifcontot(ws); data ifcontot=0; 539 size ifcongotos(ws); data ifcongotos=0; 540 ..ifconstat 541 542 $ the next few variables are primarily used as part of macro 543 $ expansion to pass macro parameters to routines. 544 size insnchars(ps); $ arg to insnamr - nchars 545 size insgarg(ps); $ global to hasher (globals) ptr to ha 546 size insnarg(ws); $ array holding name to be added 547 dims insnarg(namsz/ws); $ packed array of token characters 548 549 $ i n p u t / o u t p u t s u p p o r t. 550 551 +* iotamax = 40 ** $ dims of iota 552 553 size iowriting(1); $ 'is this put statement' 554 size ioformatted(1); $ set for formatted io 555 size iolistmode(1); $ on for list mode. 556 557 $ items to be transmitted, either expressions, variables or arra 558 $ are noted in the iota (io t-ransmission a-rray). the fields 559 $ -iotavar-, -iotalo- and -iotahi- give the ha indices of the 560 $ item, the first element of array slice and last element of 561 $ array slice (lo and hi 0 if not array slice). 562 563 size iota(ws); dims iota(iotamax); 564 size iotaptr(ps); data iotaptr=0; $ top of iota 565 size iovar(ps); $ ha index of item to transmit 566 size iolo(ps); $ ha index of array subscript or start of slice 567 size iohi(ps); $ ha index of end of array slice 568 569 $ the status of local variables needed for io is maintained in 570 $ the iova (io v-ariable a-rray) with top -iovaptr- adnd limit 571 $ -iovamax-. the field -iovaha- gives ha index of variable, 572 $ -iovasize- gives its size in bits. the i-th bit of -iovabusy- 573 $ is set if the i-th variable in iova is currently in use. 574 $ the busy bits are cleared when variable no longer needed 575 $ to permit reuse within io statement, and at start of io statem 576 $ ment since variables only needed in single statement. 577 578 +* ioformats = 6 ** $ number of data formats. 579 580 581 582 583 +* ionamesptr = 19 ** $ number of io routines to which calls ge 584 +* ior_onma = 1 ** $ -n- array element name 585 +* ior_onmv = 2 ** $ -n- simple name list 586 +* ior_gcfp = 3 ** $ control format processor 587 +* ior_ifma = 4 ** $ -a- input format 588 +* ior_ifmb = 5 ** $ -b- input format 589 +* ior_ifme = 6 ** $ -e- input format 590 +* ior_ifmf = 7 ** $ -f- input format 591 +* ior_ifmi = 8 ** $ -i- input format 592 +* ior_ifmr = 9 ** $ -r- input format 593 +* ior_rwnd = 10 ** $ file rewind 594 +* ior_ioqu = 11 ** $ io query 595 +* ior_vali = 12 ** $ validator. 596 +* ior_makf = 13 ** $ make system tables for file 597 +* ior_ofma = 14 ** $ -a- output format 598 +* ior_ofmb = 15 ** $ -b- output format 599 +* ior_ofme = 16 ** $ -e- output format 600 +* ior_ofmf = 17 ** $ -f- output format 601 +* ior_ofmi = 18 ** $ -i- output format 602 +* ior_ofmr = 19 ** $ -r- output format 603 604 605 606 $ fields of iota (io t-ransmission a-rray) 607 +* iotavar = .e. 01, 10, ** $ ha index of item to transmit 608 +* iotalo = .e. 11, 10, ** $ ha index of first array element 609 +* iotahi = .e. 21, 10, ** $ ha index of last array elementn 610 611 $ iova (io v-ariable a-rray) fields 612 +* iovaha = .e. 1, 10, ** $ ha index of variable 613 +* iovasize = .e. 11, 11, ** $ size of variable 614 615 +* iovasz = 20 ** $ size of iova 616 +* iovamax = 40 ** $ maximum number of entries in iova 617 618 size iovaptr(ps); data iovaptr=0; $ top of iova 619 size iova(iovasz); dims iova(iovamax); 620 size iovabusy(iovamax); data iovabusy = 0; 621 622 size iofilename(ps); data iofilename = 0; $ ha index of filename 623 size iokey(ps); $ io token key word. passed from 624 $ parser to generators 625 size ioerror(1); data ioerror = no; $ error flag 626 size ionameflag(1); data ionameflag = no; $ namelist flag 627 size iofilekeys(ps); dims iofilekeys(4); $ args for file definiti 628 $ the i/o functions are supported by various routines in the 629 $ little run-time library. to avoid name conflicts between 630 $ these routines and user routines, the compiler supports an 631 $ option to 'protect' i/o names. 632 633 $ within the source, io routines are reffered to by macros. 634 $ these macros expand to indices into the array -ionames- below. 635 $ the routine names are initially given as four characters. 636 $ these routines are protected by appending a trailer string 637 $ as part of the compiler isolation, the trailer will typically 638 $ contain a character acceptable to the loader but not 639 $ usually found in subprogram names (for example, '$'). 640 641 $ the default trailer is an implementation option, but 642 643 644 $ the trailer can be at most 4 characters 645 646 size iorts(sds(4)); $ io routine trailer string 647 data iorts = '$io'; 648 649 size ionames(sds(8)); dims ionames(ionamesptr); 650 data $ initialize to standard four character names 651 $ trailing blanks eliminated by genini. 652 ionames(ior_onma) = 'onma ': $ -n- array element name 653 ionames(ior_onmv) = 'onmv ': $ -n- simple name list 654 ionames(ior_gcfp) = 'gcfp ': $ control format processor 655 ionames(ior_ifma) = 'ifma ': $ -a- input format 656 ionames(ior_ifmb) = 'ifmb ': $ -b- input format 657 ionames(ior_ifme) = 'ifme ': $ -e- input format 658 ionames(ior_ifmf) = 'ifmf ': $ -f- input format 659 ionames(ior_ifmi) = 'ifmi ': $ -i- input format 660 ionames(ior_ifmr) = 'ifmr ': $ -r- input format 661 ionames(ior_rwnd) = 'rwnd ': $ file rewind 662 ionames(ior_ioqu) = 'ioqu ': $ io query 663 ionames(ior_vali) = 'vali ': $ validator. 664 ionames(ior_makf) = 'makf ': $ make system tables for file 665 ionames(ior_ofma) = 'ofma ': $ -a- output format 666 ionames(ior_ofmb) = 'ofmb ': $ -b- output format 667 ionames(ior_ofme) = 'ofme ': $ -e- output format 668 ionames(ior_ofmf) = 'ofmf ': $ -f- output format 669 ionames(ior_ofmi) = 'ofmi ': $ -i- output format 670 ionames(ior_ofmr) = 'ofmr '; $ -r- output format 671 672 $ array iodfprocs maps codes for data formats onto codes use 673 $ for formatted conversion routines. the first -ioformats- 674 $ are for input, the rest for output. 675 size iodfprocs(ps); dims iodfprocs(2*ioformats); 676 data iodfprocs = 677 ior_ifma, ior_ifmb, ior_ifme, ior_ifme, 678 ior_ifmi, ior_ifmr, ior_ofma, ior_ofmb, 679 ior_ofme, ior_ofmf, ior_ofmi, ior_ofmr; 680 681 $ several of the parameters needed for formatted io are 682 $ packed into various fields of the io parameter string; 683 $ data structures and procedures related to this packing have 684 $ names beginning with -iops-. 685 $ iopssz is the size of the string. the array iopsha is a list 686 $ of the ha indexes of the parameters to be entered. 687 $ parameters are assumed to be zero unless otherwise specified, 688 $ so iopsha entries are set to ha_0 initially. 689 $ the arrays iopsorg and iopslen give the origins and lengths of 690 $ the fields. macros beginning with 'iopsi_' give integer 691 $ codes for the fields. 692 $ the procedure -geniops- constructs the parameter string 693 $ and sets the global variable -iopshap- to the ha index; 694 $ if all the fields are constants, the string will be a constant 695 $ otherwise, the string is built by entering all constant fields 696 $ at compile time and generating code to enter nonconstant 697 $ field values at runtime. 698 +* iopsflds = 7 ** $ number of fields in iops. 699 +* iopssz = 32 ** $ size of iops. 700 size iopshap(ps); $ ha index of io parm. str. 701 size iopsha(ps); dims iopsha(iopsflds); $ ha indices of parms. 702 size iopsorg(ps); dims iopsorg(iopsflds); 703 size iopslen(ps); dims iopslen(iopsflds); 704 +* iopsi_lm = 1 ** $ on if list mode. 705 +* iopsi_fw = 2 ** $ field width. 706 +* iopsi_dw = 3 ** $ decimal width (also byte width). 707 +* iopsi_sz = 4 ** $ size of datum. 708 +* iopsi_gw = 5 ** $ group width. 709 data $ set field origins of iops fields. 710 iopsorg(iopsi_lm) = 01: iopslen(iopsi_lm) = 01: 711 iopsorg(iopsi_fw) = 02: iopslen(iopsi_fw) = 08: 712 iopsorg(iopsi_dw) = 10: iopslen(iopsi_dw) = 05: 713 iopsorg(iopsi_sz) = 17: iopslen(iopsi_sz) = 11: 714 iopsorg(iopsi_gw) = 28: iopslen(iopsi_gw) = 04; 715 $ bit iopssz is reserved for use when machine word size 716 $ is less than iopssz (see procedure geniops). 717 718 size isusenot(1); data isusenot = no; $ flag for -isuse- macro. 719 size keeptok(1); data keeptok=no; $ on to retrieve last token. 720 721 $ l a b e l p r o c e s s i n g. 722 723 724 +* lablistlen = $ dimension of label list 725 400 726 ** 727 728 +* labsz = ws ** $ size of lablist entry 729 size labgen(sds(4)); data labgen = 'l.aa'; $ local label name 730 .+s66 nameset blank; $ keep in blank common on s66. 731 size lablist(labsz); dims lablist(lablistlen); $ label table 732 .+s66 end nameset; 733 size lablistptr(ps); data lablistptr = 0; $ ptr to lablist 734 $ the lablist fields are as follows. 735 $ labha is the ha index of the entry for label. 736 $ labvoa is the voa index of the item for label definition. 737 738 .+s66. 739 +* labha = .f. 01, 10, ** 740 +* labvoa = .f. 11, 11, ** 741 ..s66 vax 54 .+s32. vax 55 +* labha = .f. 1, 16, ** vax 56 +* labvoa = .f. 17, 16, ** vax 57 ..s32 742 .+s37. 743 +* labha = .f. 1, 16, ** 744 +* labvoa = .f. 17, 16, ** 745 ..s37 utsa 70 .+s47. utsa 71 +* labha = .f. 1, 16, ** utsa 72 +* labvoa = .f. 17, 16, ** utsa 73 ..s47 746 .+s10. 747 +* labha = .f. 1, 18, ** 748 +* labvoa = .f. 19, 18, ** 749 ..s10 750 751 $ macros relating to the handling of labels 752 753 $ define label by entering voaptr in lablist 754 +* labldef(v, labnum) = 755 if labvoa lablist(labnum) then $ if already defined, 756 if (namintern ha(labha lablist(labnum)) = no) 757 call ermes(14); $ duplicate label. 758 else 759 labvoa lablist(labnum) = v; end if; 760 ** 761 762 $ increment number of uses of label 763 +* labluse(labnum) = 764 labuses lablist(labnum) = labuses lablist(labnum) + 1; ** 765 766 +* labget(labl) = $ returns ha ptr to label 767 call advstr(labgen, labl); $ advance local label name ,hash 768 ** 769 770 +* labdef(labl) = $ define label 771 push(labl) call gengol(op_lab); ** 772 773 $ lcp_opt on to list compilation parameters. 774 $ lcs_opt on to list compilation statistics. 775 size lcp_opt(ps); data lcp_opt = yes; 776 size lcs_opt(ps); data lcs_opt = yes; 777 778 $ levnow and levmin are used to detect redundant calculations. 779 $ levnow is incremented for each basic block, and minlev is set 780 $ to the value of levnow at this point, so an operation has 781 $ been performed in the current block only if its definition 782 $ level is not less than levmin. levnow is also incremented for 783 $ each assignment and the deflev field of the assignment target 784 $ is set to the new value. 785 $ an operation is redundant if both the computation itself and 786 $ the computation of any inputs which are not variables have 787 $ been performed in the current block and if no input has been 788 $ assigned a new value since the prior computation. 789 $ the search for redundant computations is performed in routines 790 $ emit1, emit2 and emit3. 791 size levnow(ps); data levnow = 1; $ level number 792 size levmin(ps); data levmin=1; $ minimum level - optimization 793 794 $ t o k e n a n d l i t e r a l p r o c e s s i n g. 795 796 $ as a diagnostic aid, a list of the most recent tokens 797 $ is maintained in lexlist with dimension -lexlistmax-. 798 $ lexlist holds list of recent tokens seen, for diagnostics 799 +* lexlistmax = $ number of words listed in 'last few tokens' 800 .+s66 16 vax 58 .+s32 16*2 $ two words/token 801 .+s37 16*2 $ two words/token utsa 74 .+s47 16*2 $ two words/token dso 28 .+s10 16*2 $ two words/token 803 ** 804 805 $ -lexlistmax- must be a power of two. 806 +* lexlistsz = ws ** $ size of lexlist entry. 807 size lexlist(lexlistsz); dims lexlist(lexlistmax); 808 size lexleng(lexlistsz); dims lexleng(lexlistmax); 809 data lexlist = 0(lexlistmax); 810 size lexlistptr(ps); data lexlistptr = 0; 811 812 size listingcode(1); $ assembler code list option value. 813 data listingcode = no; $ by default, do not list code. 814 size subtitling(1); $ set when entering subtitles. 815 data subtitling = no; 816 size listsw(1); $ flag for listing input 817 data listsw = no; $ by default, list off. 818 $ listswnew holds new listsw value until next line read. 819 $ the initial value must be same as that for listsw. 820 size listswnew(1); data listswnew = no; 821 size listauto(1); data listauto = no; $ auto-titleing flag 822 size listwds(ws); dims listwds(wpc); $ card read in 823 size listwdsp(ps); $ last non-blank word 824 825 size toklc(ps); $ token literal code 826 827 +* litclassz = $ size of littab internal entry. 828 .+s66 6 vax 59 .+s32 8 829 .+s37 8 utsa 75 .+s47 8 830 .+s10 6 831 ** 832 833 +* littabl(class, indx) = $ computeentry in littab for given 834 $ literal and class 835 .f. (littabsz+1) - litclassz*(class), litclassz, littab(indx) 836 ** 837 838 +* littabsz = $ size of littab (at least 60 bits) 839 .+s66 60 vax 60 .+s32 128 840 .+s37 128 utsa 76 .+s47 128 841 .+s10 72 842 ** 843 845 size littab(littabsz); dims littab(litcodes); $ leteral class 846 data littab = 0(litcodes); $ see ltabini for initialization code. 847 848 $ to save space, we initialize the literals table as follows. 849 $ abstractly, -littab- is a two dimensional table, littab(cl,lc) 850 $ indexed by -cl-, a class number, and -lc- a literal code. 851 $ for example, the set of binary operator names is one such 852 $ class, and the littab entry for binary operators contains 853 $ the precedence of the operator (0 if not binary op). 854 $ the table is a set of triples . 855 $ the macros below are used to enter values in arglist as initia 856 $ data and deflit is called to build littab. 857 $ this roundabout procedure saves code space which formerly 858 $ by using execution time field extracts to set up each entry. 859 860 data arglist = 861 +* ins(lc,value ) = 862 lc + value*4b'100', ** 863 864 1*4b'100', 865 ins(lc_if, 1) 866 ins(lc_while, 2) 867 ins(lc_until , 3) 868 ins(lc_do, 4) 869 ins(lc_end, 5) 870 ins(lc_else, 6) 871 ins(lc_size, 7) 872 ins(lc_dims, 8) 873 ins(lc_data, 9) 874 ins(lc_semicolon,10) 875 ins(lc_nameset, 11) 876 ins(lc_access, 12) 877 ins(lc_real,13) 878 ins(lc_elseif, 14) 879 ins(lc_subr, 15) 880 ins(lc_fnct, 16) 881 ins(lc_divide, 17) 882 ins(lc_prog, 18) 883 884 $ branch on literals - simple statements 885 2*4b'100', 886 ins(lc_call, 1) 887 ins(lc_goby, 2) 888 ins(lc_return, 3) 889 ins(lc_go, 4) 890 ins(lc_cont, 5) 891 ins(lc_quit, 6) 892 ins(lc_fext, 7) 893 ins(lc_eext, 8) 894 ins(lc_sext, 9) 895 ins(lc_chext, 10) 896 ins(lc_get, 11) 897 ins(lc_put, 12) 898 ins(lc_file, 13) 899 ins(lc_rewind, 14) 900 ins(lc_len, 15) 901 ins(lc_read, 16) 902 ins(lc_write, 17) 903 ins(lc_check, 18) 904 ins(lc_nocheck, 19) 905 ins(lc_trace, 20) 906 ins(lc_notrace, 21) 907 ins(lc_assert, 22) 908 ins(lc_monitor, 23) 909 910 $ binary operators - operator precedence level nubers 911 3*4b'100', 912 ins(lc_pad, 1) 913 ins(lc_ccat, 1) 914 ins(lc_or, 1) 915 ins(lc_ex, 1) 916 ins(lc_exor, 1) 917 ins(lc_orsym, 1) 918 ins(lc_and, 2) 919 ins(lc_andsym, 2) 920 ins(lc_andbrev, 2) 921 ins(lc_eq, 4) 922 ins(lc_ne, 4) 923 ins(lc_gt, 4) 924 ins(lc_lt, 4) 925 ins(lc_ge, 4) 926 ins(lc_le, 4) 927 ins(lc_eqsym, 4) 928 ins(lc_ltsym, 4) 929 ins(lc_gtsym, 4) 930 ins(lc_notsym, 4) 931 ins(lc_seq, 4) $ .seq. 932 ins(lc_sne, 4) $ .sne. 933 ins(lc_plus, 5) 934 ins(lc_minus, 5) 935 ins(lc_times, 6) 936 ins(lc_divide, 6) 937 ins(lc_in, 6) 938 939 $ unary operators - operator prec level numbers 940 4*4b'100', 941 ins(lc_not, 3) 942 ins(lc_notbrev, 3) 943 ins(lc_notsym, 3) 944 ins(lc_fb, 7) 945 ins(lc_nb, 7) 946 ins(lc_minus, 7) 947 ins(lc_sdsop, 7) 948 ins(lc_len, 7) 949 ins(lc_plus, 7) $ unary plus. 950 951 $ binary operators - arith routine parameter number - opcode 952 5*4b'100', 953 ins(lc_ccat, op_ccat) 954 ins(lc_in, op_in) 955 ins(lc_plus, op_add) 956 ins(lc_minus, op_sub) 957 ins(lc_gt, op_gt) 958 ins(lc_gtsym, op_gt) 959 ins(lc_lt, op_lt) 960 ins(lc_ltsym, op_lt) 961 ins(lc_ge, op_ge) 962 ins(lc_le, op_le) 963 ins(lc_eq, op_eq) 964 ins(lc_eqsym, op_eq) 965 ins(lc_ne, op_ne) 966 ins(lc_notsym, op_ne) 967 ins(lc_times, op_mul) 968 ins(lc_divide, op_div) 969 ins(lc_or, op_or) 970 ins(lc_orsym, op_or) 971 ins(lc_and, op_and) 972 ins(lc_andbrev, op_and) 973 ins(lc_andsym, op_and) 974 ins(lc_exor, op_exor) 975 ins(lc_ex, op_exor) 976 ins(lc_seq, op_seq) 977 ins(lc_pad, op_pad) 978 ins(lc_sne, op_sne) 979 980 $ unary operators - marith routine parameter number - opcode 981 6*4b'100', 982 ins(lc_fb, op_fb) 983 ins(lc_nb, op_nb) 984 ins(lc_not, op_not) 985 ins(lc_notsym, op_not) 986 ins(lc_notbrev, op_not) 987 ins(lc_minus, op_usub) 988 ins(lc_sdsop, 0) $ .sds. 989 ins(lc_len, 1) $ .len. 990 ins(lc_plus, 2) 991 992 $ branch on literals - right hand terms 993 7*4b'100', 994 $ assigned code is offset to which to branch forward in 995 $ parse of terms. 996 ins(lc_fext, 5) 997 ins(lc_eext, 6) 998 ins(lc_sext, 7) 999 ins(lc_chext, 8) 1000 ins(lc_lparen, 9) 1001 ins(lc_filestat, 10) 1002 1003 $ codes for special tokens examined by nextok. 1004 9*4b'100', 1005 ins(lc_voadump , 1) 1006 ins(lc_voapart , 2) 1007 ins(lc_contr , 5) 1008 ins(lc_nocontr , 6) 1009 ins(lc_toktr , 7) 1010 ins(lc_notoktr , 8) 1011 ins(lc_mws , 9) 1012 ins(lc_mps , 10) 1013 ins(lc_mcs , 11) 1014 ins(lc_msl , 12) 1015 ins(lc_mso , 13) 1016 1017 0, 0; $ end of data statement for ha (0 flags end of list) 1018 +* ins = ** $ drop ins macro. 1019 1020 1021 1022 $ a record is kept of the maximum use of each static array and 1023 $ the routine compiled which made maximum use. 1024 +* loadini(var,varsds) = $ initialize load statistics variable. 1025 size var(ws); data var = 0; 1026 size varsds(namsz); data varsds = ' '; 1027 ** 1028 loadini(loadha , loadrha ); $ ha. 1029 loadini(loadlablist , loadrlablist ); $ lablist. 1030 loadini(loadnames , loadrnames ); $ names. 1031 loadini(loadtlist , loadrtlist ); $ tlist. 1032 loadini(loadval , loadrval ); $ val 1033 loadini(loadvoa , loadrvoa ); $ voa. 1034 loadini(loadxarg , loadrxarg ); $ xarg. 1035 macdrop(loadini) 1036 1037 size localforce(1); data localforce=no; $ on to force use 1038 $ of local block by gensiz (set by gendo) 1039 1040 size lvgen(sds(4)); data lvgen = 'v.aa'; $ local variable name 1041 1042 $ mainprogram is set when compiling program. 1043 size mainprogram(1); data mainprogram = no; 1044 $ m b a . machine block array 1045 size mbaptr(ps); data mbaptr=0; $ most recent entry in mba 1046 1047 +* mbasz = $ size of mba (m-achine b-lock a-rray) 1048 .+s66 60 dsw 17 .+s32 96 dsw 18 .+s37 96 utsa 77 .+s47 96 1050 .+s10 72 1051 ** 1052 1053 size mba(mbasz); dims mba(nblocks); $ m-achine b-lock a-rray 1054 data mba = 0(nblocks); 1055 1056 .+s66. 1057 +* mblen = .f. 1, 20, ** 1058 +* mbha = .f. 21, 11, ** 1059 +* mbused = .f. 32, 1, ** 1060 +* mbxha = .f. 33, 12, ** 1061 +* mbdef = .f. 46, 1, ** 1062 +* mbchain = .f. 47, 11, ** 1063 ..s66 vax 62 .+s32. vax 63 +* mbused = .f. 1, 1, ** vax 64 +* mbdef = .f. 2, 1, ** vax 65 +* mbha = .f. 4, 11, ** dsw 19 +* mblen = .f. 65, 32, ** vax 67 +* mbxha = .f. 33, 13, ** vax 68 +* mbchain = .f. 46, 11, ** vax 69 ..s32 1064 .+s37. 1065 +* mbused = .f. 1, 1, ** 1066 +* mbdef = .f. 2, 1, ** 1067 +* mbha = .f. 4, 11, ** dsw 20 +* mblen = .f. 65, 32, ** 1069 +* mbxha = .f. 33, 13, ** 1070 +* mbchain = .f. 46, 11, ** 1071 ..s37 utsa 78 .+s47. utsa 79 +* mbused = .f. 1, 1, ** utsa 80 +* mbdef = .f. 2, 1, ** utsa 81 +* mbha = .f. 4, 11, ** utsa 82 +* mblen = .f. 65, 32, ** utsa 83 +* mbxha = .f. 33, 13, ** utsa 84 +* mbchain = .f. 46, 11, ** utsa 85 ..s47 1072 .+s10. 1073 +* mblen = .f. 1, 18, ** 1074 +* mbxha = .f. 19, 18, ** 1075 +* mbha = .f. 37, 18, ** dst 12 +* mbchain = .f. 55, 11, ** dst 13 +* mbused = .f. 66, 1, ** dst 14 +* mbdef = .f. 67, 1, ** 1079 ..s10 1080 1081 $ characters in symbolic names are kept in -names- array. 1082 +* namesmax = $ dimension of -names- array 1083 .+s66 600 vax 70 .+s32 800 1084 .+s37 800 utsa 86 .+s47 800 mgfb 13 .+s10 800 1086 ** 1087 1088 size namesptr(ps); data namesptr = 1; $ ptr to names array 1089 .+s66 nameset blank; $ keep in blank common on s66. 1090 size names(ws); dims names(namesmax); $ names array 1091 .+s66 end nameset; 1092 1093 size ncards(ps); data ncards = 0; $ number of cards read. 1094 1095 size ncfopt(1); data ncfopt=1; $ on if negative constant fold ok 1096 .+ncfstat. 1097 size ncftot(ps); data ncftot=0;$ no. of negative constants fold 1098 ..ncfstat 1099 1100 size nerrors(ps); data nerrors = 0; $ no of errors 1101 size nwarnings(ps); data nwarnings=0; $ num. of warnings. 1102 1103 $ n l - names list (attributes of global variables) 1104 1105 +* nlmax = $ dimension of -nl- array 1106 400 1107 ** 1108 1109 size nlptr(ps); data nlptr = 0; $ top of nl 1110 $ fields related to global names list - n l 1111 +* nlsz = $ size of nl 1112 .+s66 120 dsw 21 .+s32 96 dsw 22 .+s37 96 utsa 87 .+s47 96 1114 .+s10 72 1115 ** 1116 1117 .+s66 nameset blank; $ keep in blank common on s66. 1118 size nl(nlsz); dims nl(nlmax); 1119 .+s66 end nameset; 1120 1122 1123 .+s66. 1124 +* nldimn = .f. 1, 16, ** 1125 +* nlmadr = .f. 17, 16, ** 1126 +* nlha = .f. 33, 10, ** 1127 +* nlamode = .f. 43, 1, ** 1128 +* nlchinx = .f. 44, 1, ** 1129 +* nlsize = .f. 45, 11, ** 1130 +* nltrac = .f. 56, 1, ** 1131 +* nlfnct = .f. 57, 1, ** 1132 +* nlblk = .f. 61, 6, ** 1133 ..s66 vax 72 .+s32. dsw 23 +* nldimn = .f. 1, 32, ** dsw 24 +* nlmadr = .f. 65, 32, ** vax 75 +* nlsize = .f. 33, 11, ** vax 76 +* nlblk = .f. 44, 6, ** vax 77 +* nlamode = .f. 50, 1, ** vax 78 +* nlchinx = .f. 51, 1, ** vax 79 +* nltrac = .f. 52, 1, ** vax 80 +* nlfnct = .f. 53, 1, ** vax 81 +* nlha = .f. 55, 10, ** vax 82 ..s32 1134 .+s37. dsw 25 +* nldimn = .f. 1, 32, ** dsw 26 +* nlmadr = .f. 65, 32, ** 1137 +* nlsize = .f. 33, 11, ** 1138 +* nlblk = .f. 44, 6, ** 1139 +* nlamode = .f. 50, 1, ** 1140 +* nlchinx = .f. 51, 1, ** 1141 +* nltrac = .f. 52, 1, ** 1142 +* nlfnct = .f. 53, 1, ** 1143 +* nlha = .f. 55, 10, ** 1144 ..s37 utsa 88 .+s47. utsa 89 +* nldimn = .f. 1, 32, ** utsa 90 +* nlmadr = .f. 65, 32, ** utsa 91 +* nlsize = .f. 33, 11, ** utsa 92 +* nlblk = .f. 44, 6, ** utsa 93 +* nlamode = .f. 50, 1, ** utsa 94 +* nlchinx = .f. 51, 1, ** utsa 95 +* nltrac = .f. 52, 1, ** utsa 96 +* nlfnct = .f. 53, 1, ** utsa 97 +* nlha = .f. 55, 10, ** utsa 98 ..s47 1145 .+s10. 1146 +* nldimn = .f. 1, 18, ** 1147 +* nlmadr = .f. 19, 18, ** 1148 +* nlha = .f. 37, 10, ** 1149 +* nlamode = .f. 47, 1, ** 1150 +* nlblk = .f. 48, 6, ** 1151 +* nlchinx = .f. 54, 1, ** 1152 +* nltrac = .f. 55, 1, ** 1153 +* nlfnct = .f. 56, 1, ** 1154 +* nlsize = .f. 57, 11, ** 1155 ..s10 1156 1157 size nsflg(1); data nsflg=0; $ on when inside nameset. 1158 size nstouse(ps); $ nameset to use in next size stttement 1159 data nstouse = localblock; 1160 1161 size nsubrs(ps); data nsubrs = 0; $ number of subrs seen 1162 size ntexterr(1); data ntexterr = no; $ on if certain errors 1163 $ detected outside of subroutine to prevent run-away errors 1164 1165 $ o p e r a t o r a t t r i b u t e s. 1166 1167 $ opkind array, indexed by operator code, gives 'gross' operator 1168 $ type used by blkend and also indicates if operator commutes. 1169 $ commutativity information unpacked in genini, later accessed 1170 $ used -commutesatr- macro. 1171 size opkind(ws); dims opkind(nopcodes); 1172 1173 $ operator attributes are entered in the opkind array using the 1174 $ -op- macro below. three attributes are currently defined - 1175 $ - blkendtype, used by blkend to determine pattern in voa. 1176 $ - commutativity, used by emit2 to standardize commutative ops 1177 $ in order to detect more redundant expressions. 1178 $ -realopcd- is set for amode=amode_real ops. 1179 1180 +* op(opc, gc, c, r) = opkind(opc) = 4*gc + 2*r + c ** 1181 data 1182 op(op_add , 03, yes, no): 1183 op(op_sub , 03, no , no): 1184 op(op_gt , 03, no , no): 1185 op(op_lt , 03, no , no): 1186 op(op_ge , 03, no , no): 1187 op(op_le , 03, no , no): 1188 op(op_eq , 03, yes, no): 1189 op(op_ne , 03, yes, no): 1190 op(op_mul , 03, yes, no): 1191 op(op_div , 03, no , no): 1192 op(op_or , 03, yes, no): 1193 op(op_and , 03, yes, no): 1194 op(op_exor , 03, yes, no): 1195 $ opcode not used 1196 op(op_nb , 02, no , no): 1197 op(op_fb , 02, no , no): 1198 op(op_not , 02, no , no): 1199 op(op_fcall , 05, no , no): 1200 op(op_call , 06, no , no): 1201 op(op_asin , 07, no , no): 1202 op(op_data , 01, no , no): 1203 op(op_fasin , 09, no , no): 1204 op(op_io , 15, no , no): $ unformatted io 1205 op(op_return , 01, no , no): 1206 op(op_fext , 04, no , no): 1207 op(op_if , 11, no , no): 1208 op(op_lab , 01, no , no): 1209 op(op_goto , 01, no , no): 1210 op(op_goby , 11, no , no): 1211 op(op_xload , 16, no , no): 1212 op(op_xasin , 08, no , no): 1213 op(op_xfasin , 10, no , no): 1214 op(op_ifnot , 11, no , no): 1215 op(op_ccat , 03, no , no): 1216 op(op_in , 03, no , no): 1217 op(op_eext , 04, no , no): 1218 op(op_sext , 04, no , no): 1219 op(op_easin , 09, no , no): 1220 op(op_sasin , 09, no , no): 1221 op(op_xeasin , 10, no , no): 1222 op(op_xsasin , 10, no , no): 1223 op(rop_add , 12, yes, yes): 1224 op(rop_sub , 12, no , yes): 1225 op(rop_gt , 13, no , yes): 1226 op(rop_lt , 13, no , yes): 1227 op(rop_ge , 13, no , yes): 1228 op(rop_le , 13, no , yes): 1229 op(rop_eq , 13, yes, yes): 1230 op(rop_ne , 13, yes, yes): 1231 op(rop_mul , 12, yes, yes): 1232 op(rop_div , 12, no , yes): 1233 op(rop_usub , 14, no , yes): 1234 op(bop_float , 02, no , yes): 1235 op(bop_ifix , 02, no , no): 1236 op(bop_abs , 02, no , yes): 1237 op(bop_iabs , 02, no , no): 1238 op(bop_aint , 02, no , yes): 1239 op(bop_int , 02, no , no): 1240 op(bop_amod , 03, no , yes): 1241 op(bop_mod , 03, no , no): 1242 op(bop_sign , 03, no , yes): 1243 op(bop_isign , 03, no , no): 1244 op(bop_dim , 03, no , yes): 1245 op(bop_idim , 03, no , no): 1246 op(bop_exp , 02, no , yes): 1247 op(bop_alog , 02, no , yes): 1248 op(bop_alog10, 02, no , yes): 1249 op(bop_sin , 02, no , yes): 1250 op(bop_cos , 02, no , yes): 1251 op(bop_tanh , 02, no , yes): 1252 op(bop_sqrt , 02, no , yes): 1253 op(bop_atan , 02, no , yes): 1254 op(bop_atan2 , 03, no , yes): 1255 op(op_list , 01, no , no): 1256 op(op_seq , 03, yes, no): 1257 op(op_sne , 03, yes, no); 1258 1259 +* op = ** $ drop macro. 1260 1261 size opstackp(ps); data opstackp=0; $ ptr to opstack 1262 1263 size parsereg(ps); dims parsereg(8); $ registers of parse mac 1264 1265 size parsetrace(1); data parsetrace = no; 1266 ldsa 46 .+rep. ldsa 47 $ rep_opt on if generating report file. ldsa 48 size rep_opt(ps); ldsa 49 size rep_opt_c(1); $ on if reporting calls ldsa 50 size rep_opt_p(1); $ on if reporting procedure definitions ldsa 51 size rep_opt_g(1); $ on if reporting global storage allocation ldsa 52 size rep_suffix(.sds. 5); $ report suffix code ldsa 53 ..rep ldsa 54 1267 size pelvalue(ps); $ error limit 1268 1269 $ proclineno is line number relative to start of current 1270 $ procedure. 1271 size proclineno(ps); data proclineno = 0; 1272 1273 size rlsz(ps); $ size of real (floating point) quanitty. 1274 1275 1276 $ 'replication' variables used by gendat. replication is switch 1277 $ set wheh data replication requested in data value list. 1278 $ replication_origin records position in arglist at start of 1279 $ data list processing. replicate is bit string, with bit i on 1280 $ if arglist(i) contains a replication value and not data value. 1281 1282 size replicate(argmax); 1283 size replication(1); 1284 size replication_origin(ps); 1285 1286 $ safeconst is array, indexed by lexical type, with non-zero 1287 $ entry if constants of corresponding type can safely be 1288 $ evaluated at compile time. 1289 size safeconst(ps); dims safeconst(toktypes); 1290 data safeconst = 0(toktypes); $ assume all unsafe, correct this 1291 $ assumption in genini. 1292 1293 1294 size savetoks(ps); data savetoks=5; $ conter of saved tokens 1295 1296 size sdsnamstr(namsz); data sdsnamstr=0; $ parameter to sdsnamr. 1297 1298 size setqfok(1); data setqfok = no; $ switch for -setq-. 1299 1300 size sfp_opt(1); data sfp_opt = no; $ suppress first routine 1301 1302 size signofcon(1); data signofcon=0; $ constant sign(1 is minus 1303 1304 1305 size subinfo(ps); dims subinfo(3); $ subr/fnct info array 1306 1307 size targetmachine(ps); $ index of target machine 1308 data targetmachine = hostmachine; 1309 1310 +* tlistmax = $ dimension of -tlist- (no. of temporaries) ldsd 16 60 1312 ** 1313 1314 .+s66 nameset blank; $ keep in blank common on s66. 1315 size tlist(ws); dims tlist(tlistmax); $ temporaries list 1316 .+s66 end nameset; 1317 size tlistptr(ps); data tlistptr=0; $ top of tlist. 1318 +* tokrbuflim = 256 ** 1319 +* tokarasz = ws ** $ size of tokara 1320 +* tokaradims = ((toklenmax+cpw)/cpw) ** 1321 size tokara(tokarasz); dims tokara(tokaradims); $ token array 1322 size toklen(ps); $ token length in characters 1323 size toklt(ps); $ token lexical type 1324 .+s66 nameset blank; $ keep in blank common on s66. 1325 size tokrbuf(ws); dims tokrbuf(tokrbuflim); $ token buffer 1326 .+s66 end nameset; 1327 size tokrbufp(ps); data tokrbufp=0; $ ptr to tokrbuf 1328 size tokwords(ps); $ no of words in token value 1329 1330 size tmara(ws); dims tmara(tmparams); $ target machine parameter 1331 size tmtokara(tokarasz); dims tmtokara(tmparams); 1332 1333 .+haprobes. 1334 size tothaexam(ws); data tothaexam=0; $ no of times ha looped 1335 size tothaprobes(ws); data tothaprobes=0; $ no of ha probes 1336 ..haprobes 1337 size totwaste(ps); data totwaste=0; $ unused memory words 1338 1339 $ v a l . (used to hold constant values) 1340 +* valmax = $ dimension of -val- array 1341 .+s66 0700 vax 83 .+s32 1100 1342 .+s37 1100 utsa 99 .+s47 1100 mgfb 14 .+s10 1100 1344 ** 1345 1346 size valptr(ps); data valptr = 1; $ ptr to val array 1347 .+s66 nameset blank; $ keep in blank common on s66. 1348 size val(ws); dims val(valmax); $ holds constant values 1349 .+s66 end nameset; 1350 1351 $ v o a . variable / operations array 1352 1353 +* voasz = $ size of voa 1354 .+s66 120 dsw 27 .+s32 192 dsw 28 .+s37 192 utsa 100 .+s47 192 1356 .+s10 144 1357 ** 1358 +* vomax = $ dimension of -voa- 1359 1850 1360 ** 1361 1362 size voptr(ps); $ ptr to voa 1363 +* voafnct = 1 ** 1364 data voptr = voafnct; $ ready to begin definition 1365 1366 size voa(voasz); dims voa(vomax); 1367 .+s66 nameset blank; $ keep in blank common on s66. 1368 size voawrt(1); $ on if writing voa file 1369 .+s66 end nameset; 1370 $ v o a f i e l d s 1371 1372 $ fields common to both -operation- and -quantity- operations 1373 1374 .+s66. 1375 +* deflev = .f. 1, 6, ** $ definition level 1376 +* keeb = .f. 7, 1, ** $ keep bit for holding till blkend 1377 +* naym = .f. 8, 10, ** $ ha ptr 1378 +* opb = .f. 18, 1, ** $ 'is this an operation' 1379 +* syze = .f. 19, 11, ** $ entry size in bits 1380 +* amode = .f. 118, 1, ** $ real or integer mode 1381 1382 $ voa field for -variable' or non-operation entries (opb = no) 1383 1384 +* arb = .f. 30, 1, ** $ argument bit 1385 +* argno = .f. 31, 5, ** $ argument no of parameter 1386 +* const = .f. 36, 1, ** $ on if 'constant' 1387 +* dimn = .f. 37, 16, ** $ dimension of array (or 0 if no dimn) 1388 +* vlen = .f. 55, 5, ** $ no of words in constant value 1389 +* temb = .f. 60, 1, ** $ on if 'temporary' 1390 +* voanl = .f. 61, 9, ** $ pointer to -nl- for global 1391 +* madr = .f. 70, 16, ** $ machine address of item 1392 +* mblk = .f. 86, 6, ** $ machine block of item 1393 +* type = .f. 92, 2, ** $ quantity type 1394 +* vbeg = .f. 94, 12, ** $ start of const val in -val- array 1395 +* signbit = .f.106,1, ** $ sign of constant (0=+, 1=-) 1396 +* lextype = .f. 107,5, ** $ lexical type of constant 1397 +* isafnct = .f. 113,1, ** $ set when name used as function name 1398 +* varnuse = .f. 114, 4, ** $ number of uses of var. 1399 +* varnusemax = 1b'1111' ** $ max of -varnuse- field 1400 +* isavar = .f. 119, 1, ** $ 'used as variable' 1401 1402 $ fields for operation type entries 1403 1404 1405 +* argbeg = .f. 30, 9, ** $ beginning of extra arguments 1406 +* arglen = .f. 39, 9, ** $ number of extra arguments 1407 +* db1 = .f. 49, 1, ** $ drop bit for input 1 1408 +* db2 = .f. 50, 1, ** $ drop bit for input 2 1409 +* db3 = .f. 51, 1, ** $ drop bit for input 3 1410 +* opcode = .f. 52, 7, ** 1411 +* seblk = .f. 59, 1, ** $ indicates if scall ends block 1412 +* bytaln = .f. 60, 1, ** $ indicates char. extract or assign 1413 +* inp1 = .f. 61, 12, ** $ voa index of first input 1414 +* inp2 = .f. 73, 12, ** $ voa index of second input 1415 +* inp3 = .f. 85, 12, ** $ voa index of third input 1416 +* oup = .f. 97, 12, ** $ voa index of output 1417 +* lastuse = .f. 109, 9, **$ voa index of last use of op 1418 +* dboup = .e. 119, 01, ** $ drop bit if oup used as input. 1419 ..s66 1420 vax 85 .+s32. vax 86 +* amode = .f. 1, 1, ** vax 87 +* keeb = .f. 2, 1, ** vax 88 +* opb = .f. 3, 1, ** vax 89 +* naym = .f. 4, 10, ** vax 90 +* syze = .f. 17, 16, ** vax 91 +* deflev = .f. 33, 6, ** vax 92 vax 93 +* const = .f. 14, 1, ** vax 94 +* temb = .f. 15, 1, ** vax 95 +* signbit = .f. 16, 1, ** vax 96 +* isafnct = .f. 39, 1, ** vax 97 +* voanl = .f. 40, 9, ** dsw 29 +* dimn = .f. 129, 32, ** dss 24 +* varnuse = .f. 65, 8, ** dss 25 +* varnusemax = 4b'ff' ** dss 26 +* mblk = .f. 73, 7, ** dss 27 +* isavar = .f. 80, 1, ** dsw 30 +* madr = .f. 161, 32, ** dss 29 +* vlen = .f. 97, 8, ** dss 30 +* lextype = .f. 105, 4, ** dss 31 +* argno = .f. 109, 5, ** dss 32 +* arb = .f. 114, 1, ** dss 33 +* type = .f. 115, 2, ** dss 34 +* vbeg = .f. 117, 12, ** vax 110 vax 111 +* db1 = .f. 14, 1, ** vax 112 +* db2 = .f. 15, 1, ** vax 113 +* db3 = .f. 16, 1, ** vax 114 +* arglen = .f. 39, 9, ** vax 115 +* dboup = .f. 48, 1, ** vax 116 +* inp1 = .f. 49, 16, ** vax 117 +* inp2 = .f. 65, 11, ** vax 118 +* lastuse = .f. 76, 10, ** vax 119 +* inp3 = .f. 86, 11, ** vax 120 +* opcode = .f. 97, 8, ** vax 121 +* seblk = .f. 105, 1, ** vax 122 +* bytaln = .f. 106, 1, ** vax 123 +* argbeg = .f. 107, 10, ** vax 124 +* oup = .f. 118, 11, ** vax 125 ..s32 1421 .+s37. 1422 +* amode = .f. 1, 1, ** 1423 +* keeb = .f. 2, 1, ** 1424 +* opb = .f. 3, 1, ** 1425 +* naym = .f. 4, 10, ** 1426 +* syze = .f. 17, 16, ** 1427 +* deflev = .f. 33, 6, ** 1428 1429 +* const = .f. 14, 1, ** 1430 +* temb = .f. 15, 1, ** 1431 +* signbit = .f. 16, 1, ** 1432 +* isafnct = .f. 39, 1, ** 1433 +* voanl = .f. 40, 9, ** dsw 31 +* dimn = .f. 129, 32, ** dst 15 +* varnuse = .f. 65, 8, ** dst 16 +* varnusemax = 4b'ff' ** dst 17 +* mblk = .f. 73, 7, ** dst 18 +* isavar = .f. 80, 1, ** dsw 32 +* madr = .f. 161, 32, ** dst 20 +* vlen = .f. 97, 8, ** dst 21 +* lextype = .f. 105, 4, ** dst 22 +* argno = .f. 109, 5, ** dst 23 +* arb = .f. 114, 1, ** dst 24 +* type = .f. 115, 2, ** dst 25 +* vbeg = .f. 117, 12, ** 1446 1447 +* db1 = .f. 14, 1, ** 1448 +* db2 = .f. 15, 1, ** 1449 +* db3 = .f. 16, 1, ** 1450 +* arglen = .f. 39, 9, ** 1451 +* dboup = .f. 48, 1, ** 1452 +* inp1 = .f. 49, 16, ** 1453 +* inp2 = .f. 65, 11, ** 1454 +* lastuse = .f. 76, 10, ** 1455 +* inp3 = .f. 86, 11, ** 1456 +* opcode = .f. 97, 8, ** 1457 +* seblk = .f. 105, 1, ** 1458 +* bytaln = .f. 106, 1, ** 1459 +* argbeg = .f. 107, 10, ** 1460 +* oup = .f. 118, 11, ** 1461 ..s37 utsa 101 .+s47. utsa 102 +* amode = .f. 1, 1, ** utsa 103 +* keeb = .f. 2, 1, ** utsa 104 +* opb = .f. 3, 1, ** utsa 105 +* naym = .f. 4, 10, ** utsa 106 +* syze = .f. 17, 16, ** utsa 107 +* deflev = .f. 33, 6, ** utsa 108 utsa 109 +* const = .f. 14, 1, ** utsa 110 +* temb = .f. 15, 1, ** utsa 111 +* signbit = .f. 16, 1, ** utsa 112 +* isafnct = .f. 39, 1, ** utsa 113 +* voanl = .f. 40, 9, ** utsa 114 +* dimn = .f. 129, 32, ** utsa 115 +* varnuse = .f. 65, 8, ** utsa 116 +* varnusemax = 4b'ff' ** utsa 117 +* mblk = .f. 73, 7, ** utsa 118 +* isavar = .f. 80, 1, ** utsa 119 +* madr = .f. 161, 32, ** utsa 120 +* vlen = .f. 97, 8, ** utsa 121 +* lextype = .f. 105, 4, ** utsa 122 +* argno = .f. 109, 5, ** utsa 123 +* arb = .f. 114, 1, ** utsa 124 +* type = .f. 115, 2, ** utsa 125 +* vbeg = .f. 117, 12, ** utsa 126 utsa 127 +* db1 = .f. 14, 1, ** utsa 128 +* db2 = .f. 15, 1, ** utsa 129 +* db3 = .f. 16, 1, ** utsa 130 +* arglen = .f. 39, 9, ** utsa 131 +* dboup = .f. 48, 1, ** utsa 132 +* inp1 = .f. 49, 16, ** utsa 133 +* inp2 = .f. 65, 11, ** utsa 134 +* lastuse = .f. 76, 10, ** utsa 135 +* inp3 = .f. 86, 11, ** utsa 136 +* opcode = .f. 97, 8, ** utsa 137 +* seblk = .f. 105, 1, ** utsa 138 +* bytaln = .f. 106, 1, ** utsa 139 +* argbeg = .f. 107, 10, ** utsa 140 +* oup = .f. 118, 11, ** utsa 141 ..s47 dso 30 .+s10. dso 31 +* amode = .f. 1, 1, ** dso 32 +* keeb = .f. 2, 1, ** dso 33 +* opb = .f. 3, 1, ** dso 34 +* naym = .f. 4, 10, ** dso 35 +* syze = .f. 17, 11, ** dso 36 +* deflev = .f. 28, 6, ** dso 37 dso 38 +* const = .f. 14, 1, ** dso 39 +* temb = .f. 15, 1, ** dso 40 +* signbit = .f. 16, 1, ** dso 41 +* isafnct = .f. 37, 1, ** dso 42 +* inreg = .f. 38, 8, ** dso 43 +* ppdata = .f. 46, 1, ** dso 44 +* voanl = .f. 38, 9, ** dso 45 +* vlen = .f. 47, 8, ** dso 46 +* lextype = .f. 55, 4, ** dso 47 +* frsdata = .f. 47, 12, ** dso 48 +* argno = .f. 59, 5, ** dso 49 +* mblk = .f. 64, 6, ** dso 50 +* arb = .f. 70, 1, ** dso 51 +* isavar = .f. 71, 1, ** dso 52 +* type = .f. 73, 2, ** dsw 33 +* dimn = .f. 75, 17, ** dsw 34 +* madr = .f. 92, 17, ** dst 26 +* vbeg = .f. 109, 12, ** dst 27 +* varnuse = .f. 121, 8, ** dso 57 +* varnusemax = 4b'ff' ** dso 58 dso 59 +* db1 = .f. 14, 1, ** dso 60 +* db2 = .f. 15, 1, ** dso 61 +* db3 = .f. 16, 1, ** dso 62 +* arglen = .f. 37, 9, ** dso 63 +* dboup = .f. 46, 1, ** dso 64 +* inp1 = .f. 47, 11, ** dso 65 +* inp2 = .f. 58, 11, ** dso 66 +* seblk = .f. 69, 1, ** dso 67 +* bytaln = .f. 70, 1, ** dso 68 +* inp3 = .f. 73, 11, ** dso 69 +* lastuse = .f. 84, 10, ** dso 70 +* oup = .f. 94, 11, ** dso 71 +* opcode = .f. 109, 7, ** dso 72 +* argbeg = .f. 116, 10, ** dso 73 ..s10 1503 $ macro voaup counts up the voa ptr 1504 +* voaup = $ increment voa top pointer 1505 countup(voptr, vomax, 'voa'); ** 1506 1507 size voafilename(ws); $ name of voa file 1508 $ v o a f i l e m a c r o s 1509 +* vofsz = $ size of voa file header frame. vax 126 .+s32 256 1510 .+s37 256 utsa 142 .+s47 256 1511 .+s66 240 1512 .+s10 288 1513 ** 1514 1515 +* voa_level = .e. 17, 16, ** $ julian date of last change 1516 $ relative to 1 jan 1976 (ie, juliandate - 76000). 1517 $ *** when change array size or fields, update version no. *** 1518 1519 $ codes for items in voa-file 1520 +* voaeof_code = 0 ** $ marks end of file 1521 +* voahdr_code = 1 ** $ file header code 1522 +* voaasm_code = 2 ** $ routine header code 1523 +* voa_code = 3 ** $ voa 1524 +* ha_code = 4** $ ha 1525 +* names_code = 5 ** $ names array 1526 +* xarg_code = 6 ** $ xarg array 1527 +* val_code = 7 ** $ val array 1528 +* mbacode = 8 ** $ m-achine b-lock a-rray (mba) 1529 +* eos_code = 9 ** $ code for end of subprogram 1530 1531 vax 127 .+s32. vax 128 $ first, fields common to all header entries vax 129 +* vof_code = .e. 1,16, ** $ code of item vax 130 +* vof_hdrseq = .e. 17,16, ** $ header sequence number vax 131 +* vof_es = .e.33,16, ** $ entry size in bits vax 132 +* vof_lo = .e.49,16, ** $ lo entry of array vax 133 $ for debugging vax 134 +* vof_hi = .e.65,16, ** $ high entry of array vax 135 +* vof_listcode = .e. 81, 01, ** $ on to list generated code. vax 136 $ to format of any item written to voa. vax 137 +* vof_hamax = .e. 97,16, ** $ hamax in gen vax 138 vax 139 $ fields used to pass non/array args to assembler vax 140 +* vof_asmarg = .e. 129, 16,** $ assemblarg vax 141 +* vof_init = .e. 145, 16,** $ init vax 142 +* vof_lablistptr = .e. 161, 16, ** $ lablistptr vax 143 +* vof_sub1 = .e. 177, 16, ** $ subinfo(1), a name vax 144 +* vof_sub2 = .e. 193, 16, ** $ subinfo(2) vax 145 +* vof_sub3 = .e. 209, 16, ** $ subinfo(3) vax 146 +* vof_subrargs = .e. 225, 16, ** $ no. of arguments of current vax 147 $ routine vax 148 +* vof_ha0 = .e. 241, 16, ** $ ha index of constant 0. vax 149 +* vof_ha1 = .e. 113, 16, ** $ ha index of constant 1. vax 150 ..s32 1532 .+s37. 1533 $ first, fields common to all header entries 1534 +* vof_code = .e. 1,16, ** $ code of item 1535 +* vof_hdrseq = .e. 17,16, ** $ header sequence number 1536 +* vof_es = .e.33,16, ** $ entry size in bits 1537 +* vof_lo = .e.49,16, ** $ lo entry of array 1538 $ for debugging 1539 +* vof_hi = .e.65,16, ** $ high entry of array 1540 +* vof_listcode = .e. 81, 01, ** $ on to list generated code. 1541 $ to format of any item written to voa. 1542 +* vof_hamax = .e. 97,16, ** $ hamax in gen 1543 1544 $ fields used to pass non/array args to assembler 1545 +* vof_asmarg = .e. 129, 16,** $ assemblarg 1546 +* vof_init = .e. 145, 16,** $ init 1547 +* vof_lablistptr = .e. 161, 16, ** $ lablistptr 1548 +* vof_sub1 = .e. 177, 16, ** $ subinfo(1), a name 1549 +* vof_sub2 = .e. 193, 16, ** $ subinfo(2) 1550 +* vof_sub3 = .e. 209, 16, ** $ subinfo(3) 1551 +* vof_subrargs = .e. 225, 16, ** $ no. of arguments of current 1552 $ routine 1553 +* vof_ha0 = .e. 241, 16, ** $ ha index of constant 0. 1554 +* vof_ha1 = .e. 113, 16, ** $ ha index of constant 1. 1555 ..s37 utsa 143 .+s47. utsa 144 $ first, fields common to all header entries utsa 145 +* vof_code = .e. 1,16, ** $ code of item utsa 146 +* vof_hdrseq = .e. 17,16, ** $ header sequence number utsa 147 +* vof_es = .e.33,16, ** $ entry size in bits utsa 148 +* vof_lo = .e.49,16, ** $ lo entry of array utsa 149 $ for debugging utsa 150 +* vof_hi = .e.65,16, ** $ high entry of array utsa 151 +* vof_listcode = .e. 81, 01, ** $ on to list generated code. utsa 152 $ to format of any item written to voa. utsa 153 +* vof_hamax = .e. 97,16, ** $ hamax in gen utsa 154 utsa 155 $ fields used to pass non/array args to assembler utsa 156 +* vof_asmarg = .e. 129, 16,** $ assemblarg utsa 157 +* vof_init = .e. 145, 16,** $ init utsa 158 +* vof_lablistptr = .e. 161, 16, ** $ lablistptr utsa 159 +* vof_sub1 = .e. 177, 16, ** $ subinfo(1), a name utsa 160 +* vof_sub2 = .e. 193, 16, ** $ subinfo(2) utsa 161 +* vof_sub3 = .e. 209, 16, ** $ subinfo(3) utsa 162 +* vof_subrargs = .e. 225, 16, ** $ no. of arguments of current utsa 163 $ routine utsa 164 +* vof_ha0 = .e. 241, 16, ** $ ha index of constant 0. utsa 165 +* vof_ha1 = .e. 113, 16, ** $ ha index of constant 1. utsa 166 ..s47 1556 .+s66. 1557 +* vof_code = .e. 01, 06, ** $ code of item 1558 +* vof_hdrseq = .e. 07, 18, ** $ header sequence number. 1559 +* vof_es = .e. 25, 12, ** $ entry size in bits 1560 +* vof_lo = .e. 37, 12, ** $ lo entry of array 1561 +* vof_hi = .e. 49, 12, ** $ high entry of array 1562 +* vof_listcode = .e. 61, 01, ** $ on to list generated code. 1563 +* vof_hamax = .e. 62, 11, ** $ hamax in gen 1564 +* vof_asmarg = .e. 73, 12,** $ assemblarg 1565 +* vof_init = .e. 85, 12,** $ init 1566 +* vof_lablistptr = .e. 97, 12, ** $ lablistptr 1567 +* vof_sub1 = .e. 109, 12, ** $ subinfo(1), a name 1568 +* vof_sub2 = .e. 121, 12, ** $ subinfo(2) 1569 +* vof_sub3 = .e. 133, 12, ** $ subinfo(3) 1570 +* vof_subrargs = .e. 145, 12, ** $ no. of arguments of current 1571 $ routine 1572 +* vof_ha0 = .e. 157, 12, ** $ ha index of constant 0. 1573 +* vof_ha1 = .e. 169, 12, ** $ ha index of constant 1. 1574 ..s66 1575 .+s10. 1576 +* vof_code = .f. 1, 18, ** 1577 +* vof_hdrseq = .f. 19, 18, ** 1578 +* vof_es = .f. 37, 18, ** 1579 +* vof_lo = .f. 55, 18, ** 1580 +* vof_hi = .f. 73, 18, ** 1581 +* vof_listcode = .f. 91, 1, ** 1582 +* vof_hamax = .f. 109, 18, ** 1583 +* vof_asmarg = .f. 127, 18, ** 1584 +* vof_init = .f. 145, 18, ** 1585 +* vof_lablistptr = .f. 163, 18, ** 1586 +* vof_sub1 = .f. 181, 18, ** 1587 +* vof_sub2 = .f. 199, 18, ** 1588 +* vof_sub3 = .f. 217, 18, ** 1589 +* vof_subrargs = .f. 235, 18, ** 1590 +* vof_ha0 = .f. 253, 18, ** 1591 +* vof_ha1 = .f. 271, 18, ** 1592 ..s10 1593 1594 size vof(vofsz); $ scratch area for building voa file frames. 1595 1596 size vofhdrseq(ps); data vofhdrseq=0; $ vof header frame sequen 1597 $ warnthis is number of warnings issued including current 1598 $ routine. warnprev is number of warnings issues through 1599 $ end of previous routine. 1600 size warnprev(ps); data warnprev = 0; 1601 size warnthis(ps); data warnthis = 0; 1602 1603 $ x a r g. extra arguments array dsw 35 +* xargsz = $ size of xarg array. dsw 36 .+s10 ws dsw 37 .+s32 64 dsw 38 .+s37 64 utsa 167 .+s47 64 dsw 39 .+s66 ws dsw 40 ** 1605 +* xargmax = 511 ** $ xarg dims 1606 .+s66 nameset blank; $ keep in blank common on s66. 1607 size xarg(xargsz); dims xarg(xargmax); $ extra arguments array 1608 .+s66 end nameset; 1609 size xargptr(ps); data xargptr = 1; $ ptr to xarg 1610 $ fields of xarg array 1611 .+s66. 1612 +* xarg_voa = .f. 16, 15, ** $ ptr to voa entry 1613 +* xarg_db = .f. 31, 1, ** 1614 +* xarg_rep = .f. 1, 15, ** 1615 ..s66 vax 151 .+s32. vax 152 +* xarg_voa = .f. 1, 16, ** vax 153 +* xarg_db = .f. 17, 1, ** dsw 41 +* xarg_rep = .f. 33, 32, ** vax 155 ..s32 1616 .+s37. 1617 +* xarg_voa = .f. 1, 16, ** 1618 +* xarg_db = .f. 17, 1, ** dsw 42 +* xarg_rep = .f. 33, 32, ** 1620 ..s37 utsa 168 .+s47. utsa 169 +* xarg_voa = .f. 1, 16, ** utsa 170 +* xarg_db = .f. 17, 1, ** utsa 171 +* xarg_rep = .f. 33, 32, ** utsa 172 ..s47 1621 .+s10. dsw 43 +* xarg_voa = .f. 1, 15, ** dsw 44 +* xarg_rep = .f. 19, 18, ** dsw 45 +* xarg_db = .f. 16, 1, ** 1625 ..s10 1626 1627 $ x h a. hash array for global symbols 1628 +* xhamax = $ dimension of -xha- 1629 443 1630 ** 1631 1632 +* xhasz = $ size of xha 1633 .+s66 60 vax 156 .+s32 64 1634 .+s37 64 utsa 173 .+s47 64 1635 .+s10 72 1636 ** 1637 1638 .+s66 nameset blank; $ keep in blank common on s66. 1639 size xha(xhasz); dims xha(xhamax); $ global hash table 1640 .+s66 end nameset; 1641 $ xhafree is xha index of next free entry + 1. 1642 size xhafree(ps); data xhafree = xhamax+1; 1643 1644 $ xha fields 1645 .+s66. 1646 +* nlno = .f. 01, 09, ** $ index of size info for global var 1647 +* xlink = .f. 10, 09, ** $ link for hash in -xha- 1648 +* xnsblk = .f. 19, 06, ** $ -mba- pointer for nameset 1649 +* xhabif = .f. 25, 05, ** $ code if builtin operator name 1650 +* xnchars = .f. 33, 08, ** $ number of characters of name 1651 +* xnameptr = .f. 41, 10, ** $ -xnames- index of symbol 1652 ..s66 vax 157 .+s32. vax 158 +* nlno = .f. 1, 16, ** vax 159 +* xlink = .f. 17, 16, ** vax 160 +* xnsblk = .f. 33, 8, ** vax 161 +* xnchars = .f. 41, 8, ** vax 162 +* xhabif = .f. 49, 6, ** vax 163 +* xnameptr = .f. 55, 10, ** vax 164 ..s32 1653 .+s37. 1654 +* nlno = .f. 1, 16, ** 1655 +* xlink = .f. 17, 16, ** 1656 +* xnsblk = .f. 33, 8, ** 1657 +* xnchars = .f. 41, 8, ** 1658 +* xhabif = .f. 49, 6, ** 1659 +* xnameptr = .f. 55, 10, ** 1660 ..s37 utsa 174 .+s47. utsa 175 +* nlno = .f. 1, 16, ** utsa 176 +* xlink = .f. 17, 16, ** utsa 177 +* xnsblk = .f. 33, 8, ** utsa 178 +* xnchars = .f. 41, 8, ** utsa 179 +* xhabif = .f. 49, 6, ** utsa 180 +* xnameptr = .f. 55, 10, ** utsa 181 ..s47 1661 .+s10. 1662 +* nlno = .f. 1, 18, ** 1663 +* xlink = .f. 19, 18, ** 1664 +* xnameptr = .f. 37, 18, ** 1665 +* xnsblk = .f. 55, 6, ** 1666 +* xhabif = .f. 61, 5, ** 1667 +* xnchars = .f. 66, 7, ** 1668 ..s10 1669 1670 +* xnamesmax = $ dimension of -xnames- 1671 .+s66 400 vax 165 .+s32 600 1672 .+s37 600 utsa 182 .+s47 600 dso 74 .+s10 600 1674 ** 1675 1676 .+s66 nameset blank; $ keep in blank common on s66. 1677 size xnames(ws); dims xnames(xnamesmax); $ xha names array 1678 .+s66 end nameset; 1679 size xnamesptr(ps); data xnamesptr = 1; $ xnames ptr 1680 1681 1682 1683 call genini; $ to initialize program and print title 1684 call parse; $ enter parser 1685 exitcode = 0; call genexit; $ end executions (normal) dso 75 .+s10 end prog start; vax 166 .+s32 end prog start; dso 76 .+s37 end prog start; utsa 183 .+s47 end prog start; dso 77 .+s66 end subr start; 1 .=member genini 2 subr genini; $ initialize parser 3 size help(sds(filenamelen)); data help = ''; $ initial debug opt 4 size machinename(sds(20)); $ names of possible host, targets 5 dims machinename(totmachines); 6 data ldsd 17 $ insert names of new machines after this line. 8 machinename(m66) = 'cdc 6000 series': ldsd 18 .+s32v machinename(m32) = 'dec vax-11 vms': ldsd 19 .+s32u machinename(m32) = 'dec vax-11 unix': dso 78 machinename(m37) = 'ibm system/370': utsa 184 machinename(m47) = 'amdahl uts': dso 79 machinename(m40) = 'prime 400': 10 machinename(m16) = 'honeywell series 16': 11 machinename(m11) = 'dec pdp-11': 12 machinename(m10) = 'decsystem-10'; 13 14 size tmvar(sds(10)); $ receives tm specification 15 $ --note-- require that filenamelen >= 2*tmparams 16 size tmvarlabel(sds(35)); 17 size c1(cs), c2(cs); $ character temporaries for tm processing 18 data tmvarlabel = ' ws= , ps= , cs= , sl= , so= .'; 19 size voafilename(sds(filenamelen)); $ name of voa file 20 size tokenfilename(sds(filenamelen)); $ name of token file dsv 16 size appstr(.sds. getapp_len); $ actual parameter string. 22 size i(ps); $ do loop index 23 size j(ps); $ index. 24 size hap(ps), xhap(ps); $ ha and xha indexes. ldsa 55 size rep_opt_str(.sds. filenamelen); eaa 9 size targetmachine20(1); $ on if tm=20 for extended addr. 25 26 do i = 1 to xhamax; xha(i) = 0; end do; $ clear xha. 27 $ we hold the alias names for built-in functions in -bfntab- 28 $ during initialization in the flollowing format (op, name). 29 $ if op is zero, name is the machine for which the aliases are 30 $ assigned (0 ends list). dss 35 +* bfntabsz = (.sds. 10) ** utsa 185 +* bfntabmax = 150 ** 33 size bfntab(bfntabsz); dims bfntab(bfntabmax); 34 data bfntab = 35 +* ins(op, name) = op, name, ** $ name to insert dso 81 0, m10, $ aliases for s10 dso 87 ins(bop_exp, 'expx$r') dso 88 ins(bop_alog, 'alog$r') dso 89 ins(bop_alog10, 'al10$r') dso 90 ins(bop_sin, 'sinx$r') dso 91 ins(bop_cos, 'cosx$r') dso 92 ins(bop_tanh, 'tanh$r') dso 93 ins(bop_sqrt, 'sqrt$r') dso 94 ins(bop_atan, 'atan$r') dso 95 ins(bop_atan2, 'atn2$r') vax 169 0, m32, $ aliases for s32 dss 36 ins(bop_exp, 'mth$exp') dss 37 ins(bop_alog, 'mth$alog') ldsb 22 .+s32v ins(bop_alog10, 'mth$alog10') ldsb 23 .+s32u ins(bop_alog10, 'mth$alg10') $ at most eight chars for unix dss 39 ins(bop_sin, 'mth$sin') dss 40 ins(bop_cos, 'mth$cos') dss 41 ins(bop_tanh, 'mth$tanh') dss 42 ins(bop_sqrt, 'mth$sqrt') dss 43 ins(bop_atan, 'mth$atan') ldsb 24 .+s32v ins(bop_atan2, 'mth$atan2') ldsb 25 .+s32u ins(bop_atan2, 'mth$atn2') $ at most eight chars for unix ldsd 20 ins(bop_amod, 'mth$amod') ldsd 21 ins(bop_aint, 'mth$aint') ldsd 22 ins(bop_dim, 'mth$dim') 36 0, m37, $ aliases for s37 37 ins(bop_float, 'fltc$rl') 38 ins(bop_ifix, 'ifix$rl') 39 ins(bop_aint, 'aint$rl') 40 ins(bop_int, 'ifix$rl') 41 ins(bop_amod, 'amod$rl') 42 ins(bop_exp, 'expx$rl') 43 ins(bop_alog, 'alog$rl') 44 ins(bop_alog10, 'al10$rl') 45 ins(bop_sin, 'sinx$rl') 46 ins(bop_cos, 'cosx$rl') 47 ins(bop_tanh, 'tanh$rl') 48 ins(bop_sqrt, 'sqrt$rl') 49 ins(bop_atan, 'atan$rl') 50 ins(bop_atan2, 'atn2$rl') utsa 186 0, m47, $ aliases for s47 utsa 187 $ these names must match those used in little env mlib.s to utsa 188 $ interface to the c library. utsa 189 ins(bop_float, 'fltc$rl') utsa 190 ins(bop_ifix, 'ifix$rl') utsa 191 ins(bop_aint, 'aint$rl') utsa 192 ins(bop_int, 'ifix$rl') utsa 193 ins(bop_amod, 'amod$rl') utsa 194 ins(bop_exp, 'expx$rl') utsa 195 ins(bop_alog, 'alog$rl') utsa 196 ins(bop_alog10, 'al10$rl') utsa 197 ins(bop_sin, 'sinx$rl') utsa 198 ins(bop_cos, 'cosx$rl') utsa 199 ins(bop_tanh, 'tanh$rl') utsa 200 ins(bop_sqrt, 'sqrt$rl') utsa 201 ins(bop_atan, 'atan$rl') utsa 202 ins(bop_atan2, 'atn2$rl') 51 0,m66, $ aliases for 6600. 52 ins(bop_exp ,'expx$ml') 53 ins(bop_alog ,'alog$ml') 54 ins(bop_alog10,'al10$ml') 55 ins(bop_sin ,'sinx$ml') 56 ins(bop_cos ,'cosx$ml') 57 ins(bop_tanh ,'tanh$ml') 58 ins(bop_sqrt ,'sqrt$ml') 59 ins(bop_atan ,'atan$ml') 60 ins(bop_atan2 ,'atn2$ml') 61 0, 0; $ end of alias list 62 macdrop(ins) 63 64 size wpr(ps); data wpr = 1; $ words per real. 65 66 $ initialization data for built-ins 67 size bfnames(sds(6)); dims bfnames(numfncts); 68 data bfnames = $ user names for built-in functions 69 'float', 'ifix', 'abs', 'iabs', 'aint', 'int', 70 'amod', 'mod', 'sign', 'isign', 'dim', 'idim', 71 'exp', 'alog', 'alog10', 'sin', 'cos', 'tanh', 72 'sqrt', 'atan', 'atan2'; 73 74 $ the -bftyptab- array contains bit strings (one for each target 75 $ machine) indicating the types of each function. if a bit is 76 $ 1, the corresponding function is external; otherwise it is 77 $ internal. 78 size bftyptab(numfncts); dims bftyptab(totmachines); 79 data dsr 14 bftyptab(m10) = 1b' 1 11111 11100 00000 00000': 81 bftyptab(m11) = 1b' 1 11111 11101 01011 10111': 82 bftyptab(m16) = 1b' 1 11111 11100 00000 00000': ldsd 23 bftyptab(m32) = 1b' 1 11111 11101 00010 10000': 83 bftyptab(m37) = 1b' 1 11111 11100 00011 10011': utsa 203 bftyptab(m47) = 1b' 1 11111 11100 00011 10011': dso 96 bftyptab(m40) = 1b' 1 11111 11100 00011 10011': 84 bftyptab(m66) = 1b' 1 11111 11100 00000 00000'; 85 86 sorg sdsnamstr = nameorg; $ initalize origin 87 88 $ on entry, the literal information is available in arglist 89 $ as 3 entry groups, giving literal code, class, and value. 90 $ a code of 0 indicates end of list. 91 size cc(ps), vv(ps); 92 do i = 1 to argmax; $ scan over initial data. 93 if (arglist(i) = 0) quit do; $ at end of table. 94 vv = .f. 9, 8, arglist(i); $ get value. 95 if .f. 1, 8, arglist(i) then $ if table entry. 96 littabl(cc, (.f. 1, 8, arglist(i))) = vv; $ set value. 97 else 98 cc = vv; $ set class 99 end if; 100 end do; 101 102 do i = 1 to hamax; $ clear the ha. 103 ha(i) = 0; end do; 104 105 i = 0; $ set to null tm vax 184 .+s32 call getipp(i, 'tm=32/11'); 106 .+s37 call getipp(i, 'tm=37/'); utsa 204 .+s47 call getipp(i, 'tm=47/'); 107 .+s66 call getipp(i, 'tm=66/'); 108 .+s10 call getipp(i, 'tm=10/'); eaa 10 targetmachine20 = no; $ assume not tm=20 109 $ convert supplied code to machine code value. 110 if i=66 then targetmachine = m66; 111 elseif i=37 then targetmachine = m37; dso 97 elseif i=40 then targetmachine = m40; 112 elseif i=16 then targetmachine = m16; 113 elseif i=11 then targetmachine = m11; 114 elseif i=10 then targetmachine = m10; eaa 11 elseif i=20 then targetmachine = m10; eaa 12 targetmachine20 = yes; $ note so can set .ps. correctly. vax 185 elseif i=32 then targetmachine = m32; utsa 205 elseif i=47 then targetmachine = m47; 115 else targetmachine = hostmachine; 116 end if; 117 118 do i = 1 to numfncts; 119 bfmode bifatrtab(i) = 120 (.ch. 1, bfnames(i) < 1ri ! .ch. 1, bfnames(i) > 1rn); 121 bfext bifatrtab(i) = .f. i, 1, bftyptab(targetmachine); 122 bfargs bifatrtab(i) = blkendtype(opofbif(i))-1; 123 call pshnamr(hap, bfnames(i)); $ add name to -ha- 124 insglob(xhap, hap); $ and then to -xha- 125 xhabif xha(xhap) = i; $ mark as builtin 126 end do; 127 128 $ now, check for any alias names for this machine. 129 130 $ first, look for marker for machine. 131 do i = 1 to bfntabmax by 2; $ names kept in -bfntab- 132 if .f. 1, ws, bfntab(i) = 0 then $ we have a marker 133 if (.f. 1, ws, bfntab(i+1) = 0) quit do; $ hit end of tab 134 if .f. 1, ws, bfntab(i+1) = targetmachine then $ got it 135 do j = i+2 to bfntabmax by 2; 136 if (.f. 1, ws, bfntab(j) = 0) quit do; 137 call pshnamr(hap, bfntab(j+1)); $ add to -ha- 138 insglob(xhap, hap); $ then to -xha- 139 bfalias bifatrtab(bifofop((.f. 1, ws, bfntab(j)))) 140 = xhap; 141 end do; 142 end if; 143 end if; 144 end do; 145 .+pt call getipp(parsetrace, 'pt=0/1'); 146 utsa 206 .+s37. $ see if want ebcdic/ascii conversion utsa 207 call getipp(ebcascoption,'ebcasc=0/1'); utsa 208 ..s37 utsa 209 147 call getipp(asmvoadump, 'ad=0/1'); 148 tmvar = tmvardef; 149 150 if targetmachine = m16 then $ honeywell series 16 151 tmvar = '1616081616'; iorts=''; 152 wpr = 2; $ two words for floating point on s16. 153 elseif targetmachine = m11 then $ pdp-11. 154 tmvar = '1615081616'; 155 elseif targetmachine = m37 then utsa 210 tmvar = '3224081616'; utsa 211 elseif targetmachine = m47 then utsa 212 tmvar = '3224081616'; dso 98 elseif targetmachine = m40 then dso 99 tmvar = '1615081616'; 157 elseif targetmachine = m66 then 158 tmvar = '6017061113'; 159 elseif targetmachine = m10 then mgfb 15 tmvar = '3618091818'; vax 186 elseif targetmachine = m32 then vax 187 tmvar = '3230081616'; 161 end if; eaa 13 eaa 14 if targetmachine20 then $ if extended addressing eaa 15 tmvar = '3630091818'; $ s10, except ps=30 eaa 16 end if; 162 163 if targetmachine = hostmachine then 164 do i = 1 to toktypes; 165 safeconst(i) = yes; end do; 166 end if; 167 utsa 213 utsa 214 .+s37. $ safe to convert also if target is s47 utsa 215 if targetmachine = m47 then utsa 216 do i = 1 to toktypes; utsa 217 safeconst(i) = yes; end do; utsa 218 end if; utsa 219 ..s37 utsa 220 168 $ bit constants may always be converted safely. 169 safeconst(dectok) = yes; safeconst(bittok) = yes; 170 safeconst(sstok) = no; $ s-type strings are never safe. 171 172 call getspp(tmvar, 'tmp=' !! tmvar !! '/'); 173 if (slen tmvar ^= 10) tmvar = tmvardef; $ set default. 174 175 do i = 1 to 5; 176 c1 = .ch.(i*2)-1, tmvar; c2 = .ch. i*2, tmvar; 177 tmara(i) = 10*digofchar(c1) + digofchar(c2); 178 .ch. i*7 - 2, tmvarlabel = c1; 179 .ch. i*7 - 1, tmvarlabel = c2; 180 tmtokara(i) = blankword; 181 .f. tokarasz+1 - 1*cs, cs, tmtokara(i) = c1; 182 .f. tokarasz+1 - 2*cs, cs, tmtokara(i) = c2; 183 end do; 184 185 rlsz = mws * wpr; $ size of real number. 186 187 call getipp(sfp_opt, 'sfp=0/1'); 188 189 gsopt = 1; $ for now, by default first procedure defines nameset 190 daopt = 1; $ for now, each routine has default access to all name 191 $ sets 192 call getipp(gsopt, 'gs=1/0'); 193 call getipp(daopt, 'da=1/0'); 194 ldse 13 call getipp(expire, 'expire=0/366'); ldse 14 vax 188 .+s32 call getspp(tokenfilename, 'tokens=tokens.tmp/'); 195 .+s37 call getspp(tokenfilename, 'tokens=sysut1/'); utsa 221 .+s47 call getspp(tokenfilename, 'tokens=sysut1/'); 196 .+s66 call getspp(tokenfilename, 'tokens=tokens/'); mgfa 1 .+s10 call getspp(tokenfilename, 'tokens=*.tok/'); 198 call opensio(tokenfile, iorc, access_read, tokenfilename, 199 0, i, 0, 0); dsv 17 .+s66 call rewisio(tokenfile, iorc, 0); 201 call dropsio(tokenfile, iorc); $ this is terminal use of tokenfil 202 call rdrwsio(tokenfile, iorc, tokrbuf, 1, tokrbuflim); vax 189 .+s32 call getspp(voafilename, 'voa=voa.tmp/'); 203 .+s37 call getspp(voafilename, 'voa=sysut2/'); utsa 222 .+s47 call getspp(voafilename, 'voa=sysut2/'); 204 .+s66 call getspp(voafilename, 'voa=voa/'); mgfa 2 .+s10 call getspp(voafilename, 'voa=*.voa/'); 206 voawrt = (.ch. 1, voafilename ^= 1r0); $ set whether writing voa 207 file voafile access=write, title=voafilename; dsv 18 .+s66 rewind voafile; 209 $ now write frame marking start of file 210 vof = 0; 211 vof_code vof = voahdr_code; $ file header dspp 1 .+s66 voa_level vof = voafilelevel; 213 $ other fields not defined now 214 vofhdrseq = vofhdrseq+1; vof_hdrseq vof = vofhdrseq; 215 write voafile, vof; 216 221 call getipp(pelvalue, 'pel=50/10000'); 222 call getipp(proclist, 'pdir=0/1'); 223 dso 101 .+s10 call getspp(crfileparm, 'rf=*.rf0/'); vax 191 .+s32 call getspp(crfileparm, 'rf=little.rf0/'); 224 .+s37 call getspp(crfileparm, 'rf=sysref(ref0)/'); utsa 223 .+s47 call getspp(crfileparm, 'rf=sysref(ref0)/'); 225 .+s66 call getspp(crfileparm, 'rf=ref0/'); 230 call getipp(crossrefoption, 'lcr=0/1'); dsu 10 $ pdir option requires crossrefoption. dsu 11 if (proclist) crossrefoption = yes; 231 if crossrefoption then $ open second reference file. 232 proclist = yes; $ get procedure directory. 233 call crfnam(crfilename, crfileparm, 3); $ file 3. 234 call opensio(crfile, iorc, access_write, crfilename, 235 0, i, 0, 0); 236 end if; 237 mbaptr = globalblock - 1; $ mbaptr points to last global block 238 $ that has been defined, so start off just below globalblock 239 240 ldsa 56 .+rep. ldsa 57 call getspp(rep_opt_str, 'rep=0/pg'); ldsa 58 rep_opt_c = ('c' .in. rep_opt_str) > 0; ldsa 59 rep_opt_g = ('g' .in. rep_opt_str) > 0; ldsa 60 rep_opt_p = ('p' .in. rep_opt_str) > 0; ldsa 61 rep_opt = rep_opt_c ! rep_opt_g ! rep_opt_p; ldsa 62 if rep_opt then ldsa 63 file repfile access=put,title='', linesize=80; ldsa 64 end if; ldsa 65 ..rep 241 call getipp(ncfopt, 'ncf=1/0'); 242 .+s66. $ set ncfopt=0 as default for bootstrap from 243 $ s66 to s10. dso 102 $ disable ncf by default if bootstrapping from s66. vax 192 if targetmachine=m10 ! targetmachine=m32 vax 193 ! targetmachine=m40 then dso 104 call getipp(ncfopt, 'ncf=0/1'); end if; 245 ..s66 246 call getipp(debuglevel, 'mlev=1/2'); 247 call getspp(help, 'help=/es'); 248 if ('0' .in. help) help = ''; $ if '0' anywhere, no options used 249 if (slen help) debuglevel = 2; $ set debug level 250 gtrentrfg = ('e' .in. help) ^= 0; $ set global debug flags 251 gtrstorfg = ('s' .in. help) ^= 0; 252 gtrflowfg = ('f' .in. help) ^= 0; 253 gchinxfg = ('c' .in. help) ^= 0; 254 255 meal 14 $ if trace entry in effect, arguments to procedure will be meal 15 $ listed if value of trentrargs nonzero; otherwise, only meal 16 $ procedure name will be listed. meal 17 call getipp(trentrargs,'meal=1/0'); meal 18 if (trentrargs>1) trentrargs = 1; 256 257 size sl(ps); $ length of iorts 258 sl = slen iorts; 259 do i = 1 to ionamesptr; 260 if sl then $ non-null trailer, append it 261 slen ionames(i) = 4+sl; $ adjust length 262 .s. 5, sl, ionames(i) = iorts; $ append trailer 263 else $ null trailer, adjust length to 4 264 slen ionames(i) = 4; 265 end if; 266 end do i; 267 268 sl = slen dbgts; 269 do i = 1 to numdebugnames; 270 if sl then $ non-null trailer string, append it 271 slen debugnames(i) = 4+sl; $ adjust length 272 .s. 5, sl, debugnames(i) = dbgts; $ append trailer 273 else $ null trailer, adjust length 274 slen debugnames(i) = 4; 275 end if; 276 end do i; 277 call getipp(lcs_opt, 'lcs=1/0'); $ list compilation statistics. 278 call getipp(lcp_opt, 'lcp=1/0'); $ list compilation parameters. utse 14 .+s32u. $ minimal listing by default for unix. ldsb 27 call getipp(lcp_opt, 'lcp=0/1'); ldsb 28 call getipp(lcs_opt, 'lcs=0/1'); utse 15 ..s32u utse 16 .+s47. $ minimal listing by default for unix. utse 17 call getipp(lcp_opt, 'lcp=0/1'); utse 18 call getipp(lcs_opt, 'lcs=0/1'); utse 19 ..s47 279 dsv 19 $ get actual parameters specified. dsv 20 call getapp(appstr, getapp_len); dsv 21 dss 45 .+s10 call getipp(cis_opt, 'cis=0/18'); dss 46 .+s32 call getipp(cis_opt, 'cis=0/30'); dss 47 .+s37 call getipp(cis_opt, 'cis=0/24'); utsa 224 .+s47 call getipp(cis_opt, 'cis=0/24'); dss 48 .+s66 call getipp(cis_opt, 'cis=0/17'); 280 call ltitlr(compilerlevel); 281 call stitlr(0, 'little compilation - parse phase.'); ldsc 11 if (lcp_opt=0) go to parmslisted; 283 $ remaining code lists compilation parameters. 284 285 call stitlr(1, 'parameters for this parse.'); 286 dsv 22 if .len. appstr then $ if any explicitly specified. dsv 23 textl(appstr) endl endl dsv 24 end if; dsv 25 287 textl('host machine = ') textl(machinename(hostmachine)) 288 textl('. target machine: tm = ') 289 textl(machinename(targetmachine)) 290 textl('.') endl 291 292 textl('target machine parameters: tmp = ') 293 textl(tmvarlabel) 294 endl 295 296 textl('parse error limit: pel =') intlp(pelvalue, 3) 297 textl('. asm voa dump: ad =') intlp(asmvoadump, 2) 298 textl('.') endl 299 300 textl('globals in start: gs =') intlp(gsopt, 2) 301 textl('. default access: da =') intlp(daopt, 2) 302 textl('.') endl 303 304 if slen help then $ output initial debug options 305 textl('initial debug options: help =') 306 textl(help) textl('. ') 307 end if; 308 309 textl('monitor level: mlev =') intlp(debuglevel, 2) meal 19 textl('. monitor entry arg list: meal=') intlp(trentrargs, 2) meal 20 textl('.') endl 311 312 textl('list statistics: lcs =') intlp(lcs_opt,2) 313 textl('. fold negative constants: ncf =') intlp(ncfopt, 2) 314 textl('.') endl 315 316 textl('voa file: voa = ') textl(voafilename) 317 textl('. suppress first procedure: sfp =') intlp(sfp_opt, 2) 318 textl('.') endl 319 textl('lexical cross reference list: lcr =') 320 intlp(crossrefoption,2) 321 textl('. reference file: rf = ') textl(crfileparm) 322 textl('.') endl 323 324 textl('list procedure directory: pdir =') intlp(proclist, 2) dss 49 textl('. check index size: cis =') intlp(cis_opt,3) 325 textl('.') endl ldse 15 if expire then $ only list if expire specified. ldse 16 textl('expire: expire = ') intl(expire) textl('.') endl ldse 17 end if; 326 endl utsa 225 .+s37. utsa 226 textl('ebcdic to ascii: ebcasc = ') intl(ebcascoption) textl('.') utsa 227 endl utsa 228 ..s37 327 endl 328 ldsc 12 /parmslisted/ 329 call stitlr(1, 'program listing.'); $ set subtitle 330 331 call ptdata; call purge; $ initialize. 332 333 end subr genini; 1 .=member ptdata 2 subr ptdata; $ data for parse table (pt) 3 nameset pt; 4 size pt(32); 5 dims pt(ptmax); 6 end nameset; 7 data pt = 8 $ member syntab 9 4b'001c 1295', 4b'04a5 0895', 4b'0905 0975', 4b'0b75 0b95', $ 1 10 4b'0c55 0d85', 4b'0eb5 0015', 4b'1155 1195', 4b'11e5 0bc5', $ 2 11 4b'01a5 01f5', 4b'0335 0155', 4b'005b 0011', 4b'0016 04f3', $ 3 12 4b'0245 000b', 4b'0011 0016', 4b'0583 0245', 4b'001b 0011', $ 4 13 4b'0016 03a3', 4b'0245 002b', 4b'0011 0437', 4b'0305 0016', $ 5 14 4b'0593 0459', 4b'0447 0173', 4b'003b 0011', 4b'2a55 004b', $ 6 15 4b'0011 2a55', 4b'0016 0143', 4b'0437 0405', 4b'2bca 0113', $ 7 16 4b'0447 0123', 4b'001b 0021', 4b'0357 0133', 4b'0015 01cb', $ 8 17 4b'0031 0357', 4b'0133 0015', 4b'0457 0002', 4b'0016 04e3', $ 9 18 4b'0002 001b', 4b'0041 2a8a', 4b'04a3 0477', 4b'0535 002b', $ 10 19 4b'0041 0015', 4b'0197 0585', 4b'00ab 0041', 4b'2a55 0187', $ 11 20 4b'05d5 00bb', 4b'0041 2a55', 4b'0177 0705', 4b'0207 0423', $ 12 21 4b'0016 0433', 4b'0437 0775', 4b'2a8a 0403', 4b'0447 0413', $ 13 22 4b'00d6 07a5', 4b'00a7 07a5', 4b'009b 0041', 4b'0015 003b', $ 14 23 4b'0041 12ca', 4b'0103 004b', 4b'0041 2a55', 4b'006b 0041', $ 15 24 4b'2a55 003b', 4b'0041 0127', 4b'03c3 2bca', 4b'03e3 0207', $ 16 25 4b'03d3 2bca', 4b'03f3 003b', 4b'0021 004b', 4b'0041 0002', $ 17 26 4b'001b 0051', 4b'2a8a 0643', 4b'002b 0051', 4b'2a55 001b', $ 18 27 4b'0061 2a8a', 4b'05b3 002b', 4b'0061 2a55', 4b'001b 0071', $ 19 28 4b'0016 02f3', 4b'02e7 02c3', 4b'2a8a 02d3', 4b'0207 02b3', $ 20 29 4b'2a8a 02e3', 4b'0487 0a85', 4b'0aba 0303', 4b'2a55 002b', $ 21 30 4b'0071 2a55', 4b'0337 0b25', 4b'2a8a 0002', 4b'003b 0071', $ 22 31 4b'0002 2a8a', 4b'0002 004b', 4b'0071 0002', 4b'0081 2a55', $ 23 32 4b'005b 0041', 4b'0015 007b', 4b'0041 2a8a', 4b'0323 0477', $ 24 33 4b'0313 008b', 4b'0041 0015', 4b'0c9a 0563', 4b'0d39 2a55', $ 25 34 4b'0016 0002', 4b'0437 0553', 4b'2bca 0543', 4b'0447 0573', $ 26 35 4b'0091 0002', 4b'0457 0002', 4b'0c9a 0563', 4b'0002 0dca', $ 27 36 4b'0293 0e69', 4b'2a55 0016', 4b'0002 0437', 4b'0283 2bca', $ 28 37 4b'0273 0447', 4b'02a3 00a1', 4b'0002 0457', 4b'0002 0dca', $ 29 38 4b'0293 0002', 4b'0016 0223', 4b'0437 0f65', 4b'2bca 0233', $ 30 39 4b'0447 0243', 4b'001b 00b1', 4b'0f95 002b', 4b'00b1 0f95', $ 31 40 4b'02e7 0203', 4b'103a 0213', 4b'1109 004b', 4b'00b1 0467', $ 32 41 4b'2a55 0eb5', 4b'2b7a 0002', 4b'0437 10e5', 4b'2bca 0253', $ 33 42 4b'0447 0263', 4b'003b 00b1', 4b'0002 0088', 4b'0002 0457', $ 34 43 4b'0002 103a', 4b'0333 0002', 4b'0016 04d3', 4b'00c1 2a55', $ 35 44 4b'0016 0183', 4b'0459 00d1', 4b'2a55 0016', 4b'0523 00e1', $ 36 45 4b'1239 2a55', 4b'0457 0002', 4b'0016 0523', 4b'00e1 0002', $ 37 46 4b'12ca 0103', 4b'2a55 002c', 4b'1b95 1455', 4b'15a5 16d5', $ 38 47 4b'1705 18f5', 4b'1935 1965', 4b'1985 19a5', 4b'19c5 1d05', $ 39 48 4b'1d75 2435', 4b'25a5 1b35', 4b'1de5 1e75', 4b'25f5 2615', $ 40 49 4b'26d5 26f5', 4b'2875 28e5', 4b'0016 01c3', 4b'0437 1515', $ 41 50 4b'2a8a 01d3', 4b'1559 0447', 4b'01e3 002b', 4b'00f1 0002', $ 42 51 4b'0088 001b', 4b'00f1 0002', 4b'0457 0002', 4b'2a8a 0333', $ 43 52 4b'0002 0437', 4b'1615 2a8a', 4b'0443 0447', 4b'0453 1645', $ 44 53 4b'0016 0483', 4b'1645 0437', 4b'0473 0016', 4b'0463 0459', $ 45 54 4b'0447 0493', 4b'0101 0002', 4b'0111 0088', 4b'0002 0207', $ 46 55 4b'0423 0016', 4b'0433 0437', 4b'1855 2a8a', 4b'0403 0447', $ 47 56 4b'0413 0127', 4b'1895 2bca', 4b'03e3 0207', 4b'03d3 2bca', $ 48 57 4b'03f3 003b', 4b'0021 0002', 4b'0088 01db', 4b'0031 0002', $ 49 58 4b'00d8 0121', 4b'0088 002b', 4b'0021 0002', 4b'000b 0131', $ 50 59 4b'0088 0002', 4b'0141 0088', 4b'0002 0168', 4b'1a65 01e8', $ 51 60 4b'1a65 0268', 4b'1a65 02e8', 4b'2a8a 0673', 4b'0457 0663', $ 52 61 4b'1bda 05e3', 4b'1caa 05c3', 4b'0002 2a8a', 4b'0673 0457', $ 53 62 4b'0663 2a8a', 4b'0673 0457', 4b'0663 1bda', 4b'05e3 1caa', $ 54 63 4b'05c3 0002', 4b'0368 1bda', 4b'05e3 1caa', 4b'05c3 0002', $ 55 64 4b'1bda 00e3', 4b'00e8 1ca5', 4b'0016 0002', 4b'0437 1c75', $ 56 65 4b'2a8a 0633', 4b'0447 0623', 4b'00c8 0002', 4b'0088 0048', $ 57 66 4b'0002 02e7', 4b'0002 2a8a', 4b'05d3 0151', 4b'0002 001b', $ 58 67 4b'0161 1f0a', 4b'0002 20ba', 4b'03b3 0002', 4b'002b 0161', $ 59 68 4b'1f0a 0002', 4b'20ba 0503', 4b'0002 2a8a', 4b'0513 00bb', $ 60 69 4b'0161 206a', 4b'0073 2069', 4b'0171 0002', 4b'2a8a 0653', $ 61 70 4b'00cb 0161', 4b'206a 0073', 4b'2069 0171', 4b'0002 2a8a', $ 62 71 4b'1f55 003b', 4b'0161 0002', 4b'0088 004b', 4b'0161 0002', $ 63 72 4b'2a8a 0002', 4b'0207 2025', 4b'2a8a 05f3', 4b'002b 0181', $ 64 73 4b'0002 0088', 4b'001b 0181', 4b'0002 0457', 4b'0002 1f9a', $ 65 74 4b'0073 0002', 4b'006b 0161', 4b'211a 0002', 4b'2119 0002', $ 66 75 4b'220a 2145', 4b'0002 21ba', 4b'0002 21b9', 4b'231a 0063', $ 67 76 4b'0171 0002', 4b'0467 0002', 4b'1f9a 0073', 4b'0002 0457', $ 68 77 4b'0002 0036', 4b'0043 0437', 4b'22d5 2a8a', 4b'0093 0447', $ 69 78 4b'00c3 001b', 4b'0191 0002', 4b'0088 000b', 4b'0191 0002', $ 70 79 4b'0457 0002', 4b'0046 0053', 4b'0437 23f5', 4b'2a8a 0093', $ 71 80 4b'1559 0447', 4b'00c3 001b', 4b'01a1 0002', 4b'0088 000b', $ 72 81 4b'01a1 0002', 4b'2a8a 0343', 4b'007b 0161', 4b'24ca 00a3', $ 73 82 4b'2559 01b1', 4b'0002 0056', 4b'0002 02e7', 4b'01a3 2a8a', $ 74 83 4b'01b3 008b', 4b'0161 0002', 4b'0457 0002', 4b'24ca 00a3', $ 75 84 4b'0002 2a8a', 4b'0533 009b', 4b'0161 0002', 4b'00b8 2635', $ 76 85 4b'0138 2635', 4b'0497 01f3', 4b'0016 26a5', 4b'0459 01c1', $ 77 86 4b'0002 0088', 4b'01d1 0002', 4b'00b8 2715', 4b'0038 2715', $ 78 87 4b'27ba 05a3', 4b'0016 2785', 4b'0459 01e1', 4b'0002 0088', $ 79 88 4b'01f1 0002', 4b'04a7 27f5', 4b'00a8 0002', 4b'04b7 2835', $ 80 89 4b'01a8 0002', 4b'04c7 0002', 4b'02a8 0002', 4b'000b 0201', $ 81 90 4b'2a8a 0193', 4b'001b 0201', 4b'0002 0211', 4b'299a 00b3', $ 82 91 4b'2949 0221', 4b'0002 0457', 4b'0002 299a', 4b'00b3 0002', $ 83 92 4b'05c7 2a15', 4b'02e7 04b3', 4b'2a8a 04c3', 4b'0231 0002', $ 84 93 4b'0076 0002', 4b'0241 0002', 4b'00a7 00d3', 4b'0015 0096', $ 85 94 4b'2b05 00a6', 4b'2c15 000e', 4b'2dc9 000f', 4b'0002 000e', $ 86 95 4b'2d0a 2b55', 4b'000f 0002', 4b'000f 0002', 4b'2a8a 0002', $ 87 96 4b'0058 0121', 4b'0002 2a8a', 4b'0002 00d8', 4b'0121 0002', $ 88 97 4b'2a8a 0603', 4b'1559 0447', 4b'0613 003b', 4b'00f1 00a6', $ 89 98 4b'2ce5 000e', 4b'2dc9 000f', 4b'0002 0251', 4b'0002 2e2a', $ 90 99 4b'2d45 2dc9', 4b'0002 00f6', 4b'0002 2e2a', 4b'00f3 2dc9', $ 91 100 4b'002d 2dc9', 4b'0002 00e6', 4b'0002 2d0a', 4b'0083 001d', $ 92 101 4b'0002 00b6', 4b'0002 00c6', 4b'0002 2fa5', 4b'3025 3085', $ 93 102 4b'30e5 3145', 4b'3295 2ed5', 4b'0437 0383', 4b'2a8a 0363', $ 94 103 4b'0457 0353', 4b'0066 0373', 4b'0447 0393', 4b'00ab 0161', $ 95 104 4b'0002 2a8a', 4b'0603 1559', 4b'0447 0613', 4b'003b 00f1', $ 96 105 4b'0002 0128', 4b'31ea 0002', 4b'01ab 0261', 4b'0002 01a8', $ 97 106 4b'31ea 0002', 4b'025b 0261', 4b'0002 0228', 4b'31ea 0002', $ 98 107 4b'026b 0261', 4b'0002 02a8', 4b'2a8a 0033', 4b'0457 0023', $ 99 108 4b'2e2a 0013', 4b'001b 0261', 4b'0002 2a8a', 4b'0033 0457', $ 100 109 4b'0023 2a8a', 4b'0033 0457', 4b'0023 2e2a', 4b'0013 0002', $ 101 110 4b'2a8a 0153', 4b'0447 0163', 4b'0002 0271', 4b'3305 0086', $ 102 111 4b'2a55 3305' ; $ 103 112 $ end member syntab 113 114 $ macros for packed format of parse table. 115 +* opt_op = .f. 1, 4, ** $ operation. 116 +* opt_parm = .f. 5, 12, ** $ parameter. 117 118 $ macros for unpacked parse table format. vax 194 .+s32. vax 195 +* pt_op = .f. 3, 4, ** vax 196 +* pt_parm = .f. 17, 16, ** vax 197 ..s32 119 .+s37. 120 +* pt_op = .f. 3, 4, ** 121 +* pt_parm = .f. 17, 16, ** 122 ..s37 utsa 229 .+s47. utsa 230 +* pt_op = .f. 3, 4, ** utsa 231 +* pt_parm = .f. 17, 16, ** utsa 232 ..s47 123 .+s66. 124 +* pt_op = .f. 1, 4, ** 125 +* pt_parm = .f. 5, 17, ** 126 ..s66 127 .+s10. 128 +* pt_op = .f. 1, 18, ** 129 +* pt_parm = .f. 19, 18, ** 130 ..s10 131 132 133 size i(ps); $ loop index. 134 135 $ now unpack the parse table. 136 do i = ptmax/2 to 1 by -1; $ unpack each pair. 137 pt_op pt(i*2) = opt_op (.f. 1, 16, pt(i)); 138 pt_parm pt(i*2) = opt_parm (.f. 1, 16, pt(i)); 139 pt_op pt(i*2-1) = opt_op (.f. 17, 16, pt(i)); 140 pt_parm pt(i*2-1) = opt_parm (.f. 17, 16, pt(i)); 141 end do; 142 143 call purge; $ initialize tables. 144 145 macdrop(opt_op) macdrop(opt_parm) 146 end subr ptdata; 1 .=member parse 2 subr parse; $ parse source text 3 access pt; 4 size parseparm(ps); $ parse item operand 5 size parsenow(ps); $ position in parse table 6 size parseok(1); $ parse 'ok' flag. 7 size pi(ps); 8 9 $ opcodes of the parse machine. 10 11 +* po_act = 01 ** $ perform action. 12 +* po_bak = 02 ** $ restore parse. 13 +* po_err = 03 ** $ report error if failure. 14 +* po_jif = 04 ** $ jump if failure. 15 +* po_jmp = 05 ** $ jump. 16 +* po_lex = 06 ** $ test for token of given lexical type. 17 +* po_lit = 07 ** $ test for literal. 18 +* po_set = 08 ** $ set parse register. 19 +* po_sev = 09 ** $ seek zero or more instances of subpart. 20 +* po_sub = 10 ** $ seek subpart. 21 +* po_op1 = 11 ** $ user operation 1. 22 +* po_op2 = 12 ** $ user operation 2. 23 +* po_op3 = 13 ** $ user operation 3. 24 +* po_op4 = 14 ** $ user operation 4. 25 +* po_op5 = 15 ** $ user operation 5. 26 27 $ lexical type encoding used for po_lex operation parm field. 28 29 +* lexc_name = 01 ** $ name. 30 +* lexc_contok = 02 ** $ constant. 31 +* lexc_cfi = 03 ** $ control format. 32 +* lexc_dfi = 04 ** $ data format code. 33 +* lexc_filekwd = 05 ** $ attribute name in file statement. 34 +* lexc_statwd = 06 ** $ valid filestat option. 35 +* lexc_dbugtok = 07 ** $ 36 +* lexc_ertok = 08 ** 37 +* lexc_exprtok1 = 09 ** $ 38 +* lexc_exprtok2 = 10 ** $ 39 +* lexc_termtok1 = 11 ** $ 40 +* lexc_termtok2 = 12 ** $ 41 +* lexc_cargstk = 13 ** 42 +* lexc_binop = 14 ** 43 +* lexc_unop = 15 ** 44 45 +* lexc_max = 15 ** $ largest lexc code. 46 47 48 $ array pca (p-arse c_ontrol a-rray) contains information to 49 $ control the parse, in particular to effect recursion within 50 $ the parse. 51 52 +* pcamax = 70 ** $ dims of -pca- 53 54 size pcaptr(ps); data pcaptr = 0; 55 size pca(ws); dims pca(pcamax); $ parse recursion stack 56 57 .+s66. 58 +* pcaret(i) = .f. 1, 10,pca(i) ** $ return field in pca 59 +* pcaparm(i) = .f. 11, 10,pca(i) ** 60 +* pcatot(i) = .f. 21, 10,pca(i) ** 61 ..s66 62 .+s10. 63 +* pcaret(i) = .f. 1, 10,pca(i) ** $ return field in pca 64 +* pcaparm(i) = .f. 11, 10,pca(i) ** 65 +* pcatot(i) = .f. 21, 10,pca(i) ** 66 ..s10 vax 198 .+s32. vax 199 +* pcatot(i) = .f. 1, 16, pca(i) ** vax 200 +* pcaparm(i) = .f. 17, 16, pca(i) ** vax 201 vax 202 size pcaret(ps); dims pcaret(pcamax); vax 203 ..s32 67 .+s37. 68 +* pcatot(i) = .f. 1, 16, pca(i) ** 69 +* pcaparm(i) = .f. 17, 16, pca(i) ** 70 71 size pcaret(ps); dims pcaret(pcamax); 72 ..s37 utsa 233 .+s47. utsa 234 +* pcatot(i) = .f. 1, 16, pca(i) ** utsa 235 +* pcaparm(i) = .f. 17, 16, pca(i) ** utsa 236 utsa 237 size pcaret(ps); dims pcaret(pcamax); utsa 238 ..s47 73 74 $ the operator stack opstack is used for precedence parse of 75 $ expressions. each entry consists of level and type. for 76 $ efficiency opstack is realized as two arrays rather than 77 $ fields of a entries in a single array. 78 79 +* opstackmax = 30 ** $ dimension of opstack - maximum allowed 80 size oplev(ps); dims oplev(opstackmax); $ operator level 81 size optyp(ps); dims optyp(opstackmax); $ operator type 82 83 size t(ps); $ temporary. 84 size lastlt(ps); $ lexical type of prior token. 85 size savetok(ps); $ saved token. 86 size oper(ps); $ operation code. 87 88 $ begin with first word in parse table 89 parsenow = 1; keeptok = no; go to parseon; 90 91 /parsenext/ $ advance to next parse op. 92 parsenow = parsenow + 1; 93 94 /parseon/ $ process parse operation. 95 96 parseparm = pt_parm pt(parsenow); 97 98 .+pt. 99 if pt_op pt(parsenow) = 0 then 100 textl(' op zero err') tintl('parsenow',parsenow) endl 101 call genexit; $ exit 102 end if; 103 104 if parsetrace then 105 tintl('parseok',parseok); 106 tintl('parsenow ', parsenow) 107 tintl('parseop', pt_op pt(parsenow)) 108 textl(' ') textl((.s. (pt_op pt(parsenow)-1)*3+1, 3, 109 'actbakerrjifjmplexlitsetsevsubop1op2op3op4op5')) 110 tintl(' param', parseparm) 111 endl 112 end if; 113 114 ..pt 115 go to po(pt_op pt(parsenow)) in 1 to po_op5; 116 117 118 /po(po_lit)/ $ match literal given by parameter value 119 120 if (keeptok=no) call nextok; $ get next token. 121 if toklc = parseparm then $ success. 122 parseok = yes; keeptok = no; $ set flags. 123 parsenow = parsenow + 2; $ set next operation. 124 go to parseon; $ continue parse. 125 else $ failure. 126 parseok = no; $ set failure status. 127 go to parsenext; $ go to failure point. 128 end if; 129 130 /po(po_lex)/ $ find token of given lexical type 131 132 if (keeptok=no) call nextok; $ get next token. 133 134 go to lexc(parseparm) in 1 to lexc_max; 135 136 /lexc(lexc_name)/ $ seek name. 137 138 if (toklt = nametok) go to found; 139 go to notfound; 140 141 /lexc(lexc_contok)/ $ seek constant. 142 143 if(toklt >= constok) go to found; 144 go to notfound; 145 146 /lexc(lexc_cfi)/ /lexc(lexc_dfi)/ /lexc(lexc_filekwd)/ 147 /lexc(lexc_dbugtok)/ /lexc(lexc_statwd)/ /lexc(lexc_ertok)/ 148 $ the above lexical types have rather long routines to see if 149 $ they are 'found' or not and they rarely occur. so we will cal 150 $ a routine to check for them. 151 call pfind(t, parseparm); $ call routine. 152 if t = 0 then $ not found. 153 go to notfound; 154 elseif t = 1 then $ this is special find. 155 go to found1; $ dont hash in. 156 else $ found token. 157 go to found; $ found token. 158 end if; 159 160 /lexc(lexc_exprtok1)/ $ seek one token expression. 161 162 if (toklt^=nametok & toklt subpart. 176 end if; 177 178 $ see if binary op which continues expressin. 179 if littabl(3,toklc) then $ if binary op, expression continu 180 parsenow = parsenow + 2; 181 go to po(po_op4); $ next is xbeg. 182 end if; 183 184 $ name or constant is one token expression. 185 $ complete expr search successfully. 186 $ do a bak now. 187 pcaptr = pcaptr - 1; $ pop -pca-. 188 .+pt if (pcaptr<0) call ermey(2); $ fatal error. 189 parsenow = pcaret(pcaptr+1) + 2; $ set return point. 190 go to parseon; $ continue parse. 191 192 /lexc(lexc_termtok1)/ $ here to start term. 193 194 /* assumed order of parse ops is as follows. 195 0 lex termtok1 196 1 bak 197 2 lex termtok2 198 3 bak 199 4 jmp termlp (after seeing name, left parenthesis). 200 5 jmp fexp if .f. extractor. 201 6 jmp eexp if .e. extractor. 202 7 jmp sexp if .s. extractor. 203 8 jmp checp if .ch. extractor. 204 9 jmp pexp if left parenthesis. 205 10 jmp termfs if filestat. 206 207 the literal code is relative offset in parse table. 208 209 */ 210 211 lastlt = toklt; $ save lexical type. 212 213 if (toklt>=constok) go to found; $ constant is term. 214 215 if toklc then $ if literal, see if can branch forward. 216 t = littabl(7, toklc); 217 if t then 218 parseok = yes; keeptok = no; 219 parsenow = pt_parm pt(parsenow + t); 220 go to parseon; 221 end if; 222 end if; 223 224 $ if name, accept. 225 if (toklt=nametok) go to found; 226 227 parseok = no; 228 $ here we do a -bak-. 229 pcaptr = pcaptr - 1; $ pop -pca-. 230 .+pt if (pcaptr < 0) call ermey(2); $ underflow. 231 parsenow = pcaret(pcaptr+1) + 1; $ get return point. 232 go to parseon; $ continue parse. 233 234 /lexc(lexc_termtok2)/ 235 236 $ here after term starts with name or constant. 237 $ if term began with constant, it is term. 238 $ here after term starts with name. if current token is 239 $ left parenthesis, return to grammar to parse. otherwise 240 $ name is term. 241 242 if toklc = lc_lparen & lastlt = nametok then 243 parseok = yes; keeptok = no; 244 parsenow = pt_parm pt(parsenow+2); $ jmp to termlp label 245 else $ accept 246 parseok = yes; 247 pcaptr = pcaptr - 1; $ pop -pca-. 248 .+pt if (pcaptr < 0) call ermey(2); $ underflow. 249 parsenow = pcaret(pcaptr+1) + 2; $ get next operation. 250 end if; 251 252 go to parseon; $ continue parse. 253 254 /lexc(lexc_cargstk)/ $ want constant on top of -arglist-. 255 parseok = hascon ha(arglist(argptr-1)); 256 parsenow = parsenow + parseok + 1; $ set next parse op. 257 go to parseon; $ continue. 258 259 /lexc(lexc_unop)/ $ want valid unary operator. 260 if (toklc = 0) go to opret; $ if not literal. 261 t = littabl(4, toklc); $ get unary operator level. 262 if t = 0 then $ not operator. 263 /opret/ $ failure return point. 264 pcaptr = pcaptr-1; $ failure is -b. 265 .+pt if (pcaptr<0) call ermey(2); $ error - underflow. 266 parsenow = pcaret(pcaptr+1) + 1; $ go to failure point. 267 parseok = (parseparm = lexc_binop); $ binop is bak from sev. 268 go to parseon; $ continue parse. 269 end if; 270 271 oper = littabl(6, toklc); $ get operator number. 272 keeptok = no; $ accept token. 273 go to setoper; $ go stack operator. 274 275 /lexc(lexc_binop)/ $ want binary operator. 276 $ now see if this was either not a binary operator or 277 $ the operator on the stack has a higher precedence. if so, 278 $ say 'not found'. 279 if (toklc = 0) go to opret; $ no literal code. 280 t = littabl(3, toklc); $ get binary operator level. 281 if (oplev(opstackp) >= t) go to opret; $ fail if so. 282 oper = littabl(5, toklc); $ get operator code. 283 keeptok = no; $ accept token. 284 285 $ now check if this is a two-token operator. 286 if toklc = lc_orsym then $ !! is .cc. 287 call nextok; $ get next token. 288 if toklc = lc_orsym then $ it is. 289 oper = op_ccat; $ set new operation code. 290 keeptok = no; $ accept operator. 291 end if; 292 293 elseif t = 4 then $ this may be <=, >=, ^=. 294 savetok = toklc; $ save last token. 295 call nextok; $ get next token. 296 keeptok = (toklc ^= lc_eqsym); $ accept equal sign only. 297 $ now determine which operator this is. 298 if savetok = lc_ltsym then 299 if (keeptok = no) oper = op_le; $ this was <=. 300 elseif savetok = lc_gtsym then 301 if (keeptok = no) oper = op_ge; $ this was >=. 302 elseif savetok = lc_notsym then 303 if (keeptok) call ermes(35); $ ^ with no = 304 else $ this is not a multiple operator. 305 keeptok = yes; $ must keep token. 306 end if; 307 end if; 308 309 /setoper/ $ stack operator. 310 countup(opstackp, opstackmax, 'opstack'); 311 optyp(opstackp) = oper; $ set operation type. 312 oplev(opstackp) = t; $ set level. 313 parseok = yes; $ show success. 314 parsenow = parsenow + 2; go to parseon; $ continue. 315 316 317 /found/ $ search successful, hash in token. 318 if toklt = nametok then $ if name. 319 insnchars = toklen; 320 .+movw_env. 321 call 7nmovw$li(insnarg, tokara, tokwords); $ move words. 322 .-movw_env. 323 do t = 1 to tokwords; 324 insnarg(t) = tokara(t); 325 end do; 326 ..movw_env 327 328 call insname(t); 329 if assertfg then $ in assertion - push ptr on assert st 330 countup(assertstp, assertdim, 'assertst'); 331 assertst(assertstp) = t; 332 end if; 333 334 else $ if constant. 335 cclt = toklt; $ set lexical type 336 $ unpack tokara into array of chars. cca used by cnvcon. 337 .+unpk_env. 338 call 7nunpk$li(cca, 1, tokara, 1, toklen); $ unpack token. 339 .-unpk_env. 340 do t = 1 to toklen; 341 cca(t) = .f. tokarasz+1-cs - cs*mod(t-1, tokarasz/cs), cs, dsr 16 tokara((t-1)/(tokarasz/cs)+1); $ copy character. 343 end do; 344 ..unpk_env 345 346 ccaptr = toklen; 347 call cnvcon; $ convert constant. 348 call inscon(t); $ insert constant. 349 end if; 350 351 $ place hash code on top of arg stack 352 push(t); $ insert on stack. 353 if argptr > argmax - 20 then $ overflow of stack. 354 call ermes(65); call genexit; 355 end if; 356 357 /found1/ $ arrive at this label if do not want token hashed 358 parseok = yes; keeptok = no; 359 parsenow = parsenow + 2; go to parseon; 360 361 /notfound/ 362 parseok = no; 363 go to parsenext; 364 365 /po(po_sev)/ $ seek several instances of subpart. 366 367 $ -pcaret- records where request originated 368 $ set parameters, and go seek indicated object 369 countup(pcaptr,pcamax,'pca'); 370 pcatot(pcaptr) = 0; 371 pcaparm(pcaptr) = parseparm; 372 pcaret(pcaptr) = parsenow; 373 parsenow = parseparm; 374 go to parseon; 375 376 /po(po_sub)/ $ find indicated subpart. 377 378 countup(pcaptr,pcamax,'pca'); 379 pcaparm(pcaptr) = 0; 380 pcaret(pcaptr) = parsenow; 381 parsenow = parseparm; 382 go to parseon; 383 384 / po(po_err) / $ report error if in failure state. 385 386 if (parseok) go to parsenext; 387 388 ermsgno = parseparm; 389 pcaptr = 0; $ since at top level, clear stack 390 parsenow = parseerrloc; 391 go to parseon; 392 393 /po(po_jif)/ $ jump if failure state. 394 395 if (parseok) go to parsenext; 396 397 /po(po_jmp)/ $ branch 398 399 parsenow = parseparm; go to parseon; 400 401 /po(po_bak)/ $ restore parse status, return from search. 402 403 $ restore parser status (effectively recursion control ) 404 $ recover from completion of -find subpart- or 405 $ -find repeated instances- operation 406 407 if pcaparm(pcaptr) = 0 then $ if subpart. 408 pcaptr = pcaptr-1; 409 .+pt if (pcaptr<0) call ermey(2); 410 parsenow = pcaret(pcaptr+1) + 1 + parseok; 411 else $ restore after search for repeated instances 412 if parseok then $ continue search 413 pcatot(pcaptr) = pcatot(pcaptr) + 1; 414 parsenow = pcaparm(pcaptr); 415 else $ part not found, return instance count found 416 pcaptr = pcaptr-1; 417 .+pt if (pcaptr<0) call ermey(2); 418 parsenow = pcaret(pcaptr+1) + 1; 419 arglist(argptr) = pcatot(pcaptr+1); 420 parseok = yes; 421 end if; 422 end if; 423 424 go to parseon; $ continue with parse. 425 426 /po(po_set)/ $ set parse register. 427 428 $ setting parsereg(1) is doing an 'ok' so special-case that. 429 if .f. 1, 3, parseparm = 0 then 430 parseok = yes; $ this is 'ok'. 431 else $ normal register sets. 432 parsereg(1 + (.f. 1, 3, parseparm)) = .f. 4, 9, parseparm; 433 end if; 434 435 go to parsenext; 436 437 /po(po_op1)/ $ op1 saves parseparm in pi. 438 439 pi = parseparm; 440 go to parsenext; 441 442 /po(po_act)/ $ action sequence. 443 444 go to pa(parseparm) in 1 to parseactmax; 445 446 +* pac = go to parsenext ** 447 448 +* pr(i) = parsereg(i) ** 449 $ member synact 450 / pa( 1) / call gensub ( pi ); pac; 451 / pa( 2) / call gengosl ( pi ); pac; 452 / pa( 3) / call gengol ( pi ); pac; 453 / pa( 4) / call genif ( pi ); pac; 454 / pa( 5) / call genwhil ( pi ); pac; 455 / pa( 6) / call genuntl ( pi ); pac; 456 / pa( 7) / call gendo ( pi ); pac; 457 / pa( 8) / call genend; pac; 458 / pa( 9) / call gensiz; pac; 459 / pa( 10) / call gendim; pac; 460 / pa( 11) / call gendat ( pi ); pac; 461 / pa( 12) / call genns; pac; 462 / pa( 13) / call genacc; pac; 463 / pa( 14) / call genreal; pac; 464 / pa( 15) / call gencall ( pi ); pac; 465 / pa( 16) / call gengoby; pac; 466 / pa( 17) / call genret; pac; 467 / pa( 18) / go to checkcexp; 468 / pa( 19) / call gencont ( pi ); pac; 469 / pa( 20) / call genquit; pac; 470 / pa( 21) / call genasin ( pr ( 7 ) , pr ( 5 ) ); pac; 471 / pa( 22) / call geniost ( pi ); pac; 472 / pa( 23) / call geniotr; pac; 473 / pa( 24) / call genioit ( pi ); pac; 474 / pa( 25) / call gencfi ( pi ); pac; 475 / pa( 26) / call gendfi ( pi ); pac; 476 / pa( 27) / call genfile; pac; 477 / pa( 28) / call gentrace ( pr ( 4 ) , 8 ); pac; 478 / pa( 29) / call gentrace ( pr ( 4 ) , 7 ); pac; 479 / pa( 30) / call gentrace ( pr ( 4 ) , pr ( 3 ) + 1 ); pac; 480 / pa( 31) / call gentrace ( pr ( 4 ) , pr ( 3 ) ); pac; 481 / pa( 32) / call gensert ( pi ); pac; 482 / pa( 33) / call gendebug ( 0 , 0 ); pac; 483 / pa( 34) / call gendebug ( 0 , 1 ); pac; 484 / pa( 35) / call gendebug ( 1 , 1 ); pac; 485 / pa( 36) / call gendebug ( dparm , dval ); pac; 486 / pa( 37) / keeptok = 1; pac; 487 / pa( 38) / call genextr ( pi ); pac; 488 / pa( 39) / call ermet; pac; 489 $ end member synact 490 491 /po(po_op2)/ $ get bronlit argument, searches literal. 492 493 $ this action implements the branch on literal feature in the 494 $ grammar. the next token in input is examined. if it has been 495 $ assigned a number in the given class, the grammar table 496 $ pointer, parsenow, is advanced by that number, else the token 497 $ is simply returned and parnsing proceeds with the next item. 498 499 500 parseok = no; $ assume not found. 501 if (keeptok=no) call nextok; $ get next token. 502 if (toklc = 0) go to parsenext; $ normal token. 503 t = littabl(parseparm, toklc); $ if literal. 504 if t then $ will take branch. 505 parseok = yes; keeptok = no; $ show success. 506 parsenow = pt_parm pt(1 + (parsenow+t)); $ set next op. 507 go to parseon; $ continue parse. 508 end if; 509 510 go to parsenext; $ else continue with next. 511 512 /po(po_op3)/ 513 514 $ this action pops opstack and calls arith or marith with 515 $ appropriate parameter 516 517 518 .+pt. 519 if opstackp = 1 then 520 call ermey(6); 521 end if; 522 ..pt 523 524 opstackp = opstackp - 1; 525 t = optyp(opstackp+1); 526 if parseparm = 1 then call arith(t); 527 else call marith(t); end if; 528 go to parsenext; 529 530 /po(po_op4)/ $ stack expression. 531 532 countup(opstackp, opstackmax, 'opstack'); 533 oplev(opstackp) = 0; optyp(opstackp) = 0; 534 go to parsenext; 535 536 537 /po(po_op5)/ $ unstack expression. 538 539 .+pt. 540 if oplev(opstackp) then 541 call ermey(4); 542 end if; 543 544 if opstackp = 0 then 545 call ermey(5); 546 end if; 547 ..pt 548 549 opstackp = opstackp - 1; 550 go to parsenext; 551 552 553 /checkcexp/ $ here to check for expression in constants. 554 555 if parsereg(6) then $ must be safe constant. 556 if (hascon ha(arglist(argptr-1))) go to parsenext; $ ok. 557 else $ want any constant. 558 if var ha(arglist(argptr-1)) then $ is variable or constant. 559 if (const voa(ep ha(arglist(argptr-1)))) go to parsenext; 560 end if; 561 end if; 562 563 call ermes(42); $ give error message 564 arglist(argptr-1) = ha_1; $ reset value 565 566 go to parsenext; 567 568 end subr parse; 1 .=member pfind 2 subr pfind(ret, lexc); $ do find actions for some classes. 3 size ret(ps); $ 0=notfound, 1=found1, 2=found. 4 size lexc(ps); $ lexical class. 5 size keycode(ps); $ function which returns code from string. 6 size i(ps); $ do loop variable. 7 8 go to lexc(lexc) in lexc_cfi to lexc_ertok; 9 10 /lexc(lexc_cfi)/ $ seek control format code. 11 12 if toklt = strtok then 13 iokey = 5; $ global passed to gencfi 14 go to found; $ hash in sds 15 end if; 16 17 if (toklt ^= nametok) go to notfound; 18 if(toklen > keylenmax) go to notfound; 19 call psdstok; 20 iokey = keycode(sdsnamstr, $ control codes follow. 21 '04=x 02=skip 03=page 01=column '); 22 if (iokey) go to found1; 23 go to notfound; 24 25 /lexc(lexc_dfi) / $ seek data format item, process initial -n-. 26 27 if (toklt ^= nametok) go to notfound; 28 if (toklen > 3) go to notfound; 29 $ convert token to sds form, put in iosds. 30 call psdstok; 31 ionameflag = no; 32 if .ch. 1, sdsnamstr = 1rn then $ if -n- type format 33 ionameflag = yes; 34 do i = 2 to toklen; 35 .ch. i-1, sdsnamstr = .ch. i, sdsnamstr; end do; 36 slen sdsnamstr = toklen-1; 37 toklen = toklen - 1; 38 end if; 39 40 iokey = 0; 41 if (toklen=0) go to notfound; 42 iolistmode = no; 43 if .ch. slen sdsnamstr, sdsnamstr = 1rl then $ if list mode 44 iolistmode = yes; 45 slen sdsnamstr = slen sdsnamstr - 1; 46 toklen = toklen - 1; 47 if (toklen = 0) go to notfound; 48 end if; 49 50 iokey = keycode(sdsnamstr, $ string gives format codes 51 '01=a 02=b 03=e 04=f 05=i 06=r '); 52 if (iokey) go to found1; go to notfound; 53 54 /lexc(lexc_filekwd)/ 55 56 $ seek valid attribute for 'file' statement. 57 $ convert token into sds format in sdsnamstr. 58 if (toklt^=nametok) go to notfound; 59 if (toklen>keylenmax) go to notfound; $ if token too long. 60 call psdstok; 61 iokey = keycode(sdsnamstr, $ next line gives attribute codes 62 '01=title 02=access 03=linesize '); 63 if (iokey) go to found1; go to notfound; 64 65 /lexc(lexc_dbugtok)/ 66 67 $ seek parameter for 'debug' statement 68 if (toklt ^= nametok ! toklen > keylenmax) go to notfound; 69 call psdstok; 70 dparm = keycode(sdsnamstr, $ string gives parameters 71 '02=nolimit 04=nobyte 05=byte 06=noflow 07=flow 08=nostores 72 09=stores 10=noentry 11=entry '); 73 dval = .f. 1, 1, dparm; dparm = .f. 2, ps, dparm; $ split 74 if (dparm) go to found1; go to notfound; 75 76 /lexc(lexc_statwd)/ 77 78 $ seek 'filestat' attribute 79 if (toklt^=nametok ! toklen>keylenmax) go to notfound; 80 call psdstok; 81 iokey = keycode(sdsnamstr, $ string gives filestat codes. 82 '01=column 02=end 03=error 03=err 04=ignore 05=access 06=linesize ' 83 !! '07=stream '); 84 if (iokey) go to found1; go to notfound; 85 86 /lexc(lexc_ertok)/ $ skip to end of statement on error. 87 $ this lexical class is used to recover from an error. 88 $ it will skip forward to next semicolon unless the error 89 $ occured in an expression in an -if- in which case it 90 $ will scan for either a 'then' or a semicolon. 91 if cstype csa(csaptr) = cstype_if then $ last opener was -if-. 92 $ if this was simple -if-, end simple statement. 93 if csiftype csa(csaptr) = csiftype_sif then 94 call genif(4); $ end the simple statement. 95 elseif csiftype csa(csaptr) = 0 then $ in expression. 96 if toklc = lc_then then $ found 'then'. 97 push(ha_1); call genif(2); $ dummy expression. 98 go to notfound; $ terminates search for token. 99 elseif toklc = lc_semicolon then $ this was simple -if-. 100 push(ha_1); call genif(3); call genif(4); $ null sta 101 go to notfound; $ terminates search for token. 102 end if; 103 end if; 104 end if; 105 106 $ if normal case, only semicolon ends. 107 if (toklc = lc_semicolon) go to notfound; $ terminates search. 108 go to found1; $ else continue search. 109 110 111 /found/ ret = 2; return; 112 /found1/ ret = 1; return; 113 /notfound/ ret = 0; return; 114 115 end subr pfind; 1 .=member psdstok 2 subr psdstok; $ convert token into sds form 3 $ convert token into sds form, put result in -sdsnamstr-. 4 $ (this auxiliary routine called from -pfind-.) 5 size i(ps); $ do loop index 6 slen sdsnamstr = toklen; 7 do i = 1 to tokwords; 8 .f. nameorg - i*ws, ws, sdsnamstr = tokara(i); 9 end do; 10 11 end subr psdstok; 1 .=member keycode 2 fnct keycode(key, codes); $ seek -key- in -codes-, get value. 3 $ -key- and -codes- are strings. entries of -codes- have the 4 $ form 'nn=str' where nn is integer and str is code. if 5 $ -key- corresponds to one of the entries, return numeric 6 $ value of assigned code nn; otherwise return 0. 7 size key(sds(keylenmax)); $ key for which code desired 8 size codes(sds(120)); $ string of codes 9 size s(namsz); $ delimited form of key 10 size keycode(ps); $ function vlaue. 11 size i(ps); $ do loop index for conversion. 12 13 keycode = 0; $ assume key not present. 14 if (slen key > keylenmax) return; $ too large, cannot be present 15 sorg s = nameorg; $ set string origin field. 16 slen s = slen key+2; 17 .ch. 1, s = 1r=; .ch. slen s, s = 1r ; $ enter delimiters. 18 do i = 1 to slen key; 19 .ch. i+1, s = .ch. i, key; end do; 20 i = s .in. codes; 21 if (i=0) return; 22 keycode = digofchar((.ch.i-2,codes))*10 23 + digofchar((.ch.i-1,codes)); 24 25 end fnct keycode; 1 .=member gtoflo 2 subr gtoflo(ipoin, lim, iword); $ increment counter 3 $ increment -ipoin-, fatal error if -ipoin- >= -lim-. 4 size ipoin(ps); 5 size lim(ps); 6 size iword(ws+1); $ name of array which overflowed 7 8 terml(yes); $ write this to terminal file mgfc 14 .+s10 error_s10; $ give s10 error character. 9 textl(error_notice) textl('array ') textl(iword) 10 textl(' overflowed: ') 11 tintl('pointer ',ipoin) tintl(' limit',lim) endl 12 terml(no); $ done with terminal file output 13 call genexit; $ terminate 14 end subr gtoflo; 1 .=member nextok 2 subr nextok; $ get next token 3 $ obtain next token from input stream, unless -keeptok- is on, 4 $ in which case return prior token. if -echoline- on, then 5 $ do nothing but list the last read if it has not yet been 6 $ listed (this action requested as part of error report). 7 $ check for 'special' period-delimited tokens, 8 $ such as '.voadump.' which requests symbol table dump, etc. 9 $ set -toklc- to literal code, -toklt- to lexical type, 10 $ -toklen- to length of token in characters, 11 $ -tokwords- to number of words in 12 $ token, and insert token in array -tokara-. 13 size i(ps); $ do loop index 14 size tokhdr(ws); $ token descriptor word 15 size toktrace(1); data toktrace=0; $ on to trace tokens read 16 size titletext(.sds. (cpw*wpc)); $ text of title directive. 17 size new(voasz); $ voa item built by list code change. 18 19 +* tokread1(wd) = $ get one word from token buffer/file 20 if tokrbufp >= tokrbuflim then 21 call rdrwsio(tokenfile, iorc, tokrbuf, 1, tokrbuflim); 22 tokrbufp=0; 23 end if; 24 tokrbufp = tokrbufp + 1; wd = tokrbuf(tokrbufp); 25 ** 26 27 +* tokread(ara, wds) = $ read wds words into ara(1) to ara(wds). 28 size zzzi(ps); $ do loop index. 29 if (wds+tokrbufp) >= tokrbuflim then $ if would empty buf, 30 do zzzi = 1 to wds; 31 tokread1(ara(zzzi)); end do; 32 else 33 .+movea_env. 34 call 7nmova$li(ara, 1, tokrbuf, tokrbufp+1, wds); $ copy. 35 .-movea_env. 36 do zzzi = 1 to wds; 37 ara(zzzi) = tokrbuf(tokrbufp + zzzi); end do; 38 ..movea_env 39 tokrbufp = tokrbufp + wds; 40 end if; 41 ** 42 43 keeptok = yes; 44 /rdtok/ 45 tokread1(tokhdr); $ read token descriptor 46 toklt =tokrtyp tokhdr; $ get lexical type/code 47 toklen = tokrlen tokhdr; $ no ov chars 48 toklc = tokrlc tokhdr; $ literal code 49 tokwords = (toklen-1)/cpw + 1; $ no of words 50 if (toklen = 0) tokwords = 0; 51 if toktrace then 52 tintl(' token, lt',toklt) tintl(' len',toklen) 53 tintl(' lc', toklc) endl 54 end if; 55 go to t(toklt) in 1 to tokreof; 56 /t(listcontroltok)/ $ .=list directive or change. 57 if toklen = 2 then $ change in list input mode. 58 $ save new value in listswnew until next line read. 59 listswnew = toklc; 60 elseif toklen = 1 then $ change in code list mode. 61 $ must pass on changed code listing option to asm phase. 62 $ build voa op with opcode = op_list, 63 $ inp1 = 1 to mark as listing change and inp2 = new option. 64 $ if voptr ^= voafnct then $ avoid making first entry in voa. 65 $ new = 0; opb new = yes; opcode new = op_list; 66 $ inp1 new = 1; inp2 new = toklc; 67 $ voa(voptr) = new; voaup; 68 $ end if; 69 listingcode = toklc; $ pass in voa header frame. 70 elseif toklen = 3 then $ change titling mode 71 listauto = toklc; 72 end if; 73 go to rdtok; 74 /t(listejecttok)/ $ .=eject 75 if listsw then $ if listing on, do eject action. 76 call lstlin; $ if listing input. 77 ejectlp(toklen); 78 end if; 79 go to rdtok; 80 /t(listtitletok)/ $ .=title 81 if (listsw) call lstlin; $ if listing input. 82 if toklen then $ if title not null, read it. 83 tokread(tokara, tokwords); 84 sorg titletext = 1 + .sds. toklen; 85 do i = 1 to tokwords; 86 .f. sorg titletext - i*ws, ws, titletext = tokara(i); 87 end do; 88 end if; 89 sorg titletext = 1 + .sds. toklen; 90 slen titletext = toklen; 91 if (listauto) subtitling = no; $ use main title in auto mode 92 if (listsw) call stitlr(subtitling, titletext); 93 if subtitling & listsw then 94 ejectl; $ eject if listing and is subtitle. 95 end if; 96 subtitling = yes; 97 go to rdtok; 98 99 /t(7)/ /t(9)/ /t(10)/ /t(11)/ /t(13)/ 100 /t(15)/ /t(16)/ /t(17)/ /t(18)/ /t(19)/ /t(20)/ 101 /t(21)/ /t(22)/ /t(23)/ /t(24)/ /t(25)/ /t(26)/ 102 call ermey(9); 103 104 /t(tokrcard)/ $ card image being transmitted 105 if (listsw) call lstlin; $ if listing input. 106 listsw = listswnew; $ set if new value, or copy if old. 107 ncards = ncards + toklc; proclineno = proclineno + toklc; 108 cardlisted = no; $ new card read, not yet listed 109 listwdsp = tokwords; $ save length 110 if tokwords then $ if need to read card image. 111 tokread(listwds, tokwords); $ read card image. 112 end if; 113 go to rdtok; $ get next token 114 115 /t(tokreof)/ $ end-of-file token 116 if (listsw) call lstlin; $ if listing input. 117 exitcode = 0; call genexit; $ else exit, done 118 119 /t(nametok)/ 120 /t(spectok)/ 121 /t(pdotok)/ 122 /t(dectok)/ 123 /t(strtok)/ 124 /t(bittok)/ 125 /t(rztok)/ 126 /t(sstok)/ 127 /t(realtok)/ dso 108 .+s10 tokara(2) = blankword; vax 207 .+s32 tokara(2) = blankword; 128 .+s37 tokara(2) = blankword; utsa 239 .+s47 tokara(2) = blankword; 129 if toklen <= cpstr then 130 tokara(1) = blankword; 131 tokrval tokara(1) = tokrval tokhdr; 132 else 133 tokread(tokara, tokwords); 134 end if; 135 if toktrace then 136 textl('token = ') 137 do i = 1 to tokwords; 138 wordl(tokara(i)) 139 end do; 140 endl 141 end if; 142 lexlist(lexlistptr+1) = tokara(1); $ save token 143 lexleng(lexlistptr+1) = toklen; $ save token length. 144 lexlistptr = (lexlistptr+1) & (lexlistmax-1); dso 109 .+s10 lexlist(lexlistptr+1) = tokara(2); $ extra word for s10. dso 110 .+s10 lexlistptr = (lexlistptr+1) & (lexlistmax-1); vax 208 .+s32 lexlist(lexlistptr+1) = tokara(2); $ save extra word for s32 vax 209 .+s32 lexlistptr = (lexlistptr+1) & (lexlistmax-1); 145 .+s37 lexlist(lexlistptr+1) = tokara(2); $ save extra word for s37 utsa 240 .+s47 lexlist(lexlistptr+1) = tokara(2); $ save extra word for s47 146 .+s37 lexlistptr = (lexlistptr+1) & (lexlistmax-1); utsa 241 .+s47 lexlistptr = (lexlistptr+1) & (lexlistmax-1); 147 if(toklt ^= pdotok) go to notapdo; 148 149 $ check for special directive to parser, or machine parameter 150 $ which must be replaced by value. 151 152 if (toklc = 0) go to notapdo; 153 i = littabl(9, toklc); 154 if (i=0) go to notapdo; 155 go to l(i) in 1 to 13; 156 157 / l(1) / $ .voadump. 158 / l(2) / $ .voapart. 159 call tabdump(1, voptr, 2-i); $ dump tables. 160 161 / l(3) / / l(4) / $ unused. 162 go to rdtok; 163 164 / l( 5) / $ .contr. - start listing converted constant values. 165 $ this flag examined by routine cnvcon. 166 docontrace = yes; go to rdtok; 167 168 / l( 6) / $ .nocontr. - terminate list of converted constants. 169 docontrace = no; go to rdtok; 170 171 / l( 7) / $ .toktr. - list tkokens as read. 172 toktrace = yes; go to rdtok; 173 174 / l( 8) / $ .notoktr. - terminate list of tokens as read. 175 toktrace = no; go to rdtok; 176 177 / l(9)/ / l(10) / / l(11) / / l(12) / / l(13) / 178 $ convert target mahchine parameters to value. 179 $ warning. code currently assumed that tokara(1) can hold number 180 $ of characters (now 2) needed to specify machine paramater 181 $ value. 182 tokara(1) = tmtokara(i-8); 183 toklen = 2; toklt = dectok; toklc = 0; 184 $ thus substituting value for operator originally present. 185 186 $ is not special token, pass on 187 /notapdo/ 188 if savetoks < 5 then $ save token in csatok for opener 189 savetoks = savetoks + 1; 190 csatokptr = csatokptr + 1; 191 csatok(csatokptr) = tokara(1); 192 end if; 193 194 if toklt = realtok then $ this is real token. 195 $ check if supported on this machine. 196 if targetmachine = m11 then $ not supported. 197 call ermes(69); $ print error. 198 /unstok/ $ here to fix unsupported constants. 199 tokara(1) = blankword; $ start to set to 1. 200 .f. ws+1-cs, cs, tokara(1) = 1r1; $ set to one. 201 toklen = 1; toklt = dectok; $ set length and type. 202 end if; 203 end if; 204 205 if toklt = sstok then $ this is special string token. 206 $ see if target machine supports it. 207 if targetmachine ^= m11 then $ only pdp-11 supports it now. 208 call ermes(9); $ print error message. 209 go to unstok; $ convert it to integer 1. 210 end if; 211 end if; 212 213 end subr nextok; 1 .=member lstlin 2 subr lstlin; $ list input line. 3 size i(ps); $ loop index. 4 5 if cardlisted=no then $ if need to list. 6 cardlisted = yes; rbko 10 intl(proclineno) skipl(3) 8 do i = 1 to listwdsp; $ list each word. 9 wordl(listwds(i)); 10 end do; 11 endl 12 end if; 13 14 end subr lstlin; 1 .=member cnvcon 2 subr cnvcon; $ convert constant. 3 $ convert 'safe' constants to their internal (binary) form. 4 5 size i(ps); 6 $ note - size of rcv should be rlsz (or .rs.) when 7 $ .rs. pararameter installed. 8 size rcv(ws); $ real constant built here 9 size longint(ws); $ for integers near word size. 10 size longresult(szmax-ws); $ build long constants here 11 $ size is less than szmax so that temporary generated for 12 $ longresult * 10 has size no greater than szmax. 13 14 size c(ps); $ holds character, then numeric val 15 +* charin(c) = ccaptr = ccaptr+1; cca(ccaptr) = c; ** $ to add 16 size stringlen(ps); $ length of string 17 size charsrem(ps); $ no of chars left in word 18 size sdskel(ws); $ skeleton for self-def strings built up heree 19 size sdlast(ps); $ no of chars used in last word of str 20 size sdleft(ps); $ no of remaining char posns in last wd 21 size sddpos(ps); $ position when moving desc into val of sd 22 size cpsdd(ps); $ no. of characters in slen,sorg fields. 23 size j(ps); $ do loop index. 24 size bitwidth(ps); $ no. of bits per char in bit constant. 25 size bytenow(ps); $ current bit value. 26 size expval(ws); $ real exponent value. 27 28 ccvalptr = 1; $ assume 1 word constant 29 ccval(1) = 0; 30 ccsyze = 1; $ will return 0 if can not convert. 31 stringlen = ccaptr; 32 ccnchars = 0; 33 go to l(cclt) in 1 to toktypes; 34 35 / l(realtok) / $ real constant. 36 ccsyze = rlsz; 37 if safeconst(realtok) then $ if safe, convert real. 38 call 7nvnum$io(cca, ccaptr, expval); ldsd 24 if cca(ccaptr+2) then $ if invalid. ldsd 25 call ermes(10); ldsd 26 ccsyze = 1; $ take as zero. ldsd 27 go to converted; ldsd 28 end if; 39 if cca(ccaptr+3) > 1 then $ if point present, adjust exponent. 40 expval = expval - (cca(ccaptr+3) - 1); 41 end if; 42 call 7ncefr$io(rcv, cca, ccaptr, expval); ldsd 29 if cca(ccaptr+2) then $ if invalid. ldsd 30 call ermes(10); ldsd 31 ccsyze = 1; $ take as zero. ldsd 32 go to converted; ldsd 33 end if; 43 do i = 1 to rlsz/mws; 44 ccval(i) = .f. rlsz+1-i*mws, mws, rcv; 45 end do; 46 go to converted; 47 else 48 ccvalptr = (ccaptr-1)/cpw + 1; 49 ccnchars = ccaptr; 50 go to endofstr; 51 end if; 52 53 / l(nametok) / 54 / l(spectok) / 55 / l(pdotok) / 56 /l(7)/ /l(9)/ /l(10)/ /l(11)/ /l(13)/ 57 call ermey(8); 58 59 /l(bittok)/ 60 bitwidth = digofchar(cca(1)); 61 ccsyze = 0; 62 do i = ccaptr-1 to 4 by -1; 63 c= cca(i); if (c = 1r ) cont do; 64 if c >= 1r0 & c <= 1r9 then $ is a digit. 65 bytenow = digofchar(c); $ get value. 66 else $ must be hex a-f. 67 bytenow = c - 1ra + 10; $ get value. 68 end if; 69 70 if ccsyze+bitwidth <= ws then 71 .f. ccsyze+1, bitwidth, ccval(1) = bytenow; 72 else 73 if ccsyze <= ws then 74 longresult = ccval(1); 75 end if; 76 do j = 1 to bitwidth; 77 .f. ccsyze+j, 1, longresult = .f. j, 1, bytenow; 78 end do; 79 end if; 80 ccsyze = ccsyze + bitwidth; 81 end do; 82 if ccsyze <= ws then 83 ccsyze = .fb. ccval(1); 84 else 85 ccsyze = .fb. longresult; 86 if ccsyze <= ws then 87 ccval(1) = .f. 1, ws, longresult; 88 end if; 89 end if; 90 if (ccsyze = 0) ccsyze = 1; 91 if (ccsyze > ws) go to packlong; 92 go to converted; 93 94 /packlong/ 95 ccvalptr = (ccsyze-1) / ws; 96 do i = 0 to ccvalptr; 97 ccval(ccvalptr+1-i) = .f. 1+i*ws, ws, longresult; 98 end do; 99 ccvalptr = ccvalptr + 1; 100 go to converted; 101 102 / l(dectok) / 103 do i = 1 to ccaptr; $ decimal conversion 104 ccsyze = .fb. ccval(1); 105 .+s66. 106 if (ccsyze > 44) go to largeint; 107 $ the above machine dependent command is the result of the 108 $ chintzy integer multiply on the 6600. 109 .-s66. 110 $ on a better target 111 $ machine, replace the condition with the machine independent 112 $ (ccsyze>(ws-4)) since allow 4 bits to multiply by 10. 113 if (ccsyze>(ws-4)) go to largeint; 114 ..s66 115 ccval(1) = ccval(1) * 10 + digofchar(cca(i)); $ machine depe 116 end do; 117 ccsyze = .fb. ccval(1); 118 if (ccsyze=0) ccsyze = 1; 119 go to converted; 120 /largeint/ 121 longint = ccval(1); 122 do i = i+1 to ccaptr; 123 ccsyze = .fb. longint; 124 if (ccsyze > (mws-3)) go to toobig; 125 .-s66 longint = longint * 10 + digofchar(cca(i)); 126 .+s66. $ on s66, do via shift due to limited range 127 $ of multiply. 128 longint = longint*8 + longint*2 + digofchar(cca(i)); 129 ..s66 130 end do; 131 ccsyze = .fb. longint; 132 ccval(1) = longresult; ccvalptr = 1; 133 go to converted; 134 135 136 /toobig/ 137 call ermes(13); 138 ccsyze = 1; ccval(1)=0; ccvalptr=1; go to converted; 139 140 141 / l(strtok) / 142 ccnchars = stringlen; 143 if safeconst(strtok)=no then $ if should not convert, 144 if ccaptr=0 then $ if null string. 145 ccsyze=0; 146 ccsyze = mws*((msl+mso+mws-1)/mws); 147 go to converted; end if; 148 ccsyze = ((ccaptr*mcs + msl + mso + mws-1)/mws)*mws; 149 ccvalptr = (ccaptr-1)/cpw + 1; 150 go to endofstr; 151 end if; utsa 242 utsa 243 .+s37 if (ebcascoption) call ebcasc; 152 153 sdskel = 0; $ descriptor build up here utsb 1 .f. 1, msl, sdskel = ccaptr; $ no of chars in string 155 sdlast = ccaptr - cpw*(ccaptr/cpw); $ position of last char in wd 156 $ cpsdd is number of characters that could be held in sorg,slen 157 $ fields. at present, it is assumed that (.sl.+.so.) is 158 $ multiple of .cs. . 159 cpsdd = (msl+mso)/mcs; 160 if sdlast=0 then sdlast = cpw;end if; 161 sdleft = cpw - sdlast; $ remaining chars in last word 162 $ now pad with zeros if necessary 163 if sdleft > cpsdd then 164 do i = 1 to sdleft-cpsdd; charin(0); end do; 165 else if sdleft < cpsdd then 166 do i = 1 to (sdleft + (cpw-cpsdd) ); charin(0); end do; 167 end if ; 168 end if; utsb 2 .f. msl+1, mso, sdskel = (ccaptr + cpsdd) * cs + 1 ; 170 sddpos = cpsdd*cs + 1; $ put descriptor val in string rep 171 while(sddpos>1); 172 sddpos = sddpos - cs; $ move to next char pos 173 charin( (.f. sddpos, cs, sdskel) ); 174 end while; 175 ccsyze = mws*((ccaptr*mcs + mws-1)/mws); 176 ccvalptr = (ccaptr-1)/cpw + 1; 177 go to endofstr; 178 179 180 / l(rztok) / 181 if safeconst(rztok) then $ if should convert. utsa 244 .+s37 if (ebcascoption) call ebcasc; 182 charsrem = ((ccaptr+cpw-1)/cpw) * cpw - ccaptr; 183 ccaptr = charsrem + stringlen; 184 if (ccaptr = 0) go to converted; $ this is null string. 185 do i = 0 to stringlen-1; 186 cca(ccaptr-i)=cca(stringlen-i); 187 end do; 188 do i = 1 to charsrem; 189 cca(i) = 0; 190 end do; $ insert leading zero 191 end if; 192 193 / l(sstok) / 194 ccnchars = stringlen; 195 if (ccaptr=0) go to converted; $ if null, return 0. 196 ccsyze = ccnchars * mcs; $ assume r-type. 197 if (cclt = sstok) ccsyze = mws*((ccnchars+2)/3); $ rad-50 on s11 198 ccvalptr = (ccaptr -1)/cpw + 1; 199 /endofstr/ 200 .+pack_env call 7npack$li(ccval, 1, cca, 1, ccaptr); $ if fast pack 201 .-pack_env call linepak(ccval, cca, ccaptr); 202 /converted/ 203 if docontrace then 204 tintl(' type',cclt) 205 tintl('len',ccaptr) tintl('bits',ccsyze) 206 tintl('words',ccvalptr) endl 207 call dumpaq(' converted constant ', ccval, 1, ccvalptr); 208 end if; 209 macdrop(charin) 210 end subr cnvcon; utsa 245 .+s37. utsa 246 subr ebcasc; $ convert from ebcdic to ascii utsa 247 $ convert character string data in cca from ebcdic to ascii. utsa 248 $ the conversion table is that used by cdc in the 8-bit subroutine utsa 249 $ package and is used to write ebcdic tapes at nyu. it agrees with utsa 250 $ values used by dec for vms, except vms map takes ascii to be 7-bit utsa 251 $ code. utsa 252 size i(ps); utsc 8 size ctlc(cs); utsa 253 size ebcasctab(.ws.); dims ebcasctab(256); utsa 254 data ebcasctab = utsa 255 4b'00', 4b'01', 4b'02', 4b'03', 4b'9c', 4b'09', 4b'86', 4b'7f', utsa 256 4b'97', 4b'8d', 4b'8e', 4b'0b', 4b'0c', 4b'0d', 4b'0e', 4b'0f', utsa 257 4b'10', 4b'11', 4b'12', 4b'13', 4b'9d', 4b'85', 4b'08', 4b'87', utsa 258 4b'18', 4b'19', 4b'92', 4b'8f', 4b'1c', 4b'1d', 4b'1e', 4b'1f', utsa 259 4b'80', 4b'81', 4b'82', 4b'83', 4b'84', 4b'0a', 4b'17', 4b'1b', utsa 260 4b'88', 4b'89', 4b'8a', 4b'8b', 4b'8c', 4b'05', 4b'06', 4b'07', utsa 261 4b'90', 4b'91', 4b'16', 4b'93', 4b'94', 4b'95', 4b'96', 4b'04', utsa 262 4b'98', 4b'99', 4b'9a', 4b'9b', 4b'14', 4b'15', 4b'9e', 4b'1a', utsa 263 4b'20', 4b'a0', 4b'a1', 4b'a2', 4b'a3', 4b'a4', 4b'a5', 4b'a6', utsa 264 4b'a7', 4b'a8', 4b'5b', 4b'2e', 4b'3c', 4b'28', 4b'2b', 4b'21', utsa 265 4b'26', 4b'a9', 4b'aa', 4b'ab', 4b'ac', 4b'ad', 4b'ae', 4b'af', utsa 266 4b'b0', 4b'b1', 4b'5d', 4b'24', 4b'2a', 4b'29', 4b'3b', 4b'5e', utsa 267 4b'2d', 4b'2f', 4b'b2', 4b'b3', 4b'b4', 4b'b5', 4b'b6', 4b'b7', utsa 268 4b'b8', 4b'b9', 4b'7c', 4b'2c', 4b'25', 4b'5f', 4b'3e', 4b'3f', utsa 269 4b'ba', 4b'bb', 4b'bc', 4b'bd', 4b'be', 4b'bf', 4b'c0', 4b'c1', utsa 270 4b'c2', 4b'60', 4b'3a', 4b'23', 4b'40', 4b'27', 4b'3d', 4b'22', utsa 271 4b'c3', 4b'61', 4b'62', 4b'63', 4b'64', 4b'65', 4b'66', 4b'67', utsa 272 4b'68', 4b'69', 4b'c4', 4b'c5', 4b'c6', 4b'c7', 4b'c8', 4b'c9', utsa 273 4b'ca', 4b'6a', 4b'6b', 4b'6c', 4b'6d', 4b'6e', 4b'6f', 4b'70', utsa 274 4b'71', 4b'72', 4b'cb', 4b'cc', 4b'cd', 4b'ce', 4b'cf', 4b'd0', utsa 275 4b'd1', 4b'7e', 4b'73', 4b'74', 4b'75', 4b'76', 4b'77', 4b'78', utsa 276 4b'79', 4b'7a', 4b'd2', 4b'd3', 4b'd4', 4b'd5', 4b'd6', 4b'd7', utsa 277 4b'd8', 4b'd9', 4b'da', 4b'db', 4b'dc', 4b'dd', 4b'de', 4b'df', utsa 278 4b'e0', 4b'e1', 4b'e2', 4b'e3', 4b'e4', 4b'e5', 4b'e6', 4b'e7', utsa 279 4b'7b', 4b'41', 4b'42', 4b'43', 4b'44', 4b'45', 4b'46', 4b'47', utsa 280 4b'48', 4b'49', 4b'e8', 4b'e9', 4b'ea', 4b'eb', 4b'ec', 4b'ed', utsa 281 4b'7d', 4b'4a', 4b'4b', 4b'4c', 4b'4d', 4b'4e', 4b'4f', 4b'50', utsa 282 4b'51', 4b'52', 4b'ee', 4b'ef', 4b'f0', 4b'f1', 4b'f2', 4b'f3', utsa 283 4b'5c', 4b'9f', 4b'53', 4b'54', 4b'55', 4b'56', 4b'57', 4b'58', utsa 284 4b'59', 4b'5a', 4b'f4', 4b'f5', 4b'f6', 4b'f7', 4b'f8', 4b'f9', utsa 285 4b'30', 4b'31', 4b'32', 4b'33', 4b'34', 4b'35', 4b'36', 4b'37', utsa 286 4b'38', 4b'39', 4b'fa', 4b'fb', 4b'fc', 4b'fd', 4b'fe', 4b'ff'; utsa 287 utsa 288 do i = 1 to ccaptr; utsc 9 if ebcascoption=2 then $ if want folded to lower case. utsc 10 cca(i) = ctlc(cca(i)); utsc 11 end if; utsa 289 cca(i) = ebcasctab(cca(i)+1); utsa 290 end do; utsa 291 utsa 292 end subr ebcasc; utsa 293 ..s37 1 .=member inscon 2 subr inscon( conhc); $ add constant to ha 3 4 $ this routine returns the ha-index of a constant, adding the 5 $ constant to the ha (and voa) if not yet present. 6 $ ha-index is returned via conhc. inputs are global and are 7 $ ccsyze - no of bits in constant(its size) 8 $ we use 'add the hash' technique to resolve ha collisions 9 10 11 size conhc(ps); $ hash index returned 12 size hcode(ws); $ computed hash code 13 size j(ps); $ ha-index of entry begin examined 14 size i(ps); $ do loop temporary 15 size new(voasz); $ for building new voa entry 16 size vb(ps); $ save position in val array 17 18 hcode = ccval(1); 19 do i = 2 to ccvalptr; 20 hcode = hcode .exor. ccval(i); end do; 21 22 hcode = .f. 1, ws/2, hcode .exor. .f. ws/2+1, ws/2, hcode; 23 haprobe(j, hcode); $ search the ha 24 if (hainuse ha(j) = no) haquit; $ empty slot found 25 if ((var ha(j) = no) ! (ep ha(j) = 0)) hacont; 26 if (const voa(ep ha(j)) = no) hacont; 27 if (lextype voa(ep ha(j)) ^= cclt) hacont; 28 if (nchars ha(j) ^= ccnchars) hacont; 29 if (signbit voa(ep ha(j)) ^= signofcon) hacont; 30 if (ccvalptr ^= vlen voa(ep ha(j))) hacont; 31 vb = vbeg voa(ep ha(j)) - 1; $ con 0 origin 32 do i = 1 to ccvalptr; 33 if (val(vb+i) ^= ccval(i)) hacont; end do; 34 $ found 35 conhc = j; 36 return; 37 haend; $ end ha probe 38 39 $ add constant to ha and voa 40 new = 0; 41 hainuse ha(j) = yes; $ show in use 42 ep ha(j) = voptr; $ link to voa 43 var ha(j) = yes; 44 nchars ha(j) = ccnchars; ccnchars = 0; 45 const new = yes; $ is constant 46 amode new = (cclt = realtok); 47 syze new = ccsyze; $ size in bits 48 vlen new = ccvalptr; $ size in words 49 naym new = j; $ link to ha 50 type new = quant; 51 vbeg new = valptr; 52 lextype new = cclt; $ set constant lexical type 53 signbit new = signofcon ; $ set sign needed for cross-compiler 54 55 $ set hascon field if constant is 'safe', i.e., we can evaluate 56 $ it at compile time. 57 $ on a resident compiler, any single-word or shorter constant 58 $ is safe. on a cross compiler, only short integers and octals 59 $ are safe. 60 hascon ha(j) = safeconst(cclt); $ set if safe constant. 61 cclt = 0; $ clear lexical type value 62 if (valptr+ccvalptr) > valmax then $ if val overflow 63 call gtoflo(valptr+1, valptr, 'val'); 64 end if; 65 vb = valptr - 1; $ origin for constant vlu insertion 66 do i = 1 to ccvalptr; val(vb+i) = ccval(i); end do; 67 valptr = valptr + ccvalptr; $ update free loc avail in val array 68 conhc = j; 69 voa(voptr) = new; voaup; $ entry constant itemin voa 70 71 end subr inscon; 1 .=member sdsnamr 2 subr sdsnamr(hap); $ get sds form of ha entry 3 $ converts name in names array to self defined string and 4 $ returns it in global variable sdsname 5 size hap(ps); $ ha ptr 6 size i(ps); $ do loop index 7 8 slen sdsnamstr = nchars ha(hap); $ set length field 9 if (nchars ha(hap) = 0) go to ret; 10 do i = 1 to (nchars ha(hap) -1) / cpw+1; 11 .f. nameorg -ws*i, ws, sdsnamstr = names(nayme ha(hap)+i-1); 12 end do; 13 14 /ret/ 15 end subr sdsnamr; 16 1 .=member xsdsnamr 2 subr xsdsnamr(xhap); $ get sds form of -xha- entry (same as 3 $ -sdsnamr- except gets -xha- entry instead of -ha- entry) 4 size xhap(ps); $ -xha- pointer 5 size i(ps); $ do loop index 6 7 slen sdsnamstr = xnchars xha(xhap); $ set length 8 do i = 1 to (xnchars xha(xhap)-1)/cpw+1; 9 .f.nameorg-ws*i,ws,sdsnamstr = xnames(xnameptr xha(xhap)+i-1); 10 end do; 11 12 13 end subr xsdsnamr; 1 .=member pdsort 2 subr pdsort; $ sort and list procedures and pages. 3 $ read in list of procedure names and page numbers from 4 $ reference file; sort by name and print out. 5 6 size i(ps); $ do-loop index 7 size w(ws); 8 size l(ps); $ length of name. 9 size lines(ps); $ number of lines for list. 10 size m(ps); $loop index. 11 size haptr(ps); $ size of packed ha. 12 size top(ps); $ loop indices 13 size targ(ps); 14 size temp(hasz); $ temporary for swapping 15 size pdcomp(1); $ function to compare symbols. 16 size crfget(ws); $ read file. 17 18 haptr = 0; namesptr = 0; 19 $ read in reference file, get procedure names and page numbers. 20 crbuffptr = crbuffmax; $ indicate empty buffer to force read. 21 while 1; 22 if (crfget(w) = 0) quit while; 23 countup(haptr, hamax, 'cr-ha'); 24 ha(haptr) = 0; 25 ep ha(haptr) = crfget(w); var ha(haptr) = yes; 26 nayme ha(haptr) = namesptr + 1; 27 l = crfget(w); $ get length of name. 28 if (l=0) return; $ cannot handle null name. 29 nchars ha(haptr) = l; $ save length. 30 l = (l-1)/cpw + 1; $ convert to word count. 31 if (l+namesptr) > namesmax then 32 namesptr = namesptr +l; 33 countup(namesptr, namesptr, 'cr - names'); 34 end if; 35 do i = 1 to l; 36 names(namesptr + i) = crfget(w); 37 end do; 38 namesptr = namesptr + l; 39 end while; 40 41 if (haptr = 0) return; $ if no procedures. 42 43 +* swap(a,b) = $ macro for swapping, common sort operation 44 temp = ha(a); ha(a) = ha(b); ha(b) = temp; ** 45 46 do i = 2 to haptr; $ make into heap, i is parent. 47 m = i; 48 while m>1; $ examine parents in turn 49 if pdcomp(m/2, m) quit while; $ if parent no smaller, 50 swap(m,m/2); $ promote large child 51 m = m/2; 52 end while; 53 end do i; 54 55 do top = haptr to 2 by -1; $ sort subtrees in turn 56 swap(1,top); $ extract largest element 57 m = 1; $ force remaining subtree to be heap 58 while m*2 < top; 59 if pdcomp(m*2+1, m*2) & (m*2+1 < top) 60 then targ = m*2+1; 61 else targ = m*2; end if; 62 if pdcomp(targ,m) then 63 swap(m, targ); $ child too big, so exchange 64 else quit while; end if; 65 m = targ; $ move to subtree of largest child 66 end while m; 67 end do top; 68 69 macdrop(swap) 70 textl(' ') endl $ blank line 71 call stitlr(1, 'sorted list of procedures and page numbers.'); 72 ejectl; $ begin new page. 73 lines = (haptr+3)/4; $ number of lines. 74 do m = 1 to lines; 75 i = m; 76 while i <= haptr; 77 intl((ep ha(i))) 78 call sdsnamr(i); 79 skipl(2) 80 textl(sdsnamstr); $ print symbol 81 skipl(15-slen sdsnamstr) 82 i = i + lines; 83 end while; 84 endl endl 85 end do; 86 endl $ flushing last few names 87 88 end subr pdsort; 1 .=member crfget 2 fnct crfget(w); $ read word from reference file. 3 size crfget(ws); $ item to read. 4 size w(ws); $ dummy argument. 5 6 if crbuffptr = crbuffmax then $ if buffer done, read new one. 7 call rdrwsio(crfile, iorc, crbuff, 1, crbuffmax); 8 crbuffptr = 0; 9 end if; 10 crbuffptr = crbuffptr + 1; 11 crfget = crbuff(crbuffptr); 12 13 end fnct crfget; 1 .=member pdcomp 2 fnct pdcomp(jarg, karg); $ compare two symbols. 3 size jarg(ps), karg(ps); $ ha indices of symbols. 4 size pdcomp(1); 5 size jlen(ps), klen(ps); size minlen(ps); 6 size jch(cs), kch(cs); $ characters. 7 size i(ps); $ loop index. 8 size pos(ps); $ position within name words. 9 size jptr(ps), kptr(ps); $ nayme values. 10 11 jptr = nayme ha(jarg); kptr = nayme ha(karg); 12 jch = .f. ws+1-cs, cs, names(jptr); 13 kch = .f. ws+1-cs, cs, names(kptr); 14 if jch ^= kch then $ if initial characters differ, 15 pdcomp = (jch > kch); $ compare to get result. 16 return; 17 end if; 18 $ must examine rest of symbols, retrieve as sds and compare. 19 jlen = nchars ha(jarg); klen = nchars ha(karg); 20 minlen = jlen; if (klen < minlen) then minlen = klen; end if; 21 pdcomp=1; $ assume j bigger 22 pos = cpw*cs + 1; 23 do i = 1 to minlen; 24 pos = pos - cs; 25 jch = .f. pos, cs, names(jptr); 26 kch = .f. pos, cs, names(kptr); 27 if jch ^= kch then 28 pdcomp = (jch > kch); 29 return; 30 end if; 31 if pos = 1 then 32 pos = cpw*cs + 1; 33 jptr = jptr + 1; kptr = kptr + 1; 34 end if; 35 end do; 36 pdcomp = (jlen > klen); $ 37 38 end fnct pdcomp; 1 .=member getxsds 2 subr getxsds(hap, str); $ get execution time form of string 3 $ given sds str, generate minimal-storage representation as sds 4 $ for use at execution time. set hap to ha index of generated 5 $ string. 6 7 size hap(ps); $ ha index of generated string 8 size str(namsz); $ string to pack 9 size i(ps); $ do loop for ccval copy 10 11 ccaptr = slen str; 12 do i = 1 to ccaptr; 13 cca(i) = .ch. i, str; end do; 14 cclt = strtok; 15 call cnvcon; $ convert constant. 16 call inscon(hap); 17 end subr getxsds; 1 .=member pshnamr 2 subr pshnamr(hc, r); $ hash name and push on arglist 3 $ hashes name into ha and names array 4 $ push result on arglist 5 size hc(ps); $ hash code returned 6 size r(namsz); $ sdsname 7 size j(ps); $ do loop index 8 $ this routine is invoked from macro pushname 9 do j = 1 to (slen r + (cpw-1))/cpw; 10 insnarg(j) = .f. (sorg r) - ws*j, ws, r; 11 end do; 12 13 if (mod(slen r,cpw)) .f. 1, ws - cs*(mod(slen r, cpw)), insnarg 14 (j-1) = blankword; $ set to blank pad like -names-. 15 16 insnchars = slen r; call insname(hc); 17 push(hc); $ push result onto arglist 18 19 end subr pshnamr; 20 1 .=member pshintr 2 subr pshintr(pcon); $ hash in constant and stack it 3 size pcon(ws); $ constant to insert in ha 4 size hai(ps); $ ha index assigned 5 6 ccsyze = .fb. pcon + (pcon=0); $ set to size. 7 cclt = dectok; ccval(1)=pcon; ccvalptr = 1; 8 if (ccsyze > mws-2) cclt = bittok; $ for debugging 9 call inscon(hai); $ hash in constant. 10 push(hai); 11 12 end subr pshintr; 1 .=member insname 2 subr insname(namhc); $ insert name into ha. 3 4 $ this routine returns the ha-index of a name, inserting the 5 $ inserting the name if not yet present. global inputs are 6 $ insnarg - name to insert 7 $ insnchars - number of characters in name. 8 9 size hcode(ws); $ hash code of name 10 size j(ps); $ ha-index of entry benng probed 11 size namhc(ps); $ ha-index returned 12 size insnwds(ps); $ number of words 13 size i(ps); $ do loop index 14 15 hcode = insnarg(1); $ first word of name 16 insnwds = (insnchars - 1) / cpw; $ number of words - 1 17 if (insnchars = 0) insnwds = 0; 18 do i = 1 to insnwds; $ compute hash code 19 hcode = hcode .ex. insnarg(i + 1); 20 end do; 21 hcode = .f. 1, ws/2, hcode .ex. .f. ws/2+1, ws/2, hcode; 22 haprobe(j, hcode); $ search the ha 23 24 if (hainuse ha(j) = no) haquit; $ empty slot found 25 if (var ha(j) = no ) hacont; $ ignore ops 26 if (nchars ha(j) ^= insnchars) hacont; 27 if (nayme ha(j) = 0) hacont; $ if not a name. 28 do i = 0 to insnwds; $ compare names 29 if (names(nayme ha(j) + i) ^= insnarg(i+1)) hacont; 30 end do; 31 namhc = j; 32 return; 33 haend; $ end ha probe 34 35 $ add new name to ha 36 hainuse ha(j) = yes; $ show in use 37 nchars ha(j) = insnchars; $ number of chars in name 38 var ha(j) = yes; $ is variable 39 nayme ha(j) = namesptr; 40 do i = 1 to insnwds + 1; $ enter name in names array 41 names(namesptr) = insnarg(i); 42 countup(namesptr, namesmax, 'insert name'); 43 end do; 44 namhc = j; 45 46 end subr insname; 1 .=member insglor 2 subr insglor(glohc); $ adds name to global name table 3 $ this routine returns (via gloha) the index in the global 4 $ names symbol table of a name, adding the name if it is not yet 5 $ present. 6 size j(ps); $ do loop index for search 7 size i(ps); $ do loop index 8 size hcode(ws); $ hash code for search 9 size glohc(ps); $ hash code in global array 10 size namp(ps); $ otr to name in names array 11 size hwords(ps); $ number of words in name 12 $ inputs are transmitted globally, and are 13 $ insgarg - name to hash 14 $ insgwds - number of words for name 15 16 namp = nayme ha(insgarg); $ ptr to names array 17 hwords = (nchars ha(insgarg) - 1)/cpw; $ number of words of nm 18 if (nchars ha(insgarg) = 0) hwords = 0; 19 hcode = names(namp); $ initialize hcode to first word of name 20 do i = 1 to hwords; 21 hcode = hcode .ex. names(namp + i); 22 end do; 23 hcode = .f. 1, ws/2, hcode .ex. .f. ws/2+1, ws/2, hcode; 24 25 $ this routine returns the index in xha of a name, adding the 26 $ name to the xha table if it is not present. 27 $ the hasing algorith is 28 $ as described as algorithm 'c' in section 6.4 of knuth, vol 3. 29 $ note that xha size must be prime 30 j = mod(hcode, xhamax) + 1; $ get initial hash code. 31 /probe/ 32 if xnchars xha(j) ^= nchars ha(insgarg) go to nomatch; 33 do i = 0 to hwords; $ compare names 34 if xnames(xnameptr xha(j) + i) ^= names(namp + i) go to 35 nomatch; 36 end do; 37 glohc = j; return; $ match found 38 /nomatch/ 39 $ no match, look through links, if any 40 if xlink xha(j) then j = xlink xha(j); 41 go to probe; end if; 42 if (xnameptr xha(j) = 0) go to addnew; $ add new entry. 43 /findfree/ 44 xhafree = xhafree - 1; $ look for free xha slot 45 if xhafree = 0 then $ xha full 46 call ermes(31); call genexit; end if; 47 if (xnameptr xha(xhafree)) go to findfree; 48 xlink xha(j)=xhafree; $link to new slot 49 j=xhafree; $ and point to it. 50 /addnew/ 51 xnchars xha(j) = nchars ha(insgarg); $ number of characters in 52 $ name 53 xnameptr xha(j) = xnamesptr; 54 do i = 0 to hwords; $ copy name from names to xnames 55 xnames(xnamesptr) = names(namp + i); 56 countup(xnamesptr, xnamesmax, 'xglobal insert'); 57 end do; 58 xlink xha(j) = 0; $ indicate link 59 glohc = j; $ hash code found 60 61 end subr insglor; 1 .=member ifaglor 2 subr ifaglor(glohc); $ see if name is global 3 $ this routine sees if the argument name is a global variable 4 $ for which access has been granted. if so, the index in the 5 $ xha of the variable is returned; otherwise 0 is returned. 6 $ arguments are passed by the global variables 7 $ ifaglorname - name of variable 8 $ ifaglorwds - number of words in name 9 10 size i(ps); $ do loop var 11 size namp(ps); $ ptr to names array 12 size hwords(ps); $ number of words of name 13 size j(ps); $ do loop index 14 size hcode(ws); $ hash code of name 15 size glohc(ps); $ha index returned 16 size hap(ps); $ ha index of nameset name 17 size xnp(ps); $ index in xnames of nameset name 18 19 namp = nayme ha(ifaglorname); $ ptr to names array 20 hwords = (nchars ha(ifaglorname) - 1)/cpw; $ nwords-1. 21 hcode = names(namp); $ first word of name. 22 do i = 1 to hwords; 23 hcode = hcode .ex. names(namp+i); 24 end do; 25 26 hcode = .f. 1, ws/2, hcode .ex. .f. ws/2+1, ws/2, hcode; 27 j = mod(hcode, xhamax) + 1; $ set initial hash code. 28 /probe/ 29 if xnchars xha(j) ^= nchars ha(ifaglorname) go to nomatch; 30 if xnames(xnameptr xha(j)) ^= names(namp) go to nomatch; 31 do i = 1 to hwords; $ compare rest of name 32 if xnames(xnameptr xha(j) + i) ^= names(namp + i) 33 go to nomatch; 34 end do; 35 36 $ if we have been looking for possible builtin function name, 37 $ we return builtin function code, not xha position. 38 if bifxhasearch then 39 glohc = xhabif xha(j); 40 return; end if; 41 42 $ name found, see if access granted 43 if (nlno xha(j) = 0) go to ret; 44 if (nlblk nl(nlno xha(j)) = 0) go to ret; 45 $ if access not granted to variable, return. 46 $ if access granted, enter nameset name into ha if not already 47 $ there, and set -mbused- bit to indicate that nameset used 48 $ in current routine. 49 50 if (.f. nlblk nl(nlno xha(j)), 1, accesstab = no) go to ret; 51 52 glohc = j; $ access granted, set glohc to xha index 53 mbused mba(nlblk nl(nlno xha(j))) = yes; $ nameset member used in 54 if (mbha mba(nlblk nl(nlno xha(j)))) go to done; $ nameset name 55 j = mbxha mba(nlblk nl(nlno xha(j))); $ get xha index of conta 56 xnp = xnameptr xha(j) - 1; 57 do i = 1 to (xnchars xha(j) - 1)/cpw + 1; 58 insnarg(i) = xnames(xnp+i); 59 end do; 60 61 insnchars = xnchars xha(j); 62 call insname(hap); 63 mbha mba(nlblk nl(nlno xha(glohc))) = hap; $ set -ha- index. 64 return; 65 66 /nomatch/ $ no match found. try next entry if there is one 67 j = xlink xha(j); 68 if (j) go to probe; 69 70 /ret/ 71 glohc = 0; $ failure. 72 73 /done/ 74 end subr ifaglor; 1 .=member advstr 2 subr advstr(str, hc); $ advance name and hash in 3 $ this routine is given string naming current local variable 4 $ or local label generation string. the string is four 5 $ characters, of which the last two are alphabetic. the routine 6 $ advances the name to next one in lexicographic order, eg, 7 $ from -aa- to -zz-. compilation is aborted if attempt made to 8 $ exceed -zz-. 9 size str(sds(4)); $ string to davance 10 size hc(ps); $ hash code computed 11 size ci(ps); $ character position 12 size alphabet(sds(26)); 13 data alphabet = 'abcdefghijklmnopqrstuvwxyz'; 14 15 ci = (.s. 4, 1, str) .in. alphabet; 16 if ci<26 then $ if last character can be advanced 17 .ch. 4, str = .ch. ci+1, alphabet; $ pick next character 18 else $ try to advance third character, restart fourth at 'a' 19 ci = (.s.3,1,str) .in. alphabet; 20 if ci<26 then 21 .ch. 3, str = .ch. ci+1,alphabet; .ch.4,str=1ra; 22 else countup(ci ,26, 'advstr - name overflow'); end if; 23 $ note that above countup will abort program execution 24 end if; 25 pushname(hc, str); $ hash in name to ha and names 26 $ pushname has added item to arglist, so remove from arglist 27 argptr = argptr-1; 28 namintern ha(hc) = yes; $ set internal name flag 29 30 end subr advstr; 1 .=member assembl 2 subr assembl; $ write tables on -voa- file 3 $ write tables onto -voa- file for used by code generator. 4 $ write entries in 'frames', indicating type and length of each 5 $ frame. if argument non-zero, dump symbol table. 6 size i(ws); 7 size nzwds(ps); $ number of zero words in ha 8 size haent(hasz); $ temporary copy of ha entry 9 if asmvoadump = yes then 10 call tabdump(1, voptr, 1); end if; 11 $ if first procedure is to be suppressed, do not write out. 12 if (nsubrs=1)&(sfp_opt) then return; end if; 13 if (voawrt = no) return; $ not writing voa file 14 15 vof = 0; $ routine header 16 vof_code vof = voaasm_code; $ indicate routine header 17 vof_listcode vof = listingcode; $ default code list mode at start 18 vof_asmarg vof = 0; 19 vof_init vof = voafnct; 20 vof_lablistptr vof = lablistptr; 21 vof_sub1 vof = subinfo(1); $ copy subinfo array 22 vof_sub2 vof = subinfo(2); 23 vof_sub3 vof = subinfo(3); 24 vof_subrargs vof = argct; $ indicate number of arguments. 25 vof_ha0 vof = ha_0; $ ha index of constant 0. 26 vof_ha1 vof = ha_1; $ ha index of constant 1. 27 vofhdrseq = vofhdrseq+1; vof_hdrseq vof = vofhdrseq; 28 write voafile, vof; 29 30 vof = 0; 31 call putvhdr(voa, 1, voptr, voasz, voa_code); $ write voa 32 write voafile, voa(1) to voa(voptr); 33 34 call putvhdr(names, 1, namesptr, ws, names_code); $ write -names 35 write voafile, names(1) to names(namesptr); 36 37 call putvhdr(xarg, 1, xargptr, xargsz, xarg_code); 38 write voafile, xarg(1) to xarg(xargptr); 39 40 call putvhdr(mba, 1, mbaptr, mbasz, mbacode); 41 write voafile, mba(1) to mba(mbaptr); 42 43 call putvhdr(val, 1, valptr, ws, val_code); $ write -val- 44 write voafile, val(1) to val(valptr); 45 46 $ now write out ha. since ha hashed, we pack ha into 47 $ linear array, recording in field -zerents- the number 48 $ of empty (all 0) entries preceeding each non-zero entry. 49 $ an extra-field is written in header, giving alvue of hamax as 50 $ usedin writer, so asm can check validity of hamax val on read. 51 $ now pack ha, hp points to last value in packed form 52 size hp(ps); $ alst entry in packed ha 53 nzwds = 0; $ number of zero entries before current one 54 hp = 0; 55 do i = 1 to hamax; 56 if var ha(i) = 0 $ ignore empty and non-variables. 57 then nzwds = nzwds + 1; 58 else zerents ha(i) = nzwds; nzwds = 0; 59 hp = hp+1; ha(hp) = ha(i); $ move done packed 60 end if; 61 end do; 62 $ now write remaining zero entries at top of ha 63 if nzwds then 64 haent = 0; zerents haent = nzwds-1; 65 hp = hp + 1; ha(hp) = haent; end if; 66 vof = 0; $ clear frame 67 vof_hamax vof = hamax; $ indicate -hamax- in wrtie phase 68 vof_code vof = ha_code; $ code for array 69 vof_es vof = hasz; $ entry size 70 vof_lo vof = 1; $ first entry 71 vof_hi vof = hp; $ last entry 72 vofhdrseq = vofhdrseq+1; vof_hdrseq vof = vofhdrseq; 73 write voafile, vof; $ write header frame. 74 write voafile, ha(1) to ha(hp); 75 76 vof = 0; vof_code vof = eos_code; 77 vofhdrseq = vofhdrseq+1; vof_hdrseq vof = vofhdrseq; 78 write voafile, vof; $ write frame marking end of routine 79 80 end subr assembl; 1 .=member putvhdr 2 subr putvhdr(ara, lo, hi, es, acode); $ put array to voa-file 3 $ write ara(lo) to ara(hi) to voa-file. entries are -es- bits 4 $ long. -acode- is integer code for array. 5 $ construct header frame and call -wtrvoahdr- to write array dat 6 7 size ara(ws); $ true size is -e-s. is array to write 8 size lo(ps); $ first entry to write 9 size hi(ps); $ last entry to write 10 size acode(ps); $ array code 11 size es(ps); $ entry size in bits 12 vof = 0; $ clear header frame 13 vof_code vof = acode; 14 vof_lo vof = lo; vof_hi vof = hi; 15 vof_es vof = es; $ entry size in bits 16 vofhdrseq = vofhdrseq+1; vof_hdrseq vof = vofhdrseq; 17 write voafile, vof; 18 19 end subr putvhdr; 1 .=member ermet 2 subr ermet; $ syntactic error message output routine 3 $ issue error message after checking for unexpected error 4 $ number. call -lstlin- to list last line read if it has not 5 $ yet been listed. increment error total count -nerrors-. 6 size synstr(.sds. 15); $ error message text. 7 8 argptr = 1; opstackp = 0; $ reset arrays. 9 10 $ if this was in the middle of an opener for an statement other 11 $ than an -if- statement, flush this -csa- entry. 12 if (toknum csa(csaptr) = 0 & cstype csa(csaptr) ^= cstype_if) 13 csaptr = csaptr-1; 14 15 terml(yes); $ give output to terminal too 16 call lstlin; 17 nerrors = nerrors + 1; $ update error count mgfc 15 .+s10 error_s10; $ give s10 error character. 18 textl(error_notice) 19 20 if ermsgno<1 ! ermsgno>parseerrmax then 21 tintl('syntactic error',ermsgno) endl 22 go to return; 23 else 24 go to e(ermsgno) in 1 to parseerrmax; 25 end if; 26 27 +* et (erform, ertext) = 28 call ermlst(erform, ertext); go to return; ** 29 $ new parser syntactic error messages 30 / e(1) / 31 / e(2) / 32 / e(3) / 33 $ these three error messages occur for many extractors. we 34 $ must therefore print out the correct extractor. 35 if parsereg(3) = 2 then 36 synstr = '.f. i1, i2, '; 37 elseif parsereg(3) = 3 then 38 synstr = '.e. i1, i2, '; 39 elseif parsereg(3) = 4 then 40 synstr = '.s. i1, i2, '; 41 else $ must be 5. 42 synstr = '.ch. i1, '; 43 end if; 44 45 $ now print appropriate text. 46 if ermsgno = 3 then 47 et(synstr, 'expression') 48 elseif ermsgno = 2 then 49 et(synstr, 'comma') 50 else $ must be 1. 51 et(synstr !! 't', 'term for extraction') 52 end if; 53 54 / e(4) / et('', 'control format item') 55 / e(5) / et('', 'data format item') 56 / e(6) / et('', 'data format item') 57 / e(7) / et('', 'data item in i/o list') 58 / e(8) / et('', 'expression after binary operator') 59 / e(9) / et('', 'expression in format item') 60 / e(10) / et('', 'file attribute in ''file'' statement') 61 / e(11) / et('', 'parameter in ''monitor'' statement') 62 / e(12) / et('', 'right parenthesis in format item') 63 / e(13) / et('', 'semicolon') 64 / e(14) / et('', 'statement to begin with name') 65 / e(15) / et('', 'term after unary operator') 66 / e(16) / et('', 'valid statement beginning') 67 / e(17) / et('/l(c1)/', 'expression') 68 / e(18) / et('/l(c1)/', 'right parenthesis') 69 / e(19) / et('/l1/', 'closing slash') 70 / e(20) / et('/l1/', 'label name') 71 / e(21) / et('(e1)', 'expression') 72 / e(22) / et('(e1)', 'right parenthesis') 73 / e(23) / et('(n1,...,n9)', 'right parenthesis') 74 / e(24) / et('access n1', 'name') 75 / e(25) / et('assert e1', 'expression') 76 / e(26) / et('attr = val', 'equal sign') 77 / e(27) / et('attr = val', 'expression') 78 / e(28) / et('call n1', 'procedure name') 79 / e(29) / et('call n1(e1,...,e9)', 'expression') 80 / e(30) / et('call n1(e1,...,e9)', 'right parenthesis') 81 / e(31) / et('check index', '''index''') 82 / e(32) / et('data n1 = c1', 'equal sign') 83 / e(33) / et('data n1 = c1', 'expression') 84 / e(34) / et('data n1 = c1', 'name') 85 / e(35) / et('data n1(c1) = c2', 'index expression') 86 / e(36) / et('data n1(c1) = c2', 'right parenthesis') 87 / e(37) / et('data v1 = c1(c2)', 'repetition expression') 88 / e(38) / et('data v1 = c1(c2)', 'right parenthesis') 89 / e(39) / et('dims n1(c1)', 'expression') 90 / e(40) / et('dims n1(c1)', 'left parenthesis') 91 / e(41) / et('dims n1(c1)', 'name') 92 / e(42) / et('dims n1(c1)', 'right parenthesis') 93 / e(43) / et('do v1 = e1 to e2', '''to''') 94 / e(44) / et('do v1 = e1 to e2', 'equal sign') 95 / e(45) / et('do v1 = e1 to e2', 'initial expression') 96 / e(46) / et('do v1 = e1 to e2', 'limit expression') 97 / e(47) / et('do v1 = e1 to e2', 'loop variable name') 98 / e(48) / et('do v1 = e2 to e2 by e3', 'expression after ''by''') 99 / e(49) / et('elseif e2 then', '''then''') 100 / e(50) / et('elseif e2 then', 'expression') 101 / e(51) / et('e1,...,e9', 'expression') 102 / e(52) / et('file fid', 'expression') 103 / e(53) / et('filestat(fid, scode)', 'comma') 104 / e(54) / et('filestat(fid, scode)', 'expression') 105 / e(55) / et('filestat(fid, scode)', 'keyword') 106 / e(56) / et('filestat(fid, scode)', 'left parenthesis') 107 / e(57) / et('filestat(fid, scode)', 'right parenthesis') 108 / e(58) / et('fnct n1', 'procedure name') 109 / e(59) / et('get formlist', 'format list') 110 / e(60) / et('go to n1(e1) in c1 to c2', '''in''') 111 / e(61) / et('go to n1(e1) in c1 to c2', '''to''') 112 / e(62) / et('go to n1(e1) in c1 to c2', 'expression') 113 / e(63) / et('go to n1(e1) in c1 to c2', 'limit expression') 114 / e(64) / et('go to n1(e1)', 'expression') 115 / e(65) / et('go to n1(e1)', 'right parenthesis') 116 / e(66) / et('go to sl', '''to''') 117 / e(67) / et('go to sl', 'label name') 118 / e(68) / et('goby (e1)(l1,...,l9)', 'expression') 119 / e(69) / et('goby (e1)(l1,...,l9)', 'right parenthesis') 120 / e(70) / et('goby n1(l1,...,l9)', 'label name') 121 / e(71) / et('goby n1(l1,...,l9)', 'left parenthesis') 122 / e(72) / et('goby n1(l1,...,l9)', 'name') 123 / e(73) / et('goby n1(l1,...,l9)', 'right parenthesis') 124 / e(74) / et('if e1', 'expression') 125 / e(75) / et('monitor limit = e1', 'equal sign') 126 / e(76) / et('monitor limit = e1', 'expression') 127 / e(77) / et('nameset n1', 'name') 128 / e(78) / et('n1,...,n9', 'name') 129 / e(79) / et('prog n1', 'procedure name') 130 / e(80) / et('put formlist', 'format list') 131 / e(81) / et('read fid', 'expression') 132 / e(82) / et('real n1', 'name') 133 / e(83) / et('rewind fid', 'expression') 134 / e(84) / et('size n1(c1)', 'expression') 135 / e(85) / et('size n1(c1)', 'left parenthesis') 136 / e(86) / et('size n1(c1)', 'name') 137 / e(87) / et('size n1(c1)', 'right parenthesis') 138 / e(88) / et('subr n1', 'procedure name') 139 / e(89) / et('subr n1(n2,..)', 'parameter name') 140 / e(90) / et('trace type', 'type of trace statement') 141 / e(91) / et('until e1', 'expression') 142 / e(92) / et('v1 = e1', 'equal sign') 143 / e(93) / et('v1 = e1', 'expression') 144 / e(94) / et('v1 = e1', 'assignment target') 145 / e(95) / et('v1(e1) to v1(e2)', 'name after ''to''') 146 / e(96) / et('v1(e1)', 'expression') 147 / e(97) / et('v1(e1)', 'right parenthesis') 148 / e(98) / et('v1(i1) = e1', 'right parenthesis') 149 / e(99) / et('v1(i1) = e1', 'subscript expression') 150 / e(100)/ et('while e1', 'expression') 151 / e(101)/ et('write fid', 'expression') 152 / e(102)/ 153 / e(103)/ 154 $ these two error messages are converted to errors 2 and 3. 155 ermsgno = ermsgno - 100; $ convert error number. 156 parsereg(3) = parsereg(7); $ get type of extractor. 157 go to e(2); $ process like errors 2 and 3. 158 159 /return/ 160 call squeeze; $ list recent tokens 161 162 if nerrors > pelvalue then $ quit if too many errors. mgfc 16 endl mgfc 17 .+s10 error_s10; $ give s10 error character. mgfc 18 textl(error_notice) 164 textl('error limit of ') intl(pelvalue) 165 textl(' exceeded. compilation aborted.') endl endl 166 call genexit; end if; 167 168 terml(no); $ done with terminal output 169 170 macdrop(parseerrmax) 171 end subr ermet; $ of syntactic error printer 1 .=member ermlst 2 subr ermlst(erform,ertext); $ list error message fragment 3 $ this routine, called only from ermet, lists part of syntactic 4 $ error message. 5 size erform(ws+1); $ text giving position in parse 6 size ertext(ws+1); $ text for diagnostic 7 8 textl('expect ') textl(ertext) 9 if slen erform then $ there is a construct text. 10 textl(' in construct ''') textl(erform) textl('''.') 11 else 12 textl('.') 13 end if; 14 15 endl 16 17 end subr ermlst; 1 .=member ermes 2 subr ermes(n); $ semantic error message routine 3 size types(.sds. 7); dims types(cstypes); 4 data types(cstype_nameset) = 'nameset': 5 types(cstype_prog) = 'prog': 6 types(cstype_subr) = 'subr': 7 types(cstype_fnct) = 'fnct': 8 types(cstype_do) = 'do': 9 types(cstype_while) = 'while': 10 types(cstype_until) = 'until': 11 types(cstype_if) = 'if'; 12 13 +* ender = go to return;** 14 $ error message subroutine 15 16 size n(ps); $ error number 17 posa 1 $ avoid comparand error message for m11 for now. posa 2 if ((n=5) & (targetmachine=m11)) return; 18 terml(yes); $ write error message to terminal file 19 call lstlin; $ list input line. dst 28 if (n=5 & targetmachine=m11) ! n=15 ! n=70 ! n=71 then mgfc 19 .+s10 warn_s10; $ give s10 warn character. 21 textl(warning_notice) nwarnings = nwarnings + 1; 22 else mgfc 20 .+s10 error_s10; $ give s10 error character. 23 textl(error_notice) 24 nerrors = nerrors + 1; 25 end if; 26 dss 51 +* maxerrors = 71 ** $ maximum number of errors 28 if (n < 1 ! n > maxerrors) go to l(1); 29 go to l(n) in 1 to maxerrors; 30 $ we allow room for up to 60 error messages 31 $ unused slots branch to l(1), to list short text and number. 32 / l( 1) / textl('semantic error number ') intl(n) ender 33 / l( 2) / textl('expect data for ''') naml(ermesarg) 34 textl(''' to be in routine defining it.') ender 35 / l( 3) / go to l(1); 36 / l( 4) / textl('expect positive value.') ender dst 29 / l( 5) / textl('comparison operand is multi-word') ender; 38 / l( 6) / textl('expect positive replication value.') ender 39 / l( 7) / if preludefg then 40 ntexterr = yes; 41 textl('expect subr, fnct, or eof to immediately ') 42 textl('follow routine.') 43 else 44 textl('expect ''') naml(ermesarg) 45 textl(''' to be sized.') 46 end if; 47 ender 48 / l(8) / textl('expect less than') intl(xargmax+1) 49 textl(' parameters or data statement entries.') ender 50 / l(9) / textl('s-type strings not valid on selected target machine.') 51 ender ldsd 34 / l(10) / textl('expect real constant to be in range.') ender 53 / l(11) / go to l(1); 54 / l(12) / textl('expect inputs to string comparison not to be reals.') 55 ender 56 / l(13) / textl('expect constant with size less than') intl(szmax+1) 57 textl('.') ender 58 / l(14) / textl('expect label to be defined only once.') ender pre 1 / l(15) / textl('expect no logical expressions on reals.')endl return; 61 / l(16) / textl('expect limit value to be in range.') ender 62 / l(17) / textl('expect nameset ''') naml(ermesarg) 63 textl(''' to be defined.') ender 64 / l(18) / textl('expect dimension to be less than ') intl(dimsmax+1) 65 textl('.') ender 66 / l(19) / if (preludefg) go to l(7); 67 textl('expect function ''') naml(ermesarg) 68 textl(''' to be sized.') ender 69 / l(20) / 70 / l(21) / go to l(1); 71 / l(22) / textl('expect file attribute to be defined only once.') 72 ender 73 / l(23) / textl('expect recognizable file attribute.') ender 74 / l(24) / textl('expect control format item.') ender 75 / l(25) / textl('expect data format item.') ender 76 / l(26) / textl('namelist format not valid on input.') ender 77 / l(27) / textl('expect nameset format to be applied to variable.') 78 ender 79 / l(28) / textl('expect function argument ''') naml(ermesarg) 80 textl(''' not to be changed.') ender 81 / l(29) / go to l(1); 82 / l(30) / textl('expect ''') naml(ermesarg) textl(''' to be in ') 83 textl('argument list only once.') ender 84 / l(31) / textl('-xha- is full. compilation aborted.') ender 85 / l(32) / textl('expect size value less than ') intl(szmax+1) 86 textl('.') ender 87 / l(33) / textl('expect ''') naml(ermesarg) 88 textl(''' to be a function.') ender 89 / l(34) / textl('expect ''') naml(ermesarg) 90 textl(''' to be a subroutine.') ender 91 / l(35) / textl('expect ''='' after ''^'' in binary operation.') 92 ender 93 / l(36) / go to l(1); 94 / l(37) / textl('expect ''quit'' to refer to loop') ender 95 / l(38) / textl('expect ''cont'' to refer to loop') ender 96 / l(39) / go to l(1); 97 / l(40) / textl('expect ''') naml(ermesarg) 98 textl(''' to be an array.') ender 99 / l(41) / textl('expect ''then'' in ''if'' statement.') ender 100 / l(42) / textl('expect constant expression.') ender 101 / l(43) / textl('expect tokens to match those in ''') 102 /csatell/ 103 textl(types(cstype csa(ermesarg))) textl(''' at line') 104 intl(firstst csa(ermesarg)) textl('.') ender 105 / l(44) / textl('expect operands of same arithmetic mode.') ender 106 / l(45) / textl('expect constant mode data statement.') ender 107 / l(46) / textl('expect datum in io statement.') ender 108 / l(47) / textl('expect label index to be in range.') ender 109 / l(48) / textl('expect labels in ''go to'' to be in ascending order') 110 ender 111 / l(49) / textl('expect ''') naml(ermesarg) 112 textl(''' to be used as an array.') ender 113 / l(50) / textl('expect ''then'' or ''elseif'' before ''elseif''') 114 ender 115 / l(51) / textl('expect ''') naml(ermesarg) 116 textl(''' to be global.') ender 117 / l(52) / textl('-ha- is full. compilation aborted.') ender 118 / l(53) / textl('expect operands to .pad. to be constants.') ender 119 / l(54) / textl('expect ''') naml(ermesarg) 120 textl(''' to be dimensioned only once.') ender 121 / l(55) / go to l(1); 122 / l(56) / textl('expect ''') naml(ermesarg) 123 textl(''' to be sized only once.') ender 124 / l(57) / textl('expect only monitoring statements in interlude.') 125 ender 126 / l(58) / textl('name list not valid in this context.') ender 127 / l(59) / textl('expect main program not to have arguments.') ender 128 / l(60) / textl('expect ''end'' for ''') go to csatell; 129 / l(61) / textl('extraneous ''end'' statement.') ender 130 / l(62) / textl('expect only one ''else'' per ''if''.') ender 131 / l(63) / textl('invalid combination of file attributes in ''file'' ') 132 textl('statement.') ender 133 / l(64) / textl('expect arguments to .cc. to be strings.') ender 134 / l(65) / textl('-arglist- overflow. compilation aborted.') ender 135 / l(66) / textl('function ''') naml(ermesarg) 136 textl(''' used as variable.') ender 137 / l(67) / textl('expect only one dimensional array references.') ender 138 / l(68) / textl('expect correct number of arguments to built-in ') 139 textl('function.') ender 140 / l(69) / textl('reals not supported for selected target machine.') 141 ender dss 52 / l(70) / textl('temporary size too large, size truncated.') ender dss 53 / l(71) / textl('subscript size exceeds') intl(cis_opt) ender 142 /return/ 143 endl 144 call squeeze; $ list recent tokens 145 if nerrors>pelvalue then $ quit if too many errors. mgfc 21 endl mgfc 22 .+s10 error_s10; $ give s10 error character. mgfc 23 textl(error_notice) 147 textl('error limit of ') intl(pelvalue) 148 textl(' exceeded. compilation aborted.') endl endl 149 call genexit; end if; 150 terml(no); $ done with terminal output 151 152 macdrop(maxerrors) 153 end subr ermes; 1 .=member ermey 2 subr ermey(n); $ terminal error message routine 3 size n(ps); $ error number 4 5 terml(yes); $ write output to terminal 6 if n ^= 9 then $ not -nextok- error 7 call lstlin; $ list input line. 8 end if; 9 textl(system_notice) 10 +* maxerrors = 9 ** 11 if (n < 1 ! n > maxerrors) go to l(1); 12 go to l(n) in 1 to maxerrors; 13 +* em = go to exit; ** 14 / l(1) / textl('terminal error message number ') intl(n) em 15 / l(2) / textl('parse control stack underflow') em 16 / l(3) / textl('-bronlit- index out of range') em 17 / l(4) / textl('compiler not handling expressions correctly') em 18 / l(5) / textl('-opstack- underflow - expression') em 19 / l(6) / textl('-opstack- underflow - operator') em 20 / l(7) / textl('logic error in -gendat-') em 21 / l(8) / textl('illegal constant type') em 22 / l(9) / textl('bad token lexical type') em 23 macdrop(em) macdrop(maxerrors) 24 /exit/ 25 endl call squeeze; 26 terml(no); $ done with output to terminal 27 call genexit; $ abort - fatal error 28 29 end subr ermey; 30 31 1 .=member ctcat 2 subr ctcat(resat, a1, a2); 3 $ routine to check for .cc. on constants 4 size a1(ps), a2(ps), resat(ps); $ inputs and output 5 size arg(ps); dims arg(2); $ array of arguments 6 size l(ps); dims l(2); $ array of lengths 7 size i(ps), j(ps); $ do loop variables 8 9 arg(1) = a1; arg(2) = a2; resat = 0; $ set initial values 10 do i = 1 to 2; $ process each argument 11 if (var ha(arg(i)) = no) go to ret; $ no good if temp 12 if (const voa(ep ha(arg(i))) = no) go to ret; $ not const 13 if (lextype voa(ep ha(arg(i))) ^= strtok) go to ret; 14 l(i) = nchars ha(arg(i)); $ set string length 15 end do; 16 17 if l(1)*l(2) = 0 then $ if either null, return other 18 if (l(1) = 0) resat = a2; 19 if (l(2) = 0) resat = a1; 20 go to ret; 21 end if; 22 23 $ if result too long, return not constant 24 if (l(1)+l(2) > toklenmax-cpw) go to ret; 25 26 $ now do concatenation 27 ccaptr = 0; $ start at begining of array 28 do i = 1 to 2; $ place each string into array 29 $ first, move into -sdsnamstr- 30 do j = 1 to (l(i)-1)/cpw+1; $ move a word at a time 31 .f. nameorg-ws*j, ws, sdsnamstr = 32 val(vbeg voa(ep ha(arg(i)))+j-1); 33 end do; 34 slen sdsnamstr = l(i); $ set length of string 35 $ now, unpack into -cca- 36 do j = 1 to l(i); 37 ccaptr = ccaptr+1; cca(ccaptr) = .ch. j, sdsnamstr; 38 end do; 39 end do i; 40 41 $ finally, build and hash in new constant 42 cclt = strtok; call cnvcon; 43 call inscon(resat); 44 45 /ret/ 46 end subr ctcat; 47 1 .=member squeeze 2 subr squeeze; $ list recent tokens 3 size i(ps); $ index in lexlist 4 size n(ps); $ number listed 5 size l(ps); $ number of chars to list. 6 +* dstrlen = $ maximum number of chars to list. vax 210 .+s32 8 7 .+s37 8 utsa 294 .+s47 8 8 .+s66 10 dso 111 .+s10 12 $ 2*cpw 10 ** 11 size dstr(.sds. dstrlen); $ display string. 12 13 dstr = '' .pad. dstrlen; $ initialize. 14 15 skipl(15) textl('last few tokens: ') 16 i = lexlistptr-1; $ set to start 17 n = 0; 18 while 1; 19 i = (i+1) & (lexlistmax-1); $ bump i, modulo lexlistmax 20 n = n+1; if (n>lexlistmax) quit while; 21 if (lexlist(i+1) = 0) cont while; $ ignore if not set 22 charl(1r ); 23 l = lexleng(i+1); if (l>dstrlen) l = dstrlen; 24 slen dstr = l; 25 .f. (.sds. dstrlen)+1-ws, ws, dstr = lexlist(i+1); dso 112 .+s10. dso 113 $ on s10, use up two lexlist entries. dso 114 i = (i+1) & (lexlistmax-1); n = n + 1; dso 115 .f. (.sds. dstrlen)+1-2*ws, ws, dstr = lexlist(i+1); dso 116 ..s10 vax 211 .+s32. $ on s32, use up to two lexlist entries. vax 212 i = (i+1) & (lexlistmax-1); n = n + 1; vax 213 .f. (.sds. dstrlen)+1-2*ws, ws, dstr = lexlist(i+1); vax 214 ..s32 26 .+s37. $ on s37, use up to two lexlist entries. 27 i = (i+1) & (lexlistmax-1); n = n + 1; 28 .f. (.sds. dstrlen)+1-2*ws, ws, dstr = lexlist(i+1); 29 ..s37 utsa 295 .+s47. $ on s47, use up to two lexlist entries. utsa 296 i = (i+1) & (lexlistmax-1); n = n + 1; utsa 297 .f. (.sds. dstrlen)+1-2*ws, ws, dstr = lexlist(i+1); utsa 298 ..s47 30 textl(dstr) 31 end while; 32 endl 33 listl(listsw=no) endl listl(yes) 34 35 macdrop(dstrlen); 36 end subr squeeze; 1 .=member findcsa 2 subr findcsa(csap, typ); $ find -csa- entry. 3 $ this routine finds the -csa- pointer whose opener most closely 4 $ matches the tokens on the statement being scanned. -typ- is n 5 $ not set for -quit- and -cont- where only a loop is being 6 $ searched for. 7 size csap(ps); $ return index. 8 size typ(1); $ type parameter. 9 size csap1(ps); $ approximate match. 10 size i(ps), j(ps); $ temporaries. 11 size org(ps); $ origin in -csatoks-. 12 size toks(ps), typs(1); $ opener information. 13 dims toks(cstypes), typs(cstypes); 14 15 +* tt(cst, tok, tp) = $ initialize -toks- and -typs-. 16 toks(cst) = tok: typs(cst) = tp ** 17 18 data $ initialize tables. 19 tt(cstype_subr, lc_subr, yes): 20 tt(cstype_fnct, lc_fnct, yes): 21 tt(cstype_prog, lc_prog, yes): 22 tt(cstype_while, lc_while, no): 23 tt(cstype_until, lc_until, no): 24 tt(cstype_do, lc_do, no): 25 tt(cstype_if, lc_if, yes): 26 tt(cstype_nameset, lc_nameset,yes); 27 28 macdrop(tt) 29 30 size lc(ps); $ literal code of first token. 31 size ntoks(ps); $ number of tokens after first. 32 size stoks(ws); dims stoks(5); $ succeding tokens. 33 34 $ first, show that there were no matches. 35 csap = 0; csap1 = 0; $ clear both pointers. 36 37 $ next, get first token. 38 if (keeptok = no) call nextok; $ get next token. 39 lc = toklc; $ save its literal code. 40 ntoks = 0; $ show no more tokens yet. 41 if lc ^= lc_semicolon then $ scan for more if not end. 42 do ntoks = 1 to 5; $ scan forwards. 43 call nextok; $ get next token. 44 stoks(ntoks) = tokara(1); $ get first token word. 45 if (toklc = lc_semicolon) quit do; $ stop at semicolon. 46 end do; 47 48 ntoks = ntoks-1; $ allow for last. 49 end if; 50 51 do i = csaptr to 1 by -1; $ now scan looking for match. 52 if (typs(cstype csa(i)) > typ) cont do; $ not eligable. 53 if (lc ^= lc_semicolon & lc ^= toks(cstype csa(i))) cont do; 54 55 $ we now have an entry whose first tokens match. this is 56 $ saved as best so far. 57 csap1 = i; $ save for later analysis. 58 59 $ now compare the rest of the tokens. 60 if (ntoks > toknum csa(i)) cont do; $ too many tokens given. 61 org = tokorg csa(i) - 1; $ set to one below origin. 62 do j = 1 to toknum csa(i); $ scan all tokens in original. 63 if (j > ntoks) quit do i; $ found match. 64 if (stoks(j) ^= csatok(org+j)) cont do i; $ no match. 65 end do; 66 67 quit do i; $ we have a match. 68 end do; 69 70 csap = i; $ set return value. 71 72 $ now, if no perfect match was found and a close match was found 73 $ give an error message and use the close match. 74 if csap = 0 & csap1 ^= 0 then $ use close match. 75 ermesarg = csap1; call ermes(43); $ print error message. 76 csap = csap1; $ use close match. 77 end if; 78 79 end subr findcsa; 1 .=member closer 2 subr closer; $ close last opened opener. 3 $ this routine closes the last opened opener. the action 4 $ taken depends on the type of opener. 5 size csam(csasz); $ -csa- entry being closed. 6 size arithop(ps); $ arithmetic operation to issue. 7 size comop(ps); $ comparison operation to issue. 8 size i(ps); $ temporary. 9 size hap(ps); $ pointer to -ha-. 10 11 csam = csa(csaptr); $ extract entry to close. 12 go to l(cstype csa(csaptr)) in 1 to cstypes; $ select action. 13 14 /l(cstype_nameset)/ 15 $ for a nameset, just rest nameset to use. 16 nstouse = oldmblk csam; go to ret; 17 18 /l(cstype_while)/ /l(cstype_until)/ 19 $ for -while- and -until- generate go to body; /end/ 20 push(testlbl csam); call gengol(op_goto); 21 labdef(endlbl csam); go to ret; 22 23 /l(cstype_if)/ 24 $ unless this is a -then-, define end label. 25 if csiftype csam ^= csiftype_then then 26 labdef(endlbl csam); 27 end if; 28 29 $ now unless this is an -else-, define the body label. 30 if csiftype csam ^= csiftype_else then 31 if trflowfg then $ flow tracing. 32 trflow(flowifnsf); $ generate trace code. 33 else $ just define body label. 34 labdef(bodylbl csam); 35 end if; 36 end if; 37 38 go to ret; $ done. 39 40 41 /l(cstype_do)/ 42 $ generate test label if referenced. 43 if testlbl csam then labdef(testlbl csam); end if; 44 45 $ now select the arithmetic and comparison operations 46 $ depending on the sign of the increment. 47 if dosignp csam 48 then arithop = op_sub; comop = op_ge; $ sign was -. 49 else arithop = op_add; comop = op_le; end if; $ sign +. 50 51 $ now generate the increment (decrement). 52 push(dovarp csam) push(dovarp csam) push(doincp csam) 53 call arith(arithop); call genasin(1, 0); 54 55 $ now generate the test and branch to body label. 56 push(dovarp csam); push(dohip csam); call arith(comop); 57 push(bodylbl csam); call genifgo(op_if); 58 59 $ now define the end label. 60 labdef(endlbl csam); 61 62 $ finally, must rest the busy bits for any obtained -do- variabl 63 hap = dohip csam; $ start with high index. 64 while yes; $ loop until quit. 65 if namintern ha(hap) then $ this was internal. 66 do i = 1 to dovarptr; $ find spot. 67 if dovars(i) = hap then 68 .f. i, 1, dovarbusy = no; $ show not busy. 69 quit do; $ done with scan. 70 end if; 71 end do; 72 end if; 73 74 $ now if this was increment, done. 75 if (hap = doincp csam) quit while; 76 77 hap = doincp csam; $ else set to increment. 78 end while; 79 80 go to ret; $ done with this case. 81 82 83 /l(cstype_subr)/ /l(cstype_fnct)/ /l(cstype_prog)/ 84 $ first, list last line if not already listed. 85 if (listsw) call lstlin; $ -lstlin- does nothing if listed. 86 dsz 8 $ if function, check that function has been sized. dsz 9 if fswitch then $ if function dsz 10 if syze voa(voafnct) = 0 then $ if unsized dsz 11 ermesarg = subinfo(1); $ copy ha index. dsz 12 call ermes(19); dsz 13 end if; dsz 14 end if; dsz 15 87 $ now check for undefined labels. 88 terml(yes) $ in case there are error messages. 89 do i = 1 to lablistptr; $ scan all labels. 90 if (labvoa lablist(i)) cont do; $ label is defined. 91 if (namintern ha(labha lablist(i))) cont do; $ internal labe 92 nerrors = nerrors+1; $ increment error count. mgfc 24 .+s10 error_s10; $ give s10 error character. 93 textl(error_notice) textl('expect label ''') 94 naml(labha lablist(i)) textl(''' to be defined.') endl 95 end do; 96 97 $ now compute and print error statistics. 98 erthis = nerrors - erprev; erprev = nerrors; 99 warnthis = nwarnings - warnprev; warnprev = nwarnings; 100 101 if erthis ^= 0 ! warnthis ^= 0 then 102 listl(listsw=no) endl listl(yes) $ conditionally print a blan 103 end if; 104 105 if erthis then $ print error count. 106 textl('******* ') intl(erthis) textl(' errors detected in ''') 107 textl(currsubrname) textl('''.') endl 108 end if; 109 110 if warnthis then $ print number of warnings. 111 textl('******* ') intl(warnthis) textl(' warnings in ''') 112 textl(currsubrname) textl('''.') endl 113 end if; 114 115 if erthis ^= 0 ! warnthis ^= 0 then endl endl end if; 116 terml(no) $ stop writing to terminal. 117 118 call genret; $ generate return statement. 119 call blkend; $ end the basic block. 120 call sortvars; $ allocate local storage. 121 call assembl; $ write out a -voa- file. 122 call purge; $ clear tables for next time. 123 124 /ret/ 125 csatokptr = tokorg csam - 1; $ reset pointer. 126 csaptr = csaptr - 1; $ pop -csa-. 127 128 end subr closer; 1 .=member arith 2 subr arith(op); $ generator for binary operations 3 $ retrieve arguments from argstack. if both are constants 4 $ then try to perform operation at compile time. if arguments 5 $ same or one of them is the constant 0 or the constant 1, try 6 $ to find a formal identity, as encoded in the table -fidtab-. 7 $ check for mixed-mode arithmetic (reals and non-reals),as 8 $ well as unexpected operations ,such as .or.) on reals. 9 $ if a computation can be performed at compile time, see if 10 $ negative result is acceptable. if so, keep constant in sign 11 $ and magnitude form, with -signbit- in -voa- noting negative 12 $ sign. 13 size resat(ps); $ ha index of result 14 size op(ps); $ opcode as received 15 size opcd(ps); 16 size realops(ps); 17 size s1(ps), s2(ps); $ sizes of inputs. 18 size v(ws); 19 size v1(ws); 20 size v2(ws); 21 size a1(ps), a2(ps); $ ha indexex of inputs. 22 size ibsize(ps); $ constant size in bits 23 size am1(ps), am2(ps); $ arithmetic modes of inputs 24 size fidc(ps); $ case for formal identity search 25 26 $ formal identities are encoded in the table -fidtab-. 27 $ the result is encoded as follows: 28 $ 0 - result is constant 0, 29 $ 1 - result is constant 1, 30 $ 2 - result is the non-constant input 31 $ 3 - result must be computed. 32 $ at most one input is assumed to be constant 1 or 0, as case 33 $ where both inputs constants handled by constant folding. 34 35 $ it is left as an exercise to the zealous implementor to extend 36 $ search for formal identities to real numbers, and perhaps even 37 $ standard functions. 38 39 size fidtab(20); dims fidtab(op_sne); 40 41 $. 4. 3. 2. 1. 0. (fidc value) 42 $. a1 e e e 1 0 43 $. a2 1 0 e e e 44 data fidtab(op_add ) = 4b'3 2 3 3 2'; $ + 45 data fidtab(op_sub ) = 4b'3 2 0 3 3'; $ - 46 data fidtab(op_mul ) = 4b'2 0 3 2 0'; $ * 47 data fidtab(op_div ) = 4b'2 3 1 3 0'; $ / 48 data fidtab(op_and ) = 4b'3 0 2 3 0'; $ & 49 data fidtab(op_or ) = 4b'3 2 2 3 2'; $ ! 50 data fidtab(op_exor) = 4b'3 2 0 3 2'; $ .ex. 51 data fidtab(op_eq ) = 4b'3 3 1 3 3'; $ = 52 data fidtab(op_ne ) = 4b'3 3 0 3 3'; $ = 53 data fidtab(op_gt ) = 4b'3 3 0 3 3'; $ > 54 data fidtab(op_ge ) = 4b'3 3 1 3 3'; $ >= 55 data fidtab(op_lt ) = 4b'3 3 0 3 3'; $ < 56 data fidtab(op_le ) = 4b'3 3 1 3 3'; $ <= 57 data fidtab(op_seq ) = 4b'3 3 1 3 3'; $ .seq. 58 data fidtab(op_sne ) = 4b'3 3 0 3 3'; $ .sne. 59 60 dims realops (10); $ map from integer into reals 61 data realops = rop_add, rop_sub, rop_gt, rop_lt, rop_ge, 62 rop_le, rop_eq, rop_ne, rop_mul, rop_div; 63 $ corresponds to real + - gt lt ge le eq ne * / 64 opcd = op; 65 pop(a2); pop(a1); $ retrieve two arguments. 66 $ main ordinary operator generator 67 $ uses-emit 2 - routine for code emission 68 call setq(a1); call setq(a2); 69 if op = op_ccat then $ see if .cc. on constants 70 call ctcat(resat, a1, a2); 71 if (resat) go to ret; $ if constant result, done 72 go to normseq; 73 end if; 74 if opcd = op_pad then $ do pad separately. 75 call genpad(resat, a1, a2); 76 go to ret; 77 end if; 78 if(op > op_sne) go to normseq; 79 am1 = amode voa(ep ha(a1)); am2 = amode voa(ep ha(a2)); $ modes 80 if (am1 ! am2) go to real; 81 if (hascon ha(a1) & hascon ha(a2)) go to constfold; dsr 17 $ do not attempt folding if either input multi-word. dsr 18 if (syze voa(ep ha(a1))>mws ! syze voa(ep ha(a2))>mws) dsr 19 go to normseq; 82 if a1=ha_0 ! a1=ha_1 ! a2=ha_0 ! a2=ha_1 ! a1=a2 then 83 $ may have formal identity. 84 fidc = 2; $ assume e op e 85 if (a1=ha_0) fidc = 0; 86 if (a1=ha_1) fidc = 1; 87 if fidc = 2 then 88 if (a2=ha_0) fidc = 3; 89 if (a2=ha_1) fidc = 4; 90 end if fidc = 2; 91 92 go to give (.f. fidc*4 + 1, 4, fidtab(op)) in 0 to 3; 93 /give(0)/ resat = ha_0; go to ret; $ result is constant 0 94 /give(1)/ resat = ha_1; go to ret; $ result is constant 1 95 /give(2)/ 96 if hascon ha(a1) 97 then resat = a2; $ if a1 constant, result is a2 98 else resat = a1; $ result is a1 (the non-constant) 99 end if; 100 go to ret; 101 end if; 102 / give(3) / 103 /normseq/ 104 call emit2(opcd, a1, a2, resat); 105 /ret/ 106 push(resat); 107 return; 108 /real/ 109 if am1 ^= am2 then 110 call ermes(44); 111 resat = ha_1; 112 go to ret; 113 end if; 114 119 .+realsc if (hascon ha(a1) & hascon ha(a2)) go to realconstfold; 120 opcd = realops(op); 121 go to normseq; 122/constfold/ 123 v1 = conval(a1); v2 = conval(a2); 124 s1=.fb. v1 ; s2=.fb.v2; 125 go to l(op) in 1 to 15; 126 / l(op_lt) / v = v1 < v2; go to con1; 127 / l(op_le) / v = v1 <=v2; go to con1; 128 / l(op_gt) / v = v1 > v2; go to con1; 129 / l(op_ge) / v = v1 >=v2; go to con1; 130 / l(op_eq) / v = v1 = v2; go to con1; 131 / l(op_ne) / v = v1 ^=v2; go to con1; 132 / l(op_add) / v = v1 + v2; go to signtest; 133 / l(op_sub) / v = v1 - v2; go to signtest; 134 / l(op_mul) / ibsize = s1 + s2; 135 .+s66 if ibsize>48 then go to normseq; end if; /* 6600 hardware */ 136 v = v1 * v2; go to signtest; 137 / l(op_div) / if (v2=0) go to normseq; $ aboid divide by 0 138 v = v1 / v2; go to signtest; 139 / l(op_and) / v = v1 & v2; ibsize = .fb. v; go to con; 140 / l(op_or) / v = v1 ! v2; ibsize = .fb. v; go to con; 141 / l(op_exor) / v = v1 .exor. v2; ibsize = .fb. v; go to con; 142 / l(op_seq) / 143 / l(op_sne) / 144 $ here for string comparisons; for now just do operation. 145 go to normseq; 146 /con1/ ibsize = 1; go to con; 147 /signtest/ 148 ibsize = .fb. v; 149 if v < 0 then 150 .+ncfstat ncftot = ncftot+1; $ count negative constants 151 if (ncfopt=no) go to normseq; $ if user no wants neg con fold 152 signofcon = yes; ibsize = mws; 153 end if v; 154 155 /con/ 156 $ insert one word constant into ha 157 cclt = dectok; 158 ccsyze = ibsize + (ibsize=0); ccval(1) = v; ccvalptr = 1; 159 call inscon(resat); 160 signofcon = 0; $ reset sign flag to positive 161 go to ret; 162 .+realsc. 163 real r, r1, r2; 164 /realconstfold/ 165 r1 = val(vbeg voa(ep ha(a1))); r2 = val(vbeg voa(ep ha(a2))); 166 go to ro(op) in 1 to 15; 167 / ro(op_lt) / r = r1 < r2; go to rcon1; 168 / ro(op_le) / r = r1 <= r2; go to rcon1; 169 / ro(op_gt) / r = r1 > r2; go to rcon1; 170 / ro(op_ge) / r = r1 >= r2; go to rcon1; 171 / ro(op_eq) / r = r1 = r2; go to rcon1; 172 / ro(op_ne) / r = r1 ^= r2; go to rcon1; 173 / ro(op_add) / r = r1 + r2; go to rcon; 174 / ro(op_sub) / r = r1 - r2; go to rcon; 175 / ro(op_mul) / r = r1 * r2; go to rcon; 176 / ro(op_div) / if (r2=0.0) go to normseq; 177 r = r1 / r2; go to rcon; rcfa 1 / ro(op_and) / rcfa 2 / ro(op_or) / rcfa 3 / ro(op_exor) / rcfa 4 go to normseq; $ don't bother to fold logical ops on reals. 181 / ro(op_seq) / / ro(op_sne) / $ error if string comparison for reals. 182 call ermes(12); 183 go to normseq; 184 /rcon/ 185 cclt = realtok; 186 ccsyze = rlsz; ccval(1) = r; ccvalptr = 1; 187 call inscon(resat); 188 go to ret; 189 190 /rcon1/ 191 cclt = dectok; 192 ccval(1) = v; ccvalptr = 1; 193 ccsyze = 1; call inscon(resat); 194 go to ret; 195 ..realsc 196 end subr arith; 1 .=member marith 2 subr marith(op); $ monadic operator processor 3 size a1(ps); $ pointer to -ha- entry 4 size resat(ps); $ result pointer 5 size op(ps); $ operation code 6 size hap(ps); $ temporary used for .sds. 7 size t(ws); $ integer value 8 size s(ps); $ size of .not. operand. 9 10 pop(a1); call setq(a1); $ get and check operand 11 if op = 1 then $ special case for .len. 12 if const voa(ep ha(a1)) & lextype voa(ep ha(a1))=strtok then 13 pushint(nchars ha(a1)); $ length is constant 14 else 15 $ generate .f. 1, .sl., a1 16 push(ha_1); pushint(msl); push(a1); call genextr(op_fext); 17 end if; 18 return; 19 end if; 20 21 $ if unary plus, just return input. 22 if (op=2) then push(a1); return; end if; 23 if op = op_usub then $ unary minus 24 if amode voa(ep ha(a1)) then 25 .+realsc. 26 real r; 27 if hascon ha(a1) then $ can fold 28 r = conval(a1); r = -r; $ get result 29 cclt = realtok; t = r; go to folded; 30 end if; 31 ..realsc 32 call emit1(rop_usub, a1, resat); 33 go to ret; 34 else 35 push(ha_0); push(a1); call arith(op_sub); 36 return; 37 end if; 38 end if; 39 40 $ now, check for constant values 41 if hascon ha(a1) then $ safe constant 42 t = conval(a1); $ get constant value 43 if op = 0 then $ .sds. 44 t = ((t*mcs+msl+mso+mws-1)/mws)*mws; 45 cclt = dectok; $ set to decimal token 46 elseif op = op_not then $ .not. 47 s = .fb. t; if (s=0) s = 1; $ find size. 48 t = .f. 1, s, (.not. t); cclt = bittok; 49 elseif op = op_nb then $ .nb. 50 t = .nb. t; cclt = dectok; 51 else $ .fb. 52 t = .fb. t; cclt = dectok; 53 end if; 54 /folded/ 55 ccsyze = .fb. t + (t=0); ccval(1) = t; ccvalptr = 1; 56 call inscon(resat); $ insert constant 57 go to ret; 58 end if; 59 60 $ else, emit operation 61 if op = 0 then $ .sds. 62 push(a1); pushint(mcs); call arith(op_mul); 63 pushint(msl+mso+mws-1); call arith(op_add); 64 pushint(mws); call arith(op_div); 65 pushint(mws); call arith(op_mul); 66 else 67 call emit1(op, a1, resat); 68 /ret/ 69 push(resat); $ push result onto stack 70 return; 71 end if; 72 73 end subr marith; 74 75 1 .=member gendebug 2 subr gendebug(case, value); $ generator for -debug- statement 3 size case(ps); $ parameter type 4 size value(1); $ parameter setting 5 size a1(ps); $ -ha- pointer 6 7 if case = 0 then $ initialization/termination 8 if value = 0 then $ initialization 9 dbgparm = 0; dbgchange = 0; $ clear parameters 10 dbgha = 0; $ clear -ha- pointer 11 else dss 54 testdebug; 15 if dbgha then $ must generate code to move 16 call advstr(lvgen, a1); $ build variable dss 55 push(a1) pushint(mws); localforce = yes; 18 call gensiz; $ size variable 19 push(a1) call gendat(2); $ begin data statement 20 pushint(dbgparm); arglist(argptr) = 0; call gendat(4); dss 56 push(ha_1) pushint(mws-4) push(a1) push(dbgha) dss 57 call genasin(2, no); $ generate .f. 1, (.ws.-4), dbgh 23 else 24 pushint(dbgparm); pop(a1); $ get first parameter set 25 end if; 26 pushname(dbgha, debugnames(dbg_setx)); $ push name 27 push(a1); pushint(dbgchange); arglist(argptr) = 1; $ push 28 call gencall(call_parms); $ call routine 29 end if; 30 return; 31 end if; 32 33 if case = 1 then $ special case for line limit 34 if value then $ value given 35 pop(a1); $ get it 36 if hascon ha(a1) then $ if safe constant 37 if .fb. conval(a1) > mps then 38 call ermes(16); $ error 39 return; $ ignore parm 40 end if; dss 58 .f. 1, mws-4, dbgparm = conval(a1); $ set value 42 else 43 dbgha = a1; $ save for later 44 end if; 45 end if; dss 59 .f. 1, mws-4, dbgchange = yes; $ set change flag 47 else $ simple case dss 60 .f. (mws-5)+case, 1, dbgchange = yes; $ set change flag dss 61 .f. (mws-5)+case, 1, dbgparm = value; $ set new value 50 end if; 51 52 end subr gendebug; 53 1 .=member genacc 2 subr genacc; $ process -access- declaration 3 size a1(ps); $ ptr to ha 4 size j(ps); $ do loop index 5 size n(ps); $ number of accessed namesets 6 size nsi(ps); $ nameset number 7 size xhap(ps); $ xha index of nameset name 8 size i(ps); 9 10 $ generator routine called upon parsing an access statement to 11 $ to access nameset 12 13 n = arglist(argptr) + 1; $ number of names 14 argptr = argptr - n; 15 do i = 0 to n - 1; 16 a1 = arglist(argptr + i); $ ith name 17 insglob(xhap, a1); 18 nsi = xnsblk xha(xhap); $ get nameset index in mba 19 if nsi then $ if global variable name, 20 .f. nsi, 1, accesstab = yes; $ grant access, and note 21 mbha mba(nsi) = a1; $ record ha index. 22 else 23 ermesarg = a1; call ermes(17); 24 end if; 25 end do; 26 27 end subr genacc; 1 .=member genasin 2 subr genasin(optyp, indxd); $ process assignment statement. 3 $ generator for all assignment statements. the parameter indxd 4 $ indicates whether the assignment is indexed. the parameter 5 $ optype indicates the operation: 6 $ 1 - simple 7 $ 2 - .f. field 8 $ 3 - .e. field 9 $ 4 - .s. field 10 $ 5 - .ch. field 11 $ 6 - .len. field 12 size indxd(1); $ flag indicating indexed store 13 size optype(ps); $ operation type 14 size optyp(ps); $ operation type as given. 15 size opc(ps); dims opc(12); 16 data opc = $ case to opcode map. 17 op_asin, op_xasin, op_fasin, op_xfasin, op_easin, 18 op_xeasin, op_sasin, op_xsasin, op_fasin, op_xfasin, 19 op_fasin, op_xfasin; 20 size args(ps); dims args(12); 21 data args = $ case to argument count map. 22 2, 2+1, 4, 4+1, 4, 4+1, 4, 4+1, 3, 3+1, 2, 2+1; 23 size nargs(ps); $ number of arguments of operation 24 size j(ps); $ do loop index 25 size a1(ps), a2(ps), a3(ps), a4(ps); $ ha indices for args. 26 27 optype = optyp; 28 nargs = args(2*optype - 1 + indxd); $ get no of args 29 do j = 1 to nargs; $ verify operands 30 call setq(arglist(argptr-j)); $ check input 31 end do; 32 $ if origin and length constant, see if .f. or .e. 33 if (optype=2)!(optype=3) then $ if .e. or .f., 34 chasflg = no; $ ensure flag is off. 35 a1 = arglist(argptr - indxd - 4); $ starting position. 36 a2 = arglist(argptr - indxd - 3); $ field length. 37 if hascon ha(a2) then $ if length constant, 38 if hascon ha(a1) then $ and origin constant, 39 if mod(conval(a1)-1, mws) + conval(a2) > mws then 40 if (optype=2) optype = 3; $ must be .e. 41 else 42 if (optype=3) optype=2; $ may be .f. 43 end if; 44 45 if mod(conval(a2), mcs) = 0 then $ may be character 46 if mod(conval(a1)-1, mcs) = 0 then $ it is chara 47 chasflg = yes; $ is character op 48 end if; 49 end if; 50 else 51 if ((optype=3)&(a2=ha_1)) optype=2; 52 $ (convert .e.,...,1, to .f.,...,1, .) 53 end if; 54 end if; 55 end if; 56 57 if indxd then $ see if check index is in effect 58 if chinxf ha(arglist(argptr-3)) then $ should check this sto 59 call chinxr(arglist(argptr-3), arglist(argptr-2)); 60 end if; 61 end if; 62 go to l(optyp) in 1 to 6; $ select code type 63 64 /l(5)/ $ .ch. - generate .f. (.f. .sl.+1, .so., a2)-cs*a1, cs, a2=a3 65 $ for unindexed case and .f. sorg a2 - cs*a1,cs, a2(a3) = a4 66 $ for indexed case. 67 nargs = nargs + 1; $ convert to .f. operation 68 if indxd then pop(a4); end if; 69 pop(a3); pop(a2); pop(a1); $ retrieve arguments. 70 pushint((msl+1)) $ stack start of sds origin field for a2. 71 pushint(mso) $ field extract length 72 push(a2) 73 if indxd then $ perform indexed load - sorg a2(i) 74 push(a3); call arith(op_xload); 75 end if; 76 77 chasflg = (mod(msl, mcs) = 0 & mod(mso, mcs) = 0); 78 call genextr(op_fext); $ to do extract 79 $ generate voa entry for a1 * cs 80 pushint(mcs) 81 push(a1) 82 call arith(op_mul); 83 call arith(op_sub); $ do subtraction 84 pushint(mcs) 85 push(a2) push(a3) $ target variable, index or source 86 if (indxd) then push(a4); call setq(a4); end if; 87 chasflg = yes; $ show character assigment 88 go to l(1); $ merge to normal code 89 90 /l(6)/ $ .len. - generate .f. 1, .sl., a1 = a2 91 nargs = nargs+2; $ convert to .f 92 if indxd then pop(a3); end if; 93 pop(a2); pop(a1); $ get arguments 94 push(ha_1) pushint(msl) push(a1) push(a2) 95 if indxd then push(a3); end if; 96 chasflg = (msl = mcs); $ set if char. op. 97 $ fall through to generation 98 99 /l(1)/ /l(2)/ /l(3)/ /l(4)/ 100 $ set global parameters for trace routine 101 trstor1 = arglist(argptr - 1); 102 trstor2 = arglist(argptr - 2); 103 trstor3 = arglist(argptr - 3); 104 trstor4 = arglist(argptr - 4); 105 trstor5 = arglist(argptr - 5); 106 trstors = a1; $ for .ch. operation set to fbpos 107 call emass(opc(2*optype - 1 + indxd), nargs); 108 a1 = trstor2; if (indxd) a1 = trstor3; $ get target 109 ermesarg = a1; $ set for possible error message. 110 if argno voa(ep ha(a1)) ^= 0 & fswitch then $ error 111 call ermes(28); $ cant change that var. 112 end if; 113 114 if dimn voa(ep ha(a1)) then $ variable is dimensioned. 115 if (indxd = no) call ermes(49); $ error. 116 else $ variable is not an array. 117 if (indxd) call ermes(40); $ cannot use in this manner. 118 end if; 119 if tracef ha(a1) & namintern ha(a1) = no then $ trace 120 trstorp = optype; trstori = indxd; $ set parameters 121 call trstorr(a1); $ go trace store 122 end if; 123 124 end subr genasin; 1 .=member gencall 2 subr gencall(case); $ subroutine or function call. 3 $ this routine processes subroutine or function calls and 4 $ indexed loads. its main responsibility is to determine 5 $ whether a subscript is a function call or indexed load. 6 $ it also handles built-in functions. 7 size case(ps); $ calling case. 8 size a1(ps); $ routine or array name pointer. 9 size a2(ps); $ argument to operation. 10 size resat(ps); $ result of operation. 11 size n(ps); $ number of arguments. 12 size argbase(ps); $ base pointer to arguments on -arglist- 13 size glohc(ps); $ hash index into -xha-. 14 size bifno(ps); $ built-in function index. 15 size new(voasz); $ new -voa- entry. 16 17 $ first, see if this is a subroutine call without parameters. 18 if case = call_noparms then $ it is. 19 pop(a1); $ get routine name. 20 n = 0; argbase = argptr; $ set no parameters. 21 go to callcase; $ merge with other subroutine call code. 22 end if; 23 24 $ next get information about parameters. 25 n = arglist(argptr) + 1; $ get number of parameters. 26 argbase = argptr - n - 1; $ get pointer to below first parm. 27 a1 = arglist(argbase); $ get routine name. 28 if (case = call_parms) go to callcase; $ if call, go process. 29 30 $ we now have either a function call or an indexed load. 31 $ first, see if the name is in the -voa-. 32 if ep ha(a1) = 0 then $ it is not in -voa-. 33 $ next, check if it is a global. 34 ifaglob(glohc, a1); $ get global index. 35 if (glohc = 0) go to testbif; $ is not a global. 36 setqfok = yes; call setq(a1); $ page in name. 37 end if; 38 39 $ now see if this is an array. 40 if dimn voa(ep ha(a1)) then $ it is an array. 41 $ if this is referenced with more than one subscript 42 $ it is an error. 43 if n ^= 1 then $ more than one subscript. 44 ermesarg = a1; call ermes(67); $ output error message. 45 argptr = argptr - n + 1; $ reset pointer. 46 end if; 47 48 $ now generate the indexed load. 49 call arith(op_xload); $ all arguments are in place. 50 return; $ done in this case. 51 end if; 52 53 $ now, we have a subscripted reference to a variable which 54 $ is not an array. if it was never used as a simple variable, 55 $ then it is a function. 56 if isavar voa(ep ha(a1)) then $ was used as variable. 57 ermesarg = a1; call ermes(33); $ print message. 58 isavar voa(ep ha(a1)) = no; $ now this is a function. 59 end if; 60 61 $ otherwise, this is a normal user function. 62 go to usefcn; 63 64 65 /testbif/ 66 $ here the variable is not a global. therefore, we must now 67 $ check if it is a built-in function. 68 bifxhasearch = yes; ifaglob(bifno, a1); bifxhasearch = no; 69 if (bifno = 0) go to usefcn; $ if not, assume user function. 70 71 $ now see if the correct number of arguments were used. 72 if n ^= bfargs bifatrtab(bifno) then $ error. 73 ermesarg = a1; call ermes(68); $ print error message. 74 argptr = argbase; push(ha_1); return; $ ignore call. 75 end if; 76 77 $ now see if this is an 'external' function. 78 if bfext bifatrtab(bifno) then $ it is. 79 $ now check for and process an alias to the function. 80 if bfalias bifatrtab(bifno) then $ there is an alias. 81 call xsdsnamr(bfalias bifatrtab(bifno)); $ get name. 82 argptr = argbase; pushname(a1, sdsnamstr); $ put in -ha- 83 end if; 84 85 $ now see if the function name is already in the -ha-. 86 if ep ha(a1) = 0 then $ it is not in the -ha-. 87 ep ha(a1) = voptr; $ set pointer to -voa-. 88 var ha(a1) = yes; $ show real variable or constant. 89 new = 0; type new = quant; naym new = a1; $ build entry 90 syze new = mws; isafnct new = yes; $ set size and status 91 if bfmode bifatrtab(bifno) then $ is a floating function 92 if targetmachine = m11 then $ cannot support. 93 call ermes(69); $ print error message. 94 else $ set values. 95 syze new = rlsz; amode new = yes; 96 end if; 97 end if; 98 99 voa(voptr) = new; voaup; $ update into -voa-. 100 end if; 101 102 go to fnctmerge; $ merge with normal function code. 103 end if; 104 105 $ at this point we have a built-in function which is actually 106 $ a special op-code. we handle these depending on the number 107 $ of operands. 108 if n = 2 then $ this is binary function. 109 argptr = argbase + 3; $ point to correct place. 110 pop(a2); pop(a1); $ get arguments. 111 argptr = argptr-1; $ step over name. 112 call setq(a1); call setq(a2); $ ensure are sized. 113 call emit2(opofbif(bifno), a1, a2, resat); $ emit operation. 114 else $ function has one argument. 115 argptr = argbase; a1 = arglist(argptr+1); $ get it. 116 call setq(a1); $ ensure is sized. 117 call emit1(opofbif(bifno),a1,resat); $ do operation. 118 end if; 119 120 push(resat); $ push result. 121 return; $ done. 122 123 /usefcn/ $ here to process user functions. 124 $ first, see if it is in the -voa-. 125 if ep ha(a1) = 0 then $ it isn't. 126 if ermflag & ntexterr = no then $ output message. 127 ermesarg = a1; call ermes(19); 128 end if; 129 130 $ now add entry to -voa-. 131 ep ha(a1) = voptr; var ha(a1) = yes; $ set up -ha-. 132 new = 0; type new = quant; naym new = a1; $ set up -voa-. 133 syze new = mws; isafnct new = yes; $ set more fields. 134 voa(voptr) = new; voaup; $ insert into -voa-. 135 136 elseif type voa(ep ha(a1)) ^= quant then $ not a function. 137 ermesarg = a1; call ermes(33); 138 139 else $ valid. 140 isafnct voa(ep ha(a1)) = yes; $ dont allow as var. 141 if voanl voa(ep ha(a1)) then $ this is a global. 142 nlfnct nl(voanl voa(ep ha(a1))) = yes; $ set global fnct. 143 end if; 144 end if; 145 146 /fnctmerge/ $ here to emit function call. 147 call emcall(n, op_fcall, resat, argbase); $ emit it. 148 argptr = argbase; push(resat); $ push result. 149 return; $ done in this case. 150 151 152 /callcase/ $ this is the case of a subroutine call. 153 $ first, ensure name is in -voa-. 154 if ep ha(a1) = 0 then $ not in yet. 155 ep ha(a1) = voptr; var ha(a1) = yes; $ set up -ha-. 156 new = 0; naym new = a1; $ build -voa- entry. 157 voa(voptr) = new; voaup; $ insert into -voa-. 158 159 elseif type voa(ep ha(a1)) then $ not subroutine. 160 ermesarg = a1; call ermes(34); $ print error message. 161 end if; 162 163 call emcall(n, op_call, resat, argbase); $ emit the call. 164 165 argptr = argbase; $ reset pointer to -arglist-. 166 167 end subr gencall; 1 .=member gencont 2 subr gencont(csap); $ process -cont- statement 3 4 $ this routine generated code for the cont statement and 5 $ is similar to genquit. the cont do statement, however, is 6 $ done separately as the test code for continuation of the 7 $ loop is immediately generated. otherwise the code 8 $ go to test label is generated. 9 10 size csap(ps); $ parameter - -csa- pointer or zero 11 size csapp(ps); $ ptr to csa array 12 size csam(csasz); $ csa element 13 size arithop(ps); $ arithetic operation 14 size comop(ps); $ comparison operation 15 16 .+s66. 17 if csap then $ special call from -genif- for -if (e) con t do- 18 csam = csa(csap); $ get -csa- entry of interest 19 go to contdot; $ process -cont do- 20 end if; 21 ..s66 22 call findcsa(csapp, no); 23 if (csapp = 0) go to errmes; $ error 24 csam = csa(csapp); 25 .+s66. 26 if (testlbl csam = 0) go to contdot; $ this must be -do- for 660 27 ..s66 28 push(testlbl csam) call gengol(op_goto); $ go to testlabel 29 return; 30 31 /errmes/ $ illegal cont statement 32 call ermes(38); 33 return; 34 .+s66. 35 /contdot/ $ do loop cont. 36 $ generate code to increment(decrement) do loop var. 37 $ if(cond) go to body label else go to endlabel 38 if dosignp csam $ code depends on sign of by part. 39 then arithop = op_sub; comop = op_ge; $ by -. 40 else arithop = op_add; comop = op_le; $ by +. 41 end if; 42 $ increment or decrement do var 43 push(dovarp csam) push(dovarp csam) 44 push(doincp csam) 45 call arith(arithop); call genasin(1,0); $ var = var+(-) inc 46 $ perform comparison 47 push(dovarp csam) push(dohip csam) 48 call arith(comop); 49 $ if(cond) go to body label else go to endlabel 50 push(bodylbl csam) call genifgo(op_if); 51 push(endlbl csam) call gengol(op_goto); 52 ..s66 53 54 end subr gencont; 1 .=member gendat 2 subr gendat(case); $ process -data- initialization 3 $ generator for data statements is called in 4 possible cases - 4 $ 1 - data variable is indexed 5 $ 2 - simple data variable 6 $ in both of above cases create new voa entry 7 $ 3 - replication of data value indicated. make one entry 8 $ out of 2 entries ina rglist 9 $ 4 - end of data value list. copy all data value pointers 10 $ from arglist to xarg 11 12 size n(ps); $ number of data values 13 size a1(ps); $ first argument in arglist 14 size a2(ps); $ second argument in arglist 15 size case(ps); $ case of call of routine 16 size new(voasz); $ new voa item 17 size j(ps); $ do loop index 18 size aptr(ps); $ arglist index during copy to xarg 19 20 go to l(case) in 1 to 4; 21 / l(1) / / l(2) / 22 replication = no; $ assume replcation will not occur. 23 new = 0; $ create new voa entry 24 argbeg new = xargptr; $ beginning of data values in xarg array 25 opb new = yes; $ flag as operation 26 opcode new = op_data; 27 if case = 1 then 28 pop(a2); pop(a1); $ retrieve two arguments. 29 call setq(a1); 30 naym new = a1; 31 inp3 new = ep ha(a2); 32 else 33 pop(a1); $ non-indexed variabnle 34 call setq(a1); 35 naym new = a1; 36 end if; 37 $ verify that if data variable is nameset member, then nameset 38 $ is being defined in the current routine. 39 j = mblk voa(ep ha(a1)); $ machine block of variable 40 if mbxha mba(j) then $ if nameset element 41 if mbdef mba(j) = no then 42 ermesarg = a1; call ermes(2); 43 end if; 44 end if; 45 46 replication_origin = argptr; 47 return; 48 49 / l(3) / 50 if replication=no then $ if first replication instance 51 replication = yes; $ note replication occurred. 52 replicate = 0; $ initialize replicate flag list 53 end if; 54 55 a1 = arglist(argptr-1); $ replication value 56 .f. argptr-2, 1, replicate = 1; $ note that this is replication va 57 if conval(a1) <= 0 then 58 call ermes(6); end if; 59 return; 60 61 / l(4) / $ copy data value ptrs to xarg array 62 n = arglist(argptr) + 1; 63 aptr = replication_origin; 64 if (xargptr+n+1)>=xargmax then $ if xarg would overflow, 65 call ermes(8); return; end if; $ issue error, and return. 66 arglen new = n; $ number of arguments in voa entry 67 voa(voptr) = new; voaup; $ add new voa entry to voa 68 do j = 0 to n - 1; 69 xarg(xargptr + j) = 0; 70 xarg_voa xarg(xargptr+j) = ep ha(arglist(aptr)); 71 $ now check to see if amode of variable and constant agree 72 if (amode voa(ep ha(naym new)) ^= 73 amode voa(ep ha(arglist(aptr)))) 74 call ermes (45 ); 75 76 if replication then $ if replication occurred. 77 if .f. aptr, 1, replicate then $ if next is repl. val. 78 aptr = aptr + 1; 79 xarg_rep xarg(xargptr+j) = ep ha(arglist(aptr)); 80 end if; 81 end if; 82 aptr = aptr + 1; 83 end do; 84 85 xargptr = xargptr + n; 86 if argptr^=aptr then $ if not all values processed 87 call ermey(7); 88 end if; 89 90 argptr = replication_origin; 91 92 end subr gendat; 1 .=member gendim 2 subr gendim; $ generator for -dims- statement 3 $ check that dimension is in range; if too large, truncate 4 $ to maximum allowed value. if dimension not constant, 5 $ issue error message and return. 6 $ verify that it is meaningful to assign dimension to item 7 $ names; if not, report error and return. 8 $ if item is global variable, save dimension information 9 $ in global names list, nl. 10 11 size dim(ps); 12 size i(ps),j(ps),k(ps); 13 size nln(ps); $ name list index 14 size a1(ps), a2(ps); $ ha ptrs 15 16 pop(a2); pop(a1); $ retrieve two arguments. 17 18 if (signbit voa(ep ha(a2))) call ermes(4); $ negative. 19 20 if conval(a2) > dimsmax then $ dimension too larg 21 call ermes(18); $ so issue error message 22 dim = dimsmax; $ and truncate to maximum allowed 23 else $ if dimension in range 24 dim = conval(a2); 25 end if; 26 27 if ep ha(a1) = 0 then 28 ermesarg = a1; if (ntexterr = no) call ermes(7); 29 return; 30 end if; 31 32 if (type voa(ep ha(a1)) ^= quant) then $ only quantities 33 ermesarg = a1; call ermes(7); 34 return; 35 end if; 36 37 if dim < 1 then $ zero dimension not allowed 38 call ermes(4); 39 dim = 1; return; 40 end if; 41 42 if dimn voa(ep ha(a1)) then 43 /dupdim/ 44 ermesarg = a1; call ermes(54); 45 return; end if; 46 47 if isafnct voa(ep ha(a1)) then $ attempt to dimension function 48 ermesarg = a1; call ermes(55); return; 49 end if; 50 51 dimn voa(ep ha(a1)) = dim; $ enter dimension value 52 if (arb voa(ep ha(a1))) return; $ name is used as argument 53 $ name is not argument, so is variable 54 madr voa(ep ha(a1)) = madr voa(ep ha(a1))*dim; $ set correct leng 55 nln = voanl voa(ep ha(a1)); $ get -nl- index 56 if nln then $ var. is global 57 if (nldimn nl(nln)) go to dupdim; 58 nldimn nl(nln) = dim; $ save dimension value 59 end if; 60 61 end subr gendim; 1 .=member gendo 2 subr gendo(case); $ process -do- statement 3 $ this routine implements the do loop opener 4 $ the parameter case may be - 5 $ 1 - initialize - make new csa entry 6 $ 2 - do lloop with no by part. default value is 1 7 $ 3 - do loop with negative bypart 8 $ 4 - do loop with positive bypart 9 10 $ note that local variables are generated for the low do loop 11 $ expression, the hi expression, and the increment expression. 12 $ if any of these expressions are constant, no new variable need 13 $ be generated. 14 15 size case(ps); $ type of call 16 size a1(ps); $ ha pointer of do loop variable 17 size a2(ps); $ ha ptr of low expr 18 size a3(ps); $ ha ptr of hi expr 19 size a4(ps); $ ha ptr of increment 20 size dolo(ps); $ ha ptr of gneerated local variable 21 size dohi(ps); $ generated local variable - hi quant 22 size doinc(ps); $ generated local variabel - increment 23 size blab(ps); $ ha ptr of body label 24 size elab(ps); $ ha ptr of end label 25 size tlab(ps); $ test label 26 size dosign(ps); $ sign of do loop increment 27 size t(ps); $ temporary. 28 size csam(csasz); $ csa element 29 30 if case=1 then 31 $ initialize new csa entry 32 csacountup('dostatement'); $ increment csaptr 33 csam = 0; 34 cstype csam = cstype_do; 35 firstst csam = proclineno; 36 tokorg csam = csatokptr + 1; 37 csa(csaptr) = csam; 38 return; 39 end if; 40 41 $ determine sign of bypart. 42 toknum csa(csaptr) = savetoks; 43 savetoks = 5; $ do not save any more tokens 44 dosign = (case = 3); 45 if case = 2 then push(ha_1); end if; $ no by part. 46 $ default is 1 47 pop(a4); pop(a3); pop(a2); pop(a1); 48 $ a1=var, a2 =lo, a3=hi, a4=inc 49 call setq(a1); $ get do loop variable 50 51 +* getexpr(v, hap) = $hap is ha pointer. if item pointed to 52 $ is a constant, nothing is done, else a local variable v is 53 $ generated and hap assigned to it. 54 v = hap; 55 if hascon ha(hap) = no then 56 call setq(hap); $ make sure value is in -voa-. 57 t = mps; if (syze voa(ep ha(hap)) > t) t = mws; $ size 58 call getdovar(v, t); $ get variable for -do- 59 push(v) push(hap) 60 call genasin(1,0); $ lv = hap 61 end if; 62 ** 63 64 dolo = a2; getexpr(dohi, a3) getexpr(doinc, a4) 65 push(a1) push(dolo) call genasin(1,0); $ dovar = dolo 66 labget(elab) $ generated end label 67 if dosign $ determine comparison operator 68 then t = op_lt; $ if 'by -.' 69 else t = op_gt; end if; $ if 'by +.' 70 push(dolo) push(dohi) call arith(t); $ compare ranges. 71 push(elab) call genifgo(op_if); $ if...go to endlabel 72 73 $ define test label for all machines except s66 74 .+s66 tlab = 0; if targetmachine ^= m66 then labget(tlab) end if; 75 .-s66 labget(tlab); 76 77 $ define body label and update csa entry 78 labget(blab) labdef(blab) 79 csam = csa(csaptr); 80 bodylbl csam = blab; 81 endlbl csam = elab; 82 testlbl csam = tlab; 83 dolop csam = dolo; 84 dohip csam = dohi; 85 doincp csam = doinc; 86 dovarp csam = a1; 87 dosignp csam = dosign; 88 csa(csaptr) = csam; 89 $ trace for debugging 90 if trflowfg then trflow(flowdo) end if; 91 92 end subr gendo; 1 .=member genend 2 subr genend; $ generator for -end-. 3 $ this routine processes an -end- statement. 4 size csap(ps); $ -csa- pointer of entry matched. 5 size i(ps); $ loop index. 6 7 $ first, see which opener is matched. 8 call findcsa(csap, yes); $ indicate not just loops. 9 10 $ check if an opener found. 11 if csap then $ a matched opener was found. 12 $ now check to see if this was the last opener. 13 do i = csaptr to csap+1 by -1; $ process each unclosed entr 14 ermesarg = i; call ermes(60); $ print error message. 15 call closer; $ close the opener. 16 end do; 17 18 call closer; $ close the opener. 19 20 else 21 $ a matching opener was not found (even a close match). so 22 $ ignore the -end- statement. 23 call ermes(61); $ print error message. 24 end if; 25 26 end subr genend; 1 .=member genextr 2 subr genextr(opcarg); $ generator for .f., .e., .ch., .s. 3 $ generator for extract - .f., .e., .s., ann .ch. the value of 4 $ opcase is the opcode 5 $ for .ch. operator, in line code is generated. to compute the 6 $ expression .ch. a1, a2 code for 7 $ ((sorg a2) - cs * a1), cs, a2 8 $ is generated. if either a1 or a2 are constant, this code 9 $ can be simplified. 10 size opcase(6); $ opcode 11 size resat(ps); $ result 12 size a1(ps); $ ha ptrs to operands 13 size a2(ps); 14 size a3(ps); 15 size conha1(ps); $ ha constant ptrs 16 size conha2(ps); 17 size opcarg(ps); $ code for extractor type 18 19 opcase = opcarg; 20 if(opcase = 1) go to chext; $ .ch. operation 21 pop(a3); pop(a2); pop(a1); $ retrieve three arguments. 22 call setq(a1); call setq(a2); call setq(a3); 23 chexflg = no; $ show not character extraction. 24 if hascon ha(a2) then $ if length constant, 25 $ if length is zero, return zero. 26 if a2 = ha_0 then push(ha_0); return; end if; 27 if hascon ha(a1) then $ and origin constant, 28 if mod(conval(a1)-1, mws) + conval(a2) > mws then 29 if (opcase=op_fext) opcase = op_eext; $ must be .e. 30 else 31 if (opcase=op_eext) opcase=op_fext; $ may be .f. 32 end if; 33 34 if mod(conval(a2), mcs) = 0 then $ may be character. 35 if mod(conval(a1)-1, mcs) = 0 then $ is character. 36 chexflg = yes; $ it is character extraction 37 end if; 38 end if; 39 else 40 if ((opcase=op_eext)&(a2=ha_1)) opcase=op_fext; 41 $ (convert .e.,...,1, to .f.,...,1, .) 42 end if; 43 end if; 44 45 call emit3(opcase, a1, a2, a3, resat); $ to generate voa entry 46 push(resat); 47 return; 48 49 /chext/ $ generate inline code for the .ch. operation 50 pop(a2); pop(a1); $ retrieve two arguments. 51 $ generate code for sorg a1 52 call setq(a2); 53 pushint((msl+1)); pop(conha1); $ get ha index of sorg value. 54 pushint(mso); pop(conha2); $ get ha index of sorgl value. 55 chexflg = (mod(msl, mcs) = 0 & mod(mso, mcs) = 0); 56 call emit3(op_fext, conha1, conha2, a2, resat); 57 push(resat) 58 $ multiply first character a1 by cs 59 pushint(mcs) 60 push(a1) 61 call arith(op_mul); 62 $ do subtraction 63 call arith(op_sub); 64 pushint(mcs); pop(conha1); $ get ha index of mcs val. 65 call setq(arglist(argptr-1)); call setq(a2); $ check inputs. 66 chexflg = yes; $ show character operation 67 call emit3(op_fext, arglist(argptr - 1), conha1, a2, resat); 68 arglist(argptr - 1) = resat; 69 70 end subr genextr; 1 .=member gengoby 2 subr gengoby; $ -goby- generator 3 $ check that number of labels given is not excessive. 4 $ check that control item is value-producer. 5 $ construct new voa entry with labels kept in xarg, 6 $ noting label uses. 7 8 size n(ps); 9 size i(ps); $ loop index. 10 size new(voasz); $ new voa entry build here if needed 11 size labn(ps); $ label no 12 13 n = arglist(argptr)+1; 14 argptr = argptr-n-1; 15 call setq(arglist(argptr)); 16 new = 0; 17 opb new = yes; 18 opcode new = op_goby; 19 20 $ now all labels must be placed on xarg stack 21 arglen new = n; 22 argbeg new = xargptr; 23 $ first check for room on stack 24 if (xargptr+n) > xargmax then $ if -xarg- would overflow 25 call ermes(8); return; 26 end if; 27 28 do i = 1 to n; 29 call setlabl(arglist(argptr+i), labn); 30 xarg_voa xarg(xargptr + i - 1) = labn; 31 end do i; 32 33 inp1 new = ep ha(arglist(argptr)); 34 inp3 new = proclineno; $ record position in procedure. 35 isuse(arglist(argptr)); 36 xargptr = xargptr + n; 37 voa(voptr) = new; voaup; 38 39 end subr gengoby; 1 .=member gengosl 2 subr gengosl(c); $ generator for subscripted labels 3 4 $ for subscripted label or goto, generate label name and then 5 $ call -gengol-. for switched goto, generate labels and call 6 $ -gengoby-. 7 8 size c(ps); $ case 9 size slname(namsz); $ generated label name 10 size sl(ps); $ length of slname 11 size d(ps); dims d(3); $ digits of generated suffix code 12 size vlo(ws), vhi(ws); $ values of label subscripts 13 size i(ps), l(ps); $ do loop indices 14 size hap(ps); $ ha index of generated name 15 size op(ps); $ operation to be generated 16 size labvar(ps); $ ha index of label array name 17 size lablo(ps), labhi(ps); $ ha indices of subscripts 18 size lv(ps); $ value of integer to be appended to name 19 size lw(ps); $ number of columns sed by vale 20 size a1(ps), a2(ps), a3(ps), a4(ps); $ ha indices of arguments 21 22 go to l(c) in 1 to 4; 23 / l(1) / $ /l(c)/ 24 op = op_lab; go to l(4); 25 / l(2) / $ 'go to l(c)' 26 op = op_goto; go to l(4); 27 / l(4) / $ common code for /l(c)/ and 'go to l(c);' 28 pop(a2); pop(a1); $ retrieve two arguments. 29 labvar = a1; lablo = a2; labhi = a2; 30 /def/ 31 $ generate labels, call appropriate generators. 32 vlo = val(vbeg voa(ep ha(lablo))); 33 vhi = val(vbeg voa(ep ha(labhi))); 34 35 if (signbit voa(ep ha(lablo))) ! (signbit voa(ep ha(labhi))) ! 36 (vlo > 999) ! (vhi > 999) then call ermes(48); return; end if; 37 38 if vlo>vhi then call ermes(47); return; end if; 39 40 $ see if putting these labels on -argstack- would overflow it. 41 if argptr + vhi - vlo > argmax - 15 then $ overflow. 42 call ermes(65); call genexit; $ fatal error. 43 end if; 44 45 do i = vlo to vhi; 46 sdsname(slname, labvar); $ get label array name as sds 47 $ last three digits of generated label taken from 48 $ subscript value. 49 lv = i; 50 d(1) = lv/100; d(2) = mod(lv, 100)/10; 51 d(3) = mod(lv, 10); 52 lw = 1 + (lv>9) + (lv>99); $ num chars in value 53 slen slname = slen slname + 2 + lw; 54 sl = slen slname; 55 .ch. sl, slname = 1r); .ch. sl-lw-1, slname = 1r(; 56 do l = 1 to lw; 57 .ch. sl-l, slname = charofdig(d(4-l)); 58 end do; 59 pushname(hap, slname); 60 if (c=4) return; 61 if op then $ if not switch case 62 call gengol(op); 63 end if; 64 end do; 65 66 if op=0 then $ if switch case, call gengoby 67 arglist(argptr) = vhi - vlo; $ gengoby expects lab_count-1 68 call gengoby; 69 end if; 70 return; 71 72 / l(3) / $ 'go to l(e) in e1 to e2' 73 pop(a4); pop(a3); pop(a2); pop(a1); call setq(a2); $ e must be qu 74 $ generate code for goby starting at 1 75 $ goby expression is e-(lo-1), compute it 76 push(a2); $ e 77 push(a3); push(ha_1); call arith(op_sub); $ lo-1 78 call arith(op_sub); $ e - (lo-1) 79 labvar = a1; lablo = a3; labhi = a4; 80 op = 0; go to def; 81 end subr gengosl; 1 .=member gengol 2 subr gengol(op); $ -go- and -/lab/- generator 3 $ single argument a1 is label. note label usage/definition 4 $ according as operation is goto/labeldef. 5 $ construct new voa etnntry, calling blkend if this is a 6 $ label definition, which terminates basic block. 7 8 size a1(ps); $ ptr to ha 9 size op(ps); 10 size labn(ps); 11 size new(voasz); $ new voa entry built here. 12 pop(a1); 13 $ go statement generator routine,combined with 14 $ label routine. both include code emission routine. 15 call setlabl(a1, labn); 16 new = 0; 17 opb new = yes; 18 opcode new = op; 19 naym new = a1; $ index to ha 20 inp1 new = labn; $ index to lablist 21 voa(voptr)=new; voaup; 22 if op=op_lab then 23 call blkend; $ label ends basic block. 24 labldef(voptr, labn); 25 if trflowfg & namintern ha(a1) = no then $ trace flow 26 trflowl = a1; trflow(flowlab); $ trace label 27 end if; 28 end if; 29 30 end subr gengol; 1 .=member genifgo 2 subr genifgo(ifcode); $ process conditional branch 3 4 size ifcode(ps); 5 size labn(ps); 6 size a1(ps), a2(ps); $ ha ptrs 7 size new(voasz); $ new voa entry built here. 8 $ genif calls setq to verify that its first input is a quantity, 9 $ and call setlab to verify that the second argument is a label 10 $ a new voa operation entry is then constructued. 11 12 pop(a2); pop(a1); $ retrieve two arguments. 13 14 $ if input to if is a constant we can evaluate, then we 15 $ replace if by either goto or noop. 16 17 if hascon ha(a1) then 18 .+ifconstat ifcontot = ifcontot+1; 19 if (conval(a1) ^= 0) = (ifcode = op_if) then 20 push(a2); call gengol(op_goto); $ issue goto 21 .+ifconstat ifcongotos = ifcongotos+1; 22 end if; 23 return; 24 end if; 25 26 call setlabl(a2, labn); 27 call setq(a1); 28 if syze voa(ep ha(a1)) > mws then 29 push(a1) push(ha_0) 30 call arith(op_ne); pop(a1); 31 end if; 32 isuse(a1); 33 new = 0; 34 opb new = yes; 35 opcode new = ifcode; 36 inp1 new = ep ha(a1); 37 inp2 new = labn; $ index to label list 38 naym new = a2; $ index to ha 39 voa(voptr)=new; voaup; 40 41 end subr genifgo; 1 .=member genif 2 subr genif(case); $ process -if- statement 3 4 $ process various clauses of if statement, according to 5 $ argument case. meaning of each case given in code below. 6 7 size case(ps); $ type of call 8 size csanew(csasz); $ new csa entry 9 size blab(ps); $ body label ha ptr 10 size elab(ps); $ end label ha ptr 11 size csapp(ps); $ -csa- pointer 12 size t(ps); $ temporary. 13 14 go to l(case) in 1 to 11; 15 / l(1) / $ make new entry in csa array. 16 csanew = 0; 17 csacountup(' if statement'); 18 cstype csanew = cstype_if; 19 firstst csanew = proclineno; $ line number in subr 20 tokorg csanew =csatokptr + 1; 21 csa(csaptr) = csanew; 22 return; 23 / l(2) / $ then part. 24 toknum csa(csaptr) = savetoks; $ number of tokens in csatok 25 savetoks = 5; $ to indicate not to save any more tokens 26 labget(blab) $ gnerate body label 27 push(blab) call genifgo(op_ifnot); $ ifnot..go to blab 28 bodylbl csa(csaptr) = blab; 29 csiftype csa(csaptr) = csiftype_then; 30 $ trace for debugging 31 if trflowfg then trflow(flowift) end if; 32 return; 33 / l(3) / $ process simple if statement, issue 'ifnot(a1) go to..' 34 labget(elab) $ generate an end label 35 push(elab) call genifgo(op_ifnot); $ simple statement after 36 $ condition - ifnot...go to endlabel 37 endlbl csa(csaptr) = elab; 38 csiftype csa(csaptr) = csiftype_sif; 39 $ trace for debugging 40 if trflowfg then trflow(flowift) end if; 41 return; 42 / l(4) / $ end of simple staement - define end label 43 elab = endlbl csa(csaptr); 44 if trflowfg then 45 $ trace for debugging 46 trflow(flowifsf) else labdef(elab) end if; 47 savetoks = 5; $ do not save tokens 48 csatokptr = tokorg csa(csaptr) - 1; $ reset ptr to csatok 49 csaptr = csaptr - 1; $ pop coas stack 50 return; 51 / l(5) / $ else part 52 if csiftype csa(csaptr) = csiftype_elseif then 53 elab = endlbl csa(csaptr); 54 elseif csiftype csa(csaptr) = csiftype_else then 55 call ermes(62); return; $ this is an error. 56 else 57 labget(elab); $ get an end label. 58 end if; 59 60 push(elab); call gengol(op_goto); $ go to end label. 61 blab = bodylbl csa(csaptr); 62 if blab = 0 then call ermes(41); return; end if; 63 labdef(blab) $ define bodylabel 64 csiftype csa(csaptr) = csiftype_else; 65 endlbl csa(csaptr) = elab; 66 if trflowfg then 67 $ trace for debugging 68 trflow(flowiff) end if; 69 return; 70 / l(6) / $ if(cond) go to ... this statement form is 71 $ special cased from the simple statement after an if to produce 72 $ better code. one conditional branch only need be gnerated 73 $ instead of a conditional and unconditional branch. 74 savetoks = 5; $ do not save any more tokens 75 csatokptr = tokorg csa(csaptr) - 1; $ reset ptr to csatok 76 csaptr = csaptr - 1; 77 if trflowfg then 78 trflow(flowifgt) $ true part for debugging 79 else call genifgo(op_if); 80 end if; 81 $ trace for debugging 82 if trflowfg then trflow(flowiff) end if; 83 return; 84 / l(7) / $ after 'elseif' in elseif clause 85 $ define body label for previous 'then' or 'elseif', then get 86 $ new body label, generate 'ifnot (e) to to blab'. 87 if csiftype csa(csaptr) = csiftype_then then 88 $ if previous clause is then, generate end label, branch to 89 $ elab, define blab, get new blab, generate 90 $ 'ifnot(e) go to blab;' and set type to elseif type 91 labget(elab); endlbl csa(csaptr) = elab; $ generate end label 92 csiftype csa(csaptr) = csiftype_elseif; 93 elseif csiftype csa(csaptr) = csiftype_elseif then 94 elab = endlbl csa(csaptr); 95 else 96 call ermes(50); return; $ must have 'then' or 'elseif' before 97 end if; 98 99 push(elab); call gengol(op_goto); $ terminate then clause 100 blab = bodylbl csa(csaptr); 101 if blab=0 then call ermes(41); return; end if; 102 labdef(blab); 103 labget(blab); bodylbl csa(csaptr) = blab; 104 if trflowfg then trflow(flowiff) end if; 105 return; 106 / l(8) / $ after 'then' in elseif clause emit conditional branch 107 blab = bodylbl csa(csaptr); 108 if blab=0 then call ermes(41); return; end if; 109 push(blab); call genifgo(op_ifnot); 110 if trflowfg then trflow(flowift) end if; 111 return; 112 / l(9) / $ if (e) go to l(c) 113 $ action similar to case=6, but use gengosl to process 114 $ subscripted label in go to. 115 call gengosl(4); 116 go to l(6); $ now have single label, treat as case=6 117 / l(10) / / l(11) / $ if (e) quit/cont 118 $ special cased by branching to test label for -cont- and 119 $ end label for -quit- except in the case of a -cont do- 120 $ for s66. 121 call findcsa(csapp, no); $ find which loop 122 if csapp = 0 then $ error 123 call ermes(case+27); $ print error message 124 go to l(4); $ attempt to recover 125 end if; 126 if case = 10 then $ quit 127 elab = endlbl csa(csapp); $ get end label 128 else $ cont 129 elab = testlbl csa(csapp); $ get test label 130 end if; 131 .+s66. $ check for -cont do- 132 if elab = 0 then $ have it 133 labget(elab) push(elab) call genifgo(op_ifnot); $ do if 134 endlbl csa(csaptr) = elab; csiftype csa(csaptr) =csiftype_sif; 135 if trflowfg then trflow(flowift) end if; 136 call gencont(csapp); $ generate -cont do- 137 go to l(4); $ now end simple statement 138 end if; 139 ..s66 140 push(elab) go to l(6); $ treat as -if (e) go to- 141 142 end subr genif; 1 .=member genns 2 subr genns; $ process -nameset- declaration 3 size xhap(ps); $ xha index of nameset name 4 size i(ps); $ do loop index 5 size a1(ps); $ ptr to entry in ha of nameset name 6 size csanew(csasz); $ new -csa- entry. 7 8 $ begin nameset definition, see if previous use as nameset. 9 $ if so, return nameset index. otherwise build new nameset entry 10 $ when nameset index obtained, set nstouse to indicate nameset 11 pop(a1); 12 nsflg = yes; $ to indicate processing naemset 13 insglob(xhap, a1); $ add nameset name to xha 14 i = xnsblk xha(xhap); $ get nameset number (index in mba) 15 16 if i=0 then $ if new nameset, we must enter it in mba 17 countup(mbaptr, nblocks, 'nameset'); 18 mba(mbaptr) = 0; 19 mbxha mba(mbaptr) = xhap; $ record xha position of name 20 mbdef mba(mbaptr) = yes; $ nameset defined in this routine 21 xnsblk xha(xhap) = mbaptr; $ record nameset index in mba 22 i = mbaptr; 23 end if; 24 25 mbha mba(i) = a1; $ set -ha- index. 26 $ is set 27 28 csanew = 0; $ clear new -csa- entry. 29 cstype csanew = cstype_nameset; $ set opener type. 30 oldmblk csanew = nstouse; $ set old block. 31 firstst csanew = proclineno; $ set line number. 32 tokorg csanew = csatokptr + 1; $ set token list origin. 33 toknum csanew = 1; $ just nameset name. 34 csatokptr = csatokptr + 1; $ get space for token. 35 csatok(csatokptr) = names(nayme ha(a1)); $ get token word. 36 csacountup('nameset'); csa(csaptr) = csanew; $ add new entry. 37 savetoks = 5; $ do not collect tokens. 38 39 nstouse = i; $ set nameset to new one 40 .f. i, 1, accesstab = yes; $ grant access to nameset 41 42 end subr genns; 1 .=member genpad 2 subr genpad(res, a1, a2); $ generator for .pad. 3 $ a1 .pad. a2 pads character string constant a1 with blanks 4 $ to have length a2. a2 must be integer constant. 5 $ if arguments not valid or a2 too large, return a1; otherwise, 6 $ build new constant and hash it in. 7 size res(ps); $ result ha index. 8 size a1(ps), a2(ps); $ working copies of a1, a2. 9 size l1(ps), l2(ps); $ lengths of inputs. 10 size i(ps); $ loop index. 11 12 res = a1; $ set result to a1 in case error. 13 if (const voa(ep ha(a1)) = no) go to err; 14 if (lextype voa(ep ha(a1)) ^= strtok) go to err; 15 if (const voa(ep ha(a2)) = no) go to err; 16 l1 = nchars ha(a1); $ length of string. 17 if (hascon ha(a2) = no) go to err; 18 l2 = conval(a2); $ desired pad length. 19 if (l1>l2) l1 = l2; $ truncate if pad count longer than string. 20 if (l2 > toklenmax) go to err; $ if pad length too long. 21 ccaptr = 0; 22 $ get first string, copy into cca. 23 if l1 then 24 do i = 1 to (l1-1)/cpw + 1; 25 .f. nameorg - i*ws, ws, sdsnamstr = 26 val(vbeg voa(ep ha(a1)) + i - 1); 27 end do; 28 slen sdsnamstr = l1; 29 do i = 1 to l1; 30 ccaptr = ccaptr + 1; cca(ccaptr) = .ch. i, sdsnamstr; 31 end do; 32 end if; 33 34 do i = l1+1 to l2; $ pad with blanks. 35 ccaptr = ccaptr + 1; cca(ccaptr) = 1r ; 36 end do; 37 38 cclt = strtok; call cnvcon; 39 call inscon(res); 40 return; 41 /err/ $ if error, issue message and return a1. 42 call ermes(53); res = a1; 43 44 end subr genpad; 1 .=member genquit 2 subr genquit; $ process -quit- statement 3 4 $ genquit generates code for the quit statement. 5 $ quit and cont statements refer to the innermost while, until, 6 $ or do loop in which it occurs. therefore, when a cont or 7 $ quit statement appers within if-then-else statements the 8 $ csa stack must be searched for the innermost loop. the code 9 $ generated is simply 'go to end label' . 10 11 size csapp(ps); $ -csa- stack pointer. 12 13 call findcsa(csapp, no); $ find loop 14 if (csapp = 0) go to errmes; 15 if (endlbl csa(csapp) = 0) go to errmes; 16 push(endlbl csa(csapp)) call gengol(op_goto); $ go to end labe 17 return; 18 19 /errmes/ $ issue error message - illegal quit statement 20 call ermes(37); 21 22 end subr genquit; 1 .=member genreal 2 subr genreal; $ process -real- declaration 3 $ genreal is the generator routine invoked when processing 4 $ a real declaration in a little program. it sizes the 5 $ variable to word-size and sets the amode field of 6 $ the voa entry associated with the variable to amode_real. 7 8 pushint(rlsz); $ size of real. 9 if targetmachine = m11 then $ does not support reals yet. 10 call ermes(69); $ print error message. 11 else $ ok to build real. 12 buildreal = yes; $ set flag to tell gensiz to build real 13 end if; 14 15 $ real quantity 16 call gensiz; 17 buildreal = no; $ reset flag 18 19 end subr genreal; 1 .=member genret 2 subr genret; $ -return- generator 3 size new(voasz); $ new voa entry built here. 4 size hap(ps); $ dummy -ha- pointer 5 $ genret buils voa entry for return operation 6 7 $ trace for debugging aids 8 if trentrfg then trentry(entrend) end if; 9 if trflowfg then trflow(flowend) end if; 10 if debuglevel = 2 then $ must show exit from routine 11 pushname(hap, debugnames(dbg_subx)); $ push routine name 12 endblock = no; 13 call gencall(call_noparms); $ call routine 14 end if; 15 16 $ for main program, issue call ltlfin(0,0). 17 if mainprogram then 18 pushname(hap, proc_terminate); 19 push(ha_0); push(ha_0); 20 arglist(argptr) = 1; $ two params. 21 call gencall(call_parms); 22 return; 23 end if; 24 new = 0; 25 opb new = yes; 26 opcode new = op_return ; 27 voa(voptr)=new; voaup; 28 29 end subr genret; 1 .=member gensiz 2 subr gensiz; $ -size- generator 3 $ check that size value in range; if too big, truncate to 4 $ allowed maximum size szmax. check that item named can 5 $ can be sized and has not been sized already. 6 $ if sizing global variable, save information in xha,nl. 7 8 size new(voasz); $ used to build new voa entry 9 size sz(ps); $ size value 10 size i(ps); $ do loop index 11 size nssave(ps); $ saves nameset index when localblock forced 12 size nlwd(nlsz); $ nl entry to set 13 size a1(ps); 14 size a2(ps); $ ha ptr 15 16 pop(a2); pop(a1); $ retrieve two arguments. 17 sz = val(vbeg voa(ep ha(a2))); 18 if sz > szmax then $ if size too big. 19 call ermes(32); 20 sz = szmax; 21 elseif sz < 1 then $ if zero, report error and give size mws. 22 call ermes(4); 23 sz = mws; 24 end if; 25 26 $ set trace and check flags 27 tracef ha(a1) = trstorfg; $ set trace flag 28 chinxf ha(a1) = chinxfg; $ set check flag 29 $ now check special 'check' and 'trace' list 30 do i = 1 to dbgcspcp; $ check 'check' stack 31 if dbgcspc(i) = a1 then $ found 32 dbgcspc(i) = 0; $ clear place 33 chinxf ha(a1) = .f. i, 1, dbgcspcf; $ get special value 34 end if; 35 end do; 36 37 do i = 1 to dbgtspcp; $ check 'trace' stack 38 if dbgtspc(i) = a1 then $ found 39 dbgtspc(i) = 0; $ clear place 40 tracef ha(a1) = .f. i, 1, dbgtspcf; $ get special value 41 end if; 42 end do; 43 44 if (ep ha(a1) = 0) go to sizenew; $ sizing. 45 if arb voa(ep ha(a1)) then $ sizing argument 46 if syze voa(ep ha(a1)) then 47 ermesarg = a1; call ermes(56); 48 end if; 49 50 syze voa(ep ha(a1)) = sz; type voa(ep ha(a1)) = quant; 51 if (buildreal) amode voa(ep ha(a1)) = amode_real; meal 21 if trentrfg & trentrargs then $ call to print argument 53 trentry(2+a1); $ bias of 2 for ha pointer 54 end if; 55 return; 56 end if; 57 58 $ not argument name, see if sizing function begin defined 59 if fswitch & a1 = subinfo(1) then 60 if syze voa(voafnct) then $ re-sizing. 61 ermesarg = a1; call ermes(56); 62 end if; 63 64 syze voa(voafnct) = sz; 65 if (buildreal) amode voa(voafnct) = amode_real; 66 subinfo(3) = voafnct; $ voafnct is loc at which def begins 67 return; 68 end if; 69 70 $ see if this item is already sized. 71 if syze voa(ep ha(a1)) then $ already has size assigned. 72 ermesarg = a1; call ermes(56); 73 end if; 74 75 $ if we get here, something strange is happening, but size the 76 $ item anyway to prevent further errors. 77 syze voa(ep ha(a1)) = sz; $ set size of item. 78 if (buildreal) amode voa(ep ha(a1)) = yes; $ set if real. 79 return; 80 81 /sizenew/ 82 new = 0; $ build new voa entry 83 ep ha(a1) = voptr; 84 var ha(a1) = yes; $ is variable 85 if (buildreal) amode new = amode_real; 86 if localforce then $ save current nameset index, force local 87 nssave = nstouse; nstouse = localblock; end if; 88 89 vbeg new = mbchain mba(nstouse); $ set chain to last 90 mbchain mba(nstouse) = voptr; $ this is head of list 91 mblk new = nstouse; $ enter current machine block 92 mbdef mba(nstouse) = yes; 93 mbused mba(nstouse) = yes; $ use of this nameset. 94 madr new = (sz-1)/mws + 1; $ set size in words 95 type new = quant; syze new = sz; naym new = a1; 96 voa(voptr) = new; voaup; $ add at top of voa 97 $ if localforce has been set, we must use local block 98 if localforce then 99 nstouse = nssave; $ restore priod nameset 100 localforce = no; return; end if; 101 if nstouse = localblock then return; end if; 102 $ done if local variable, if 103 $ global names array, so can be used by following routines 104 insglob(i, a1); 105 if nlno xha(i) then $ is global, resizing 106 ermesarg = a1; call ermes(56); 107 return; 108 end if; 109 110 $ add new global variable 111 countup(nlptr, nlmax, 'nl'); 112 nlwd = 0; 113 nlsize nlwd = sz; $ save size 114 if (buildreal) nlamode nlwd = amode_real; 115 nlblk nlwd = nstouse; $ save machine block 116 nlha nlwd = i; 117 nltrac nlwd = tracef ha(a1); $ set global trace 118 nlchinx nlwd = chinxf ha(a1); $ set global check 119 nl(nlptr) = nlwd; 120 nlno xha(i) = nlptr; 121 voanl voa(ep ha(a1)) = nlptr; $ link voa to -nl- 122 123 end subr gensiz; 1 .=member gensub 2 subr gensub(casearg); $ fnct / prog / subr generator. 3 size casearg(ps); $ case. 4 size case(ps); $ call case 5 size i(ps); $ loop index. 6 size j(ps); 7 size new(voasz); $ used to build new voa entry 8 size a1(ps); $ ha ptr 9 size xhap(ps); $ xha index of nameset name 10 size temptitle(.sds. (cpw+ cpw*wpc)); $ used to build subtitle ldse 18 size ta(ws); dims ta(8); $ current time array. 11 12 $ subroutine generator for declaration 13 $ together with function declaration generator 14 $ if an end card does not preceed the present statement, call 15 $ genend, thus effectively inserting an end card.- 16 case = casearg; 17 go to c(case) in 0 to 5; $ select case. 18 19 /c(no)/ /c(yes)/ $ subr/fnct encountered 20 /c(5)/ 21 do j = csaptr to 1 by -1; $ end any open blocks. 22 ermesarg = j; call ermes(60); $ print error message. 23 call closer; $ close the block. 24 end do; 25 26 if voptr ^= voafnct then 27 call ermes(57); $ print error message. 28 call purge; 29 end if; 30 31 ntexterr = no; $ clear error flag 32 csaptr = 1; 33 fswitch = (case = 1); 34 mainprogram = (case = 5); 35 if case = 0 then i = cstype_subr; 36 elseif case = 1 then i = cstype_fnct; 37 elseif case = 5 then i = cstype_prog; end if; 38 csa(1) = 0; cstype csa(1) = i; $ set compound statement type. 39 flowgen = 0; $ initialize flow trace counter 40 csatokptr = 0; $ ptr to -csatok- array 41 tokorg csa(1) = 1; $ set save token origin 42 firstst csa(1) = 1; $ set line number. 43 savetoks = 0; $ save tokens 44 dovarptr = 0; dovarbusy = 0; $ clear -do- variables stack 45 46 preludefg = no; $ show not in prelude 47 trentrfg = gtrentrfg; trflowfg = gtrflowfg; $ set initial values 48 trstorfg = gtrstorfg; chinxfg = gchinxfg; $ of debug flags 49 trstorsfg = no; chinxsfg = no; $ clear indicators 50 dbgcspcp = 0; dbgtspcp = 0; $ reset debug stack pointers 51 iovaptr = 0; $ clear list of local io variables 52 iotaptr = 0; $ clear list of saved transmission items 53 $ reset levmin and levnow since routine begins with empty 54 $ ha and voa. 55 levmin = 1; 56 levnow = 1; 57 tlistptr = 0; $ reset temporaries list. 58 curblock = voptr; 59 proclineno = 1; $ reset line number within routine. 60 argct = 0; 61 return; 62 63 /c(2)/ $ have subr/fnct name 64 pop(a1); $ get name 65 new = 0; 66 ep ha(a1) = voptr; 67 var ha(a1) = yes; $ variable type entry 68 naym new = a1; $ link to ha 69 if fswitch = 0 then type new = subrtyp; 70 else type new = quant; end if; 71 voa(voptr) = new; voaup; $ add entry to voa 72 subinfo(1) = a1; $ ptr to current subr 73 sdsname(currsubrname, a1); $ subrname = sds string 74 subinfo(2) = fswitch; 75 if (mainprogram) subinfo(2) = 2; 76 if listsw then $ insert subr/fnct seporator or title 77 if listauto then $ insert title 78 temptitle = ''.pad.(cpw*wpc + cpw); $ temporary title. 79 do i = 1 to listwdsp; $ copy out header line. 80 .f. sorg temptitle - i*ws, ws, temptitle = listwds(i); 81 end do; 82 do i = 1 to 72; $ find first non blank. 83 if (.ch. i, temptitle ^= 1r ) then 84 call stitlr(1, (.s. i, 73-i, temptitle)); 85 ejectl; $ start new page. 86 quit do; 87 end if; 88 end do; 89 else $ auto-titling mode not on 90 ejectlp(5); $ dont want only 'subr' line on page 91 endl endl endl $ write default seporator 92 end if; 93 end if; 94 $ insert constants 0 and 1 in ha, save indices 95 ccsyze = 1; cclt = dectok; ccval(1) = 0; ccvalptr=1; 96 ccnchars = 0; 97 call inscon(ha_0); 98 ccsyze = 1; cclt = dectok; ccval(1) = 1; ccvalptr=1; 99 call inscon(ha_1); 100 nsubrs = nsubrs + 1; $ update subroutine count 101 nstouse = localblock; $ use local block for new vars 102 defnstouse = localblock; 103 mba(localblock) = 0; $ clear local block 104 105 $ since purge has cleared ha, set -mbha- fields to 0, and 106 $ reset -used- bits for each global nameset 107 $ (nameset is global if it is in xha) 108 109 do j = 1 to mbaptr; 110 mbha mba(j) = 0; 111 mbused mba(j) = no; $ not yet used in current routine 112 mbdef mba(j) = no; $ clear nameset definition bit 113 mbchain mba(j) = 0; $ clear defined variable chain 114 end do; 115 116 $ nameset of same name as routine name, define new nameset, 117 $ and set default nameset to be this nameset for this routine. 118 if (nsubrs=1) & (gsopt=1) then 119 mbaptr = globalblock; $ block for globals in first procedure 120 nstouse = mbaptr; 121 defnstouse = nstouse; $ set default nameeet 122 mba(mbaptr) = 0; 123 .f. nameorg-cs, cs, sdsnamstr = 1r$; $ set special name for fi 124 pushname(a1, sdsnamstr); $ set to new name for nameset 125 insglob(xhap, a1); $ locate nameset name in xha 126 xnsblk xha(xhap) = mbaptr; $ record machine block (also index 127 $ in mba) for new nameset. 128 mbha mba(mbaptr) = a1;$ record ha index of nameset name 129 mbxha mba(mbaptr) = xhap; $ record xha index of nameset name 130 end if; 131 132 if (nsubrs=2) & (daopt=yes) then $ if default access on, note 133 $ namesets defined in first procedure. 134 do j = 1 to mbaptr; 135 xhap = mbxha mba(j); $ get xha index (nonzero if global ) 136 if (xhap=0) cont do; $ not global machine block 137 .f. j, 1, defaccesstab = yes; 138 end do; 139 end if; 140 141 accesstab = defaccesstab; $ reset default access table 142 143 if (nsubrs=1) & (gsopt=yes) then $ if first rout and gsopt, 144 .f. mbaptr, 1, accesstab = yes; $ must grant access to 145 end if; $ the global block being defined in first procedure. 146 147 if crossrefoption then 148 crefput(ncards); $ first line number of routine. 149 $ write page number if listing input, else write 0. 150 i = 0; if (listsw) call contlpr(12,i); 151 crefput(i); $ write page info. 152 crefput((slen currsubrname)); $ length of name. 153 size refpos(ps), refent(ws); 154 refpos = cpw*cs + 1; refent = blankword; 155 do i = 1 to slen currsubrname; 156 refpos = refpos - cs; 157 .f. refpos, cs, refent = .ch. i, currsubrname; 158 if refpos = 1 then 159 crefput(refent); 160 refpos = cpw*cs + 1; refent = blankword; 161 end if; 162 end do; 163 if refpos ^= (cpw*cs+1) then crefput(refent); end if; 164 end if; 165 if mainprogram then $ if program, generate call to ltlini. 166 pushname(i, proc_initiate); 167 push(ha_0); 168 arglist(argptr) = 0; $ one param. 169 call gencall(call_parms); ldse 19 $ if expire option specified, generate call to ltlced to ldse 20 $ check expiration. ldse 21 if expire then ldse 22 $ lntime gives year in ta(1), day of year in ta(7). ldse 23 call lntime(ta); ldse 24 ta(1) = ta(1) + (ta(7) + expire)/365; $ expiry year. ldse 25 ta(7) = mod(ta(7)+expire, 365); $ expiry day of year. ldse 26 if (ta(7)=0) ta(7)=1; $ avoid day 0. ldse 27 $ generate call ltlced(year_expire, day_expire); ldse 28 pushname(i, proc_expire); ldse 29 pushint(ta(1)); $ year. ldse 30 pushint(ta(7)); $ day of year. ldse 31 arglist(argptr) = 1; $ two args. ldse 32 call gencall(call_parms); ldse 33 end if; 170 end if; 171 testdebug; $ see if debug code wanted 172 pushname(a1, debugnames(dbg_subn)); $ push routine name 173 endblock = no; $ dont end block 174 call sdsnamr(naym voa(voafnct)); $ get name of current routin 175 call getxsds(a1, sdsnamstr); $ build constant 176 push(a1); pushint(fswitch+2*mainprogram); $ push parms 177 arglist(argptr) = 1; $ show one parm 178 call gencall(call_parms); $ generate call 179 if trentrfg then trentry(entrrout) end if; 180 return; 181 182 /c(3)/ $ process arguments 183 argct = arglist(argptr)+1; $ number of formal arguments 184 do i = 0 to argct-1; 185 a1 = arglist(argptr-argct+i); $ get argument 186 if ep ha(a1) then $ argument already defined 187 ermesarg = a1; $ set error message number. 188 call ermes(30); cont do; 189 end if; 190 191 new = 0; $ build voa entry 192 ep ha(a1) = voptr; naym new = a1; 193 type new = quant; argno new = i+1; 194 arb new = yes; $ show is argument 195 isavar new = yes; $ show cannot be function. 196 voa(voptr) = new; voaup; 197 end do; 198 199 $ fall through to terminal processing 200 201 /c(4)/ $ end of subr/fnct statement 202 toknum csa(1) = savetoks; 203 savetoks = 5; $ do not save any more tokens 204 if mainprogram & (argct>0) then $ no args to main program 205 call ermes(59); 206 end if; 207 ldsa 66 .+rep. ldsa 67 if rep_opt_p then $ if reporting procedure definitions ldsa 68 call putrep(rep_typ, rep_typ_p); ldsa 69 call putrep(rep_nam, subinfo(1)); $ name ldsa 70 call putrep(rep_int, subinfo(2)); $ type ldsa 71 call putrep(rep_int, argct); ldsa 72 call putrep(rep_end, 0); ldsa 73 end if; ldsa 74 ..rep ldsa 75 208 end subr gensub; 1 .=member genuntl 2 subr genuntl(case); $ process -until- statement 3 4 $ implements an intil loop opener statement. 5 $ if case = 1, make new csa entry of type until. 6 $ generate a goto bodylabel entry in voa, using routine 7 $ gengol. 8 $ if case = 2, definetest label and generate code for 9 $ if...go to end label and then define bodylabel. 10 11 size case(ps); $ type of call 12 size blab(ps); $ body label 13 size tlab(ps); $ test label 14 size elab(ps); $ end label 15 size csanew(csasz); $ new coasa entry 16 17 go to l(case) in 1 to 2; 18 / l(1) / 19 labget(blab) push(blab) call gengol(op_goto); $ generate go to 20 labget(tlab) labdef(tlab) 21 $ body label 22 csacountup('until'); $ increment csaptr 23 csanew = 0; $ build new csa entry 24 cstype csanew = cstype_until; 25 firstst csanew = proclineno; 26 bodylbl csanew = blab; 27 testlbl csanew = tlab; 28 tokorg csanew =csatokptr + 1; 29 csa(csaptr) = csanew; 30 return; 31 32 / l(2) / 33 toknum csa(csaptr) = savetoks; 34 savetoks = 5; $ do not save any more tokens 35 labget(elab) $ generate end label 36 push(elab) call genifgo(op_if); $ generate if..go to elab 37 blab = bodylbl csa(csaptr); $ get body label, already defined 38 labdef(blab) 39 endlbl csa (csaptr) = elab; 40 $ trace for debugging 41 if trflowfg then trflow(flowtil) end if; 42 43 end subr genuntl; 1 .=member genwhil 2 subr genwhil(case); $ process -while- statement 3 4 $ implements a while loop opener statement. if case = 1, make 5 $ new entry in csa stack, flagged as a while type. 6 $ generate a new label definition which is the test label 7 $ if case = 2, generate code for ifnot go to endlabel 8 9 size case(ps); $ type of call 10 size csanew(csasz); $ new entry in csa 11 size elab(ps); $ end label ha ptr 12 size tlab(ps); $ test label ha ptr 13 14 go to l(case) in 1 to 2; 15 / l(1) / 16 labget(tlab) $ generate new label tlab 17 labdef(tlab) $ define new label 18 csacountup('while'); $ increment csaptr 19 csanew = 0; $ make new entry in csa 20 cstype csanew = cstype_while; 21 firstst csanew = proclineno; $ first statement of opener 22 testlbl csanew = tlab; 23 tokorg csanew =csatokptr + 1; 24 csa(csaptr) = csanew; 25 return; 26 / l(2) / 27 toknum csa(csaptr) = savetoks; 28 savetoks = 5; $ do not save any more tokens 29 labget(elab) $ generate end label 30 push(elab) $ on argument stack 31 call genifgo(op_ifnot); 32 endlbl csa(csaptr) = elab; 33 $ trace for debugging 34 if trflowfg then trflow(flowhil) end if; 35 36 end subr genwhil; 1 .=member genfile 2 subr genfile; $ process file declaration 3 4 $ generator for file statement. 5 $ emits call makfile(filename, actname, attributes...) 6 $ the actual filename is restricted to 10 characters 7 8 size i(ps); $ ha index for call generation. 9 size given(ps); $ list of values given. 10 11 $ generate call makf(filename, given, iofilekeys(1), 12 $ ...,iofilekeys(4)); 13 given = 0; 14 do i = 1 to 4; 15 $ if attribute given, set bit in -given. 16 $ if attribute not given, pass constant 0 as arg. 17 if iofilekeys(i) then $ if given. 18 .f. i, 1, given = 1; 19 else 20 iofilekeys(i) = ha_0; 21 end if; 22 end do; 23 24 if given ^= 1b'010' & given ^= 1b'011' & given ^= 1b'111' then 25 call ermes(63); return; $ this is an error. 26 end if; 27 28 pushname(i, ionames(ior_makf)); push(iofilename); 29 pushint(given); 30 do i = 1 to 4; push(iofilekeys(i)); end do; 31 endblock = no; $ dont end block 32 arglist(argptr) = 5; call gencall(call_parms); 33 34 end subr genfile; 1 .=member geniost 2 subr geniost(c); $ miscellaneous io generator 3 $ process miscellaneous io generator functions. 4 5 size c(ps); $ action code 6 size a1(ps); $ ha index of first arg, if present 7 size i(ps); $ loop index 8 size keycode(ps); $ function to search string with codes. 9 10 go to l(c) in 1 to 12; 11 /l(1)/ /l(2)/ $ start of put or get, indicate mode 12 iowriting = (c=2); 13 iovabusy = 0; $ free all io-related local variables 14 iotaptr = 0; $ clear list of saved transmission items 15 iofilename = 0; 16 return; 17 18 / l(3) / $ process file name. 19 pop(iofilename); 20 return; 21 22 / l(4) / $ 'get' or 'put' with no file given 23 pushint(1+iowriting); pop(iofilename); 24 return; 25 26 / l(5) / / l(6) / $ indicate whether formatted or unformatted io 27 ioformatted = (c=6); 28 if ioformatted then $ if formated, clear iops. 29 do i = 1 to iopsflds; 30 iopsha(i) = ha_0; 31 end do; 32 end if; 33 34 $ generate validation request. 35 pushname(i, ionames(ior_vali)); push(iofilename); 36 pushint(iowriting + 2*(1-ioformatted)); 37 endblock = no; $ dont end basic block 38 arglist(argptr) = 1; call gencall(call_parms); 39 return; 40 41 / l(7) / $ process file definition statement 42 do i = 1 to 4; iofilekeys(i) = 0; end do; 43 go to l(3); $ to process file name 44 45 / l(8) / $ process attribute specifications in file statement 46 pop(a1); 47 $ error if attribute already given. 48 if (iofilekeys(iokey)) call ermes(22); 49 if iokey = 2 then $ iotype 50 if var ha(a1) then 51 sdsname(sdsnamstr, a1); 52 i = keycode(sdsnamstr, $ next line gives iotype encoding 53 '01=get 02=print 03=put 04=read 05=string 06=write 07=release '); 54 if (i) go to fkey; 55 end if; 56 57 $ error if not variable or bad attribute. 58 call ermes(23); return; 59 /fkey/ 60 pushint(i); pop(a1); $ set a1 to ha index of i value. 61 end if; 62 iofilekeys(iokey) = a1; 63 return; 64 65 / l(9) / $ process rewind request 66 pop(iofilename); 67 pushname(i, ionames(ior_rwnd)); push(iofilename); 68 endblock = no; $ not end of block 69 push(ha_0) $ indicate no access change. 70 arglist(argptr) = 1; call gencall(call_parms); 71 return; 72 73 / l(10) / $ process filestat request 74 $ generate = ioqu(iofilename, hap) . 75 pop(iofilename); $ get file id. 76 pushname(i, ionames(ior_ioqu)); push(iofilename); 77 pushint(iokey); 78 ermflag = no; $ suppress unsized function diagnostic 79 arglist(argptr) = 1; call gencall(call_value); ermflag=yes; 80 return; 81 /l(11)/ /l(12)/ $ binary io entries. 82 iovabusy = 0; iotaptr = 0; 83 pop(iofilename); 84 iowriting = (c=12); 85 go to l(5); 86 end subr geniost; 1 .=member geniotr 2 subr geniotr; $ generate or stack transmission request 3 $ in unformatted case, do nothing, as -genioit- will issue io 4 $ request. 5 $ in formatted case, call formatted data primitives for stacked 6 $ data items. (items are stacked if multiple items with same 7 $ format, as in ':x:y:z,i(10)'.) 8 size i(ps); $ do loop index 9 size iopshasv(ps); dims iopshasv(iopsflds); 10 size j(ps); $ loop index. 11 12 if (ioformatted=no) return; 13 14 $ if more than one item, must save iopsha since geniops 15 $ clears it at end. 16 if iotaptr > 1 then 17 do j = 1 to iopsflds; iopshasv(j) = iopsha(j); end do; 18 end if; 19 20 do i = 1 to iotaptr; 21 iovar = iotavar iota(i); 22 iolo = iotalo iota(i); iohi = iotahi iota(i); 23 call setq(iovar); 24 if iolo then call setq(iolo); end if; 25 if iohi then call setq(iohi); end if; 26 if i > 1 then $ if must restore iopsha. 27 do j = 1 to iopsflds; iopsha(j) = iopshasv(j); end do; 28 end if; 29 if iowriting 30 then call genpdi; 31 else call gengdi; end if; 32 end do; 33 34 ionameflag = no; 35 iotaptr = 0; 36 37 end subr geniotr; 1 .=member genioit 2 subr genioit(c); $ process io data item specification 3 $ process datum to transmit. if c=1 then have name, perhaps 4 $ of array (implying transmission of all of array); 5 $ if c=2 have array slice, parsed as indexed loads. 6 7 size c(ps); $ case, 1 if single item, 2 if definite slice 8 size hap(ps); $ ha index of generated entries 9 size a1(ps), a2(ps); $ ha indices of arguments 10 size it1(voasz), it2(voasz); $ voa entries for arguments 11 size new(voasz); $ new voa entry for unformatted case 12 13 iolo = 0; iohi = 0; $ assume not slice 14 15 if c=1 then $ variable or expression 16 pop(a1); call setq(a1); 17 it1 = voa(ep ha(a1)); 18 if opb it1 = no then $ variable case 19 iovar = naym it1; $ variable to transmit 20 if dimn it1 then $ entire array 21 iolo = ha_1; 22 pushint(dimn it1); pop(iohi); 23 end if; 24 else 25 if opcode it1 = op_xload then $ array element, set lo 26 iovar = naym voa(inp1 it1); 27 iolo = inp3 it1; 28 else 29 iovar = a1; 30 end if; 31 end if; 32 end if; 33 34 if c=2 then $ array slice 35 pop(a2); pop(a1); $ retrieve two arguments. 36 call setq(a1); call setq(a2); $ check inputs. 37 it1 = voa(ep ha(a1)); it2 = voa(ep ha(a2)); 38 if ((opb it1 + opb it2) ^= 2) go to baditem; 39 if (opcode it1 ^= opcode it2) go to baditem; 40 if (opcode it1 ^= op_xload) go to baditem; 41 if (inp1 it1 ^= inp1 it2) go to baditem; 42 iovar = naym voa(inp1 it1); $ array being transmitted 43 iolo = inp3 it1; iohi = inp3 it2; 44 if iohi=iolo then iohi = 0; end if; 45 end if; 46 47 48 if ioformatted then $ build iota entry 49 countup(iotaptr, iotamax, 'genioit'); 50 iota(iotaptr) = 0; iotavar iota(iotaptr) = iovar; 51 iotalo iota(iotaptr) = iolo; iotahi iota(iotaptr)=iohi; 52 else 53 call setq(iovar); 54 if iolo then call setq(iolo); isuse(iolo); end if; 55 if iohi then call setq(iohi); isuse(iohi); end if; 56 new = 0; 57 opb new = yes; opcode new = op_io; 58 oup new = iowriting; 59 inp1 new = ep ha(iofilename); 60 inp2 new = ep ha(iovar); dss 62 isuse(iofilename); dss 63 isuse(iovar); dss 64 if iolo then inp3 new = ep ha(iolo); isuse(iolo); end if; 62 if iohi then dss 65 isuse(iohi); 63 xarg_voa xarg(xargptr) = ep ha(iohi); 64 argbeg new = xargptr; 65 countup(xargptr, xargmax, 'genioit'); 66 arglen new = 1; 67 end if; 68 voa(voptr) = new; voaup; 69 end if; 70 $ if reading, terminate block since values read 71 if iowriting=no then call blkend; end if; 72 return; 73 /baditem/ $ bad transmission item, build no iota enrytry 74 call ermes(46); 75 76 end subr genioit; 1 .=member gencfi 2 subr gencfi(c); $ process control format. 3 $ process control format, c is 0 if no parameter supplied, and 4 $ one if parameter supplied. 5 size c(ps); 6 size a1(ps); $ ha index of count. 7 size hap(ps); $ ha index. 8 9 if iokey = 5 then $ convert title to a format output. 10 pop(a1); 11 iovar = a1; iolo = 0; iohi = 0; 12 iokey = 1; $ reset to key of a format. 13 arglist(argptr) = 0; $ no args. dsq 9 call gendfi(0); 15 call genpdi; 16 return; 17 end if; 18 $ check that no parm given for page. 19 if (c) & (iokey = 3) go to err; 20 $ if no parm given, set to one. 21 if c = 0 then push(ha_1); end if; 22 pop(a1); $ get count. 23 pushname(hap, ionames(ior_gcfp)); 24 push(a1); pushint(iokey); 25 endblock = no; $ dont end basic block 26 arglist(argptr) = 1; call gencall(call_parms); 27 return; 28 /err/ 29 ioerror = yes; 30 call ermes(24); 31 32 end subr gencfi; 1 .=member gendfi 2 subr gendfi(c); $ process data format. 3 size c(ps); $ zero if no args, else one if args given. 4 size ioara(ps); dims ioara(3); 5 $ maxargara gives maximum number of parameters for data 6 $ format, as function of assigned encoding established in parse. 7 size maxargara(ps); dims maxargara(ioformats); 8 data maxargara = 2, 3, 3, 3, 3, 2; 9 size nargs(ps); $ number of arguments. 10 size i(ps); $ loop index. 11 12 ioerror = no; 13 nargs = 0; if (c = 1) nargs = arglist(argptr) + 1; 14 if (nargs > maxargara(iokey)) go to err; 15 if (iolistmode) iopsha(iopsi_lm) = ha_1; $ indicate list mode. 16 if nargs then $ retrieve arguments, if present. 17 argptr = argptr - nargs; 18 do i = 1 to nargs; 19 ioara(i) = arglist(argptr+i-1); 20 end do; 21 end if; 22 do i = nargs+1 to maxargara(iokey); $ clear unspecified args. 23 ioara(i) = ha_0; end do; 24 $ as first approximation to checking consistency of arguments, 25 $ assume that the first parameter specified is field width, and 26 $ that if maximum number of parameters is specified, then last 27 $ is group width. also, for formats with maximum three 28 $ parameters, second is decimal width (e,f) or byte width (b). 29 if ioara(1) then $ first parm is always field width. 30 iopsha(iopsi_fw) = ioara(1); 31 end if; 32 if nargs = maxargara(iokey) then $ if group width given. 33 iopsha(iopsi_gw) = ioara(nargs); 34 end if; 35 if (nargs > 1) & (maxargara(iokey) = 3) then $ if dw (or bw) gi 36 iopsha(iopsi_dw) = ioara(2); 37 end if; 38 iolistmode = no; 39 return; 40 /err/ 41 ioerror = yes; 42 call ermes(25); 43 44 end subr gendfi; 1 .=member geniops 2 subr geniops; $ generate io parm. str. 3 size hap(ps); $ ha index. 4 size i(ps); $ loop index. 5 size iopsval(iopssz); $ constant part of parm. str. 6 size varorg(ps); $ if nonzero, index of first nonconst parm 7 size getiov(ps); $ get local variable for io. 8 9 iopsval = 0; 10 $ if target machine word size is less than size of iops, 11 $ iops is multiword, so set high order bit to guarantee that 12 $ multiword parameter string obtained. 13 if (mws < iopssz) then 14 .f. iopssz, 1, iopsval = 1; 15 end if; 16 varorg = 0; 17 do i = 1 to iopsflds; 18 hap = iopsha(i); 19 if (hap = ha_0) cont do; 20 if hascon ha(hap) then $ if constant enter value. 21 .f. iopsorg(i), iopslen(i), iopsval = conval(hap); 22 else $ if non constant, save loc if first. 23 if (varorg = 0) varorg = i; 24 end if; 25 end do; 26 27 if varorg then $ if any variables, generate assigns. 28 iopshap = getiov(iopssz); $ get variable. 29 push(iopshap); pushint(iopsval); $ v = val. 30 call genasin(1, no); 31 do i = varorg to iopsflds; 32 hap = iopsha(i); 33 if (hap = ha_0) cont do; 34 if (hascon ha(hap)) cont do; 35 pushint(iopsorg(i)); pushint(iopslen(i)); 36 push(iopshap); push(hap); 37 call genasin(2, no); 38 end do; 39 else $ if all fields constant, hash in constant. 40 pushint(iopsval); 41 pop(iopshap); 42 end if; 43 44 do i = 1 to iopsflds; $ reset iopsha to initial state. 45 iopsha(i) = ha_0; 46 end do; 47 48 end subr geniops; 1 .=member gengdi 2 subr gengdi; $ process -get- for a data item. 3 $ this routine emits a call to a get data formatted routine. 4 $ the format type is indicated by -iokey-. the arguments 5 $ are stored in - iodfitems-. 6 size index(ps); $ ha index of index 7 size nbts(ps); $ number of bits 8 size hap(ps); $ ha index of rout name 9 size datum(ps); $ ha index of datum 10 size array(ps); $ ha index of array 11 size dovar(ps); $ do loop generated variable 12 size getiov(ps); $ returns ha index of io local variable 13 14 if (ioerror) return; $ was a format error - supress call 15 if (ionameflag) call ermes(26); $ namelist request on input 16 index = iolo; datum = iovar; 17 call setq(datum); $ check input. 18 array = 0; 19 nbts = syze voa(ep ha(datum)); 20 21 if iolo then $ need a temporary. because of little 22 $ linkage mechanisms, cannot pass 23 $ indexed arrays as parameter to input. 24 $ a temporary is passed, and stored in 25 $ array after call. 26 array = datum; 27 datum = getiov(nbts); $ get io local variable 28 dovar = 0; $ do loop variable 29 if iohi then 30 $ issue a do loop. 31 call gendo(1); $ to initialize 32 dovar = getiov(mps); push(dovar); 33 push(iolo); push(iohi); 34 call gendo(2); $ do dovar = lo to hi (no by part) 35 index = dovar; 36 end if; 37 end if; 38 39 pushint(nbts); pop(hap); $ enter sz field in iops. 40 iopsha(iopsi_sz) = hap; 41 call geniops; $ generate io parm. str. 42 push(iopshap); 43 pushname(hap, ionames(iodfprocs(iokey + ioformats*iowriting))); 44 push(datum) $ first parameter. 45 push(iopshap); 46 arglist(argptr) = 1; $ two params. 47 call gencall(call_parms); $ generate call 48 if array then $ a(i) = temp 49 push(array) push(index) push(datum) 50 call genasin(1, 1); $ simple index assign 51 if (dovar) call closer; 52 end if; 53 54 end subr gengdi; 1 .=member genpdi 2 subr genpdi; $ process request to put data item 3 $ this routine emits a call to a formatted output routine. 4 $ the routine to be called is indicated by the value of 5 $ -iokey-. the arguments are stored in the array -iodfitems-. 6 $ if ionameflag is set, namelist format is specified, and a call 7 $ routine onmlst_name is generate. 8 size datum(ps); $ ha index of datum 9 size dovar(ps); $ ha index of do loop variable 10 size ion(ps); $ index of namelist routine to use 11 size nbts(ps); $ number of bits 12 size hap(ps); $ ha index of routine name 13 size getiov(ps); $ get local variable for io 14 size array(ps); $ ha index of array if array case 15 size index(ps); $ ha index of array element whose name to list 16 17 if (ioerror) return; $ format error - supress 18 datum = iovar; 19 call setq(iovar); 20 array = 0; $ assume not transmitting array element 21 nbts = syze voa(ep ha(iovar)); 22 23 24 if iolo then $ if array element(s) involved 25 array = iovar; 26 dovar = 0; 27 if iohi then $ array slice, generate do loop 28 call gendo(1); $ to initialize do loop 29 dovar = getiov(mps); $ get do loop index 30 push(dovar) 31 push(iolo); push(iohi); 32 call gendo(2); $ no by part 33 push(iovar) push(dovar) 34 else $ transmit array(iolo) 35 push(iovar); push(iolo); 36 end if iohi; 37 38 index = arglist(argptr-1); $ save index in case -n- output 39 arglist(argptr) = 0; call gencall(call_value); $ index operati 40 pop(datum); 41 end if iolo; 42 43 if ionameflag then $ namelist output (for variable) 44 if var ha(iovar) = 0 then call ermes(27);return; end if; 45 $ generate call onmv(nameofvariable) 46 if iolo 47 then ion = ior_onma; 48 else ion = ior_onmv; $ simple variable case 49 end if; 50 51 pushname(hap, ionames(ion)); 52 sdsname(sdsnamstr, iovar); $ get name of variable as sds 53 call getxsds(hap, sdsnamstr); push(hap); $ get execution form 54 arglist(argptr) = 0; $ one parameter. 55 if iolo then $ if array element, pass index 56 push(index); arglist(argptr) = 1; end if; $ two params. 57 endblock = no; $ not end of basic block 58 call gencall(call_parms); 59 end if ionameflag; 60 61 $ generate call 62 pushint(nbts); pop(hap); $ enter sz field in iops. 63 iopsha(iopsi_sz) = hap; 64 call geniops; $ generate io parm. str. 65 pushname(hap, ionames(iodfprocs(iokey + ioformats*iowriting))); 66 push(datum) $ first parameter. 67 push(iopshap); 68 arglist(argptr) = 1; $ two parameters. 69 endblock = no; $ dont end basic block 70 call gencall(call_parms); $ emit call 71 if (iohi) call closer; 72 73 end subr genpdi; 1 .=member getiov 2 fnct getiov(nb); $ get local variable for io 3 $ obtain local variable of -nb- bits for io. use a free one if 4 $ available, else allocate a new local variable. 5 size getiov(ps); $ ha pointer returned 6 size nb(ps); $ number of bits 7 size v(ps); $ ha index of variable 8 size i(ps); $ -iova- index 9 10 do i = 1 to iovaptr; 11 if (iovasize iova(i) ^= nb) cont do; $ not right size 12 if (.f. i, 1, iovabusy = 0) go to exists; $ if free, assign 13 end do; 14 15 $ build new entry in iova 16 call advstr(lvgen, v); $ get fresh variable name 17 push(v) pushint(nb) 18 localforce = yes; $ make sure gensiz uses local block 19 call gensiz; 20 countup(iovaptr, iovamax, 'getiov'); 21 iova(iovaptr) = 0; 22 iovasize iova(iovaptr) = nb; 23 iovaha iova(iovaptr) = v; 24 i = iovaptr; 25 /exists/ 26 .f. i, 1, iovabusy = 1; $ mark variable as in use 27 getiov = iovaha iova(i); 28 29 end fnct getiov; 1 .=member blkend 2 subr blkend; $ basic block processor 3 $ terminate basic block. if no instructions in block, then 4 $ return immediately. 5 $ for each voa item in the block: 6 $ if the entry is an operation, obtain a temporary, 7 $ and then for each of its inputs, check for last use of 8 $ input in this block. if last use found, set drop bit 9 $ for later use by machine code generator, as after last use 10 $ need no longer keep items in machine registers. 11 12 size this(voasz); $ copy of voa(voanow) 13 size sz(ps); $ size of temporary 14 size retinp(ps); $ voa index of input examined by retarg. 15 size i(ps); 16 size voanow(ps); $ index of voa item being examined. 17 size opa(6); $ opatr entry for opcode of this item. 18 size mode(1); $ arithmetic mode. 19 20 $ the operator attributes used by blkend are encoded in the 21 $ array opatr, indexed by op code initialized in -kind- array 22 $ in routine start. the attributes are as follows, where 1 23 $ indicates attribute true for this operator class. 24 $ te- op has value, get temporary to hold output value. 25 $ i1- inp1 field has input 26 $ i2- inp2 field has input. 27 $ i3 - inp3 field has input. 28 $ xa - -xarg- stack may have varying list of inputs. 29 $ ou - oup field has input. 30 31 size opatr(6); dims opatr(16); 32 data opatr = 33 $. te i1 i2 i3 ou xa 34 1b' 0 0 0 0 0 0', $ 01. return, data, etc. 35 1b' 1 1 0 0 0 0', $ 02. unary 36 1b' 1 1 1 0 0 0', $ 03. binary 37 1b' 1 1 1 1 0 0', $ 04. field extract 38 1b' 1 0 0 0 0 1', $ 05. function call 39 1b' 0 0 0 0 0 1', $ 06. subroutine call 40 1b' 0 1 1 0 0 0', $ 07. a1 = a2 41 1b' 0 1 1 1 0 0', $ 08. a1(a2) = a3 42 1b' 0 1 1 1 1 0', $ 09. .e. a1, a2, a3 = a4 43 1b' 0 1 1 1 1 1', $ 10. .e. a1, a2, a3(a4) = a5 44 1b' 0 1 0 0 0 0', $ 11. if, goby 45 1b' 1 1 1 0 0 0', $ 12. real binary 46 1b' 1 1 1 0 0 0', $ 13. real comparison 47 1b' 1 1 0 0 0 0', $ 14. real unary 48 1b' 0 1 1 1 0 1', $ 15. unformatted io 49 1b' 1 0 1 0 0 0'; $ 16. indexed load 50 51 +* oa_temp = .e. 06, 01, ** $ 'does oup hold value.' 52 +* oa_inp1 = .e. 05, 01, ** $ 'does inp1 contain input.' 53 +* oa_inp2 = .e. 04, 01, ** $ 'does inp2 contain input.' 54 +* oa_inp3 = .e. 03, 01, ** $ 'does inp3 contain input.' 55 +* oa_oup = .e. 02, 01, ** $ 'does oup contain input.' 56 +* oa_xarg = .e. 01, 01, ** $ 'may xarg contain inputs.' 57 58 $ if there are no instructions in the current block, return 59 $ at once. else set levmin = levnow+1. 60 $ if this overflows the levmin counter, go to over. 61 $ macros used in this routine only, dropped at end 62 63 +* tlist_voa = .e. 01, 11, ** $ voa index of temporary 64 +* tlist_size = .e. 12, 11, ** $ temporary length. 65 +* tlist_free = .e. 23, 01, ** $ 'is temporary free.' 66 +* tlist_mode = .e. 24, 01, ** $ arithmetic mode. 67 +* retarg(f, v, db) = $ return argument, drop field to set. 68 retinp = f v; 69 $ check voa entry indexed by -retinp-. if the lastuse field of 70 $ this entry corresponds to current voa entry (index -voanow-) 71 $ set the drop bit -db-. if lastuse of temporary, indicate 72 $ the temporary no longer busy. 73 $ if this item is a variable or constant, then set the last use 74 $ bit (drop bit) if this entry is the last use of the item. 75 76 if opb voa(retinp) then $ if operation, check lastuse 77 f v = oup voa(retinp); $ replace output pointer by temp.. 78 if retinp + lastuse voa(retinp) = voanow & keeb voa(retinp) = 79 no then $ this is last use. 80 tlist_free tlist(vbeg voa(oup voa(retinp))) = yes; 81 db v = yes; $ set drop bit. 82 end if; 83 84 else $ this is a variable or constant. 85 if varluse ha(naym voa(retinp)) = voanow then $ drop bit set 86 db v = yes; $ set drop bit in -voa-. 87 end if; 88 end if; 89 ** 90 91 if (curblock >= voptr) return; 92 93 levnow=levnow+1; 94 levmin=levnow; 95 if (levmin >= levmax) then; 96 $ here follows overflow sequence for 97 $ level counter.use same sequence as asign 98 $ make a complete pass over the entire ha array, setting 99 $ the definition level of every variable entry referenced by an 100 $ ha entry to 1, then set levmin = 1 and levnow = 1, go back to 101 $ starter to perform the normal blocked procedure. 102 103 do i = 1 to hamax; 104 if (ep ha(i) = 0) cont do; 105 deflev voa(ep ha(i)) = var ha(i); 106 end do; 107 .+haprobes blkendreset = blkendreset+1; 108 levmin = 1; levnow = 1; 109 end if; 110 111 $ if entry voanow in the voa stack is not an operation entry, 112 $ bypass the steps below by going to next. 113 114 voanow = curblock; 115 /start/ 116 if (opb voa(voanow)=no) go to next; 117 this = voa(voanow); $ copy entry 118 sz = syze this; 119 mode = amode this; 120 opa = opatr(blkendtype(opcode this)); 121 if (opa=0) go to next; $ if no actions, continue. 122 if oa_temp opa then $ if need output temporary 123 $ locate free temporary of desired size on tlist, constructing 124 $ new one if necessary. nameset -block- contains input argument 125 $ sz giving desired size, and -temp- which is set to voa index 126 $ of temporary. 127 size new(voasz); $ new voa entry for temporary. 128 129 do i = 1 to tlistptr; 130 if (tlist_size tlist(i) ^= sz) cont do; 131 if (tlist_mode tlist(i) ^= mode) cont do; $ if wrong mode. 132 if (tlist_free tlist(i)) go to exists; 133 end do; 134 $ no entry found, construct new temporary. 135 countup(tlistptr, tlistmax, 'gettemp'); 136 i = tlistptr; 137 if sz>szmax then $ if size too big, trim it. dss 66 call ermes(70); 142 sz = szmax; end if; 143 tlist_size tlist(i) = sz; tlist_voa tlist(i) = voptr; 144 tlist_mode tlist(i) = mode; 145 new = 0; temb new = yes; type new = quant; 146 vbeg new = tlistptr; $ save tlist position. 147 syze new = sz; 148 amode new = mode; 149 voa(voptr) = new; voaup; 150 /exists/ 151 tlist_free tlist(i) = no; 152 oup this = tlist_voa tlist(i); 153 end if; 154 155 if oa_inp1 opa then $ if inp1 has input 156 $ check for lastuse of temporary. 157 retarg(inp1, this, db1); end if; 158 159 if oa_inp2 opa then $ if inp2 is input 160 retarg(inp2, this, db2); end if; 161 162 if oa_inp3 opa then $ if inp3 is input 163 retarg(inp3, this, db3); end if; 164 165 if oa_oup opa then $ if oup has input 166 retarg(oup, this, dboup); end if; 167 168 if oa_xarg opa then $ if inputs on xarg stack 169 if arglen this then $ if any inputs present 170 do i = argbeg this to argbeg this + arglen this - 1; 171 retarg(xarg_voa, xarg(i), xarg_db); 172 end do; 173 end if; 174 end if; 175 176 voa(voanow) = this; 177 178 /next/ 179 voanow = voanow+1; 180 if(voanow < voptr) go to start; 181 182 curblock = voptr; 183 184 macdrop(retarg) 185 end subr blkend; 1 .=member getdovar 2 subr getdovar(hap, sz); $ get variable for -do- 3 $ this routine searches the list of variables obtained for 4 $ bounds and indexes of -do- statements to determine if any 5 $ may be re-used. if not, this routine creates a new one, 6 $ generates a -size- statement, and adds it to the list. 7 size hap(ps); $ -ha- pointer 8 size sz(ps); $ size to assign. 9 size i(ps); $ do loop index 10 11 do i = 1 to dovarptr; $ scan list 12 if .f. i, 1, dovarbusy = 0 then $ found a free one 13 if (dovarsz(i) ^= sz) cont do; $ skip if wrong size. 14 hap = dovars(i); $ get -ha- pointer 15 .f. i, 1, dovarbusy = yes; $ set busy 16 return; $ done 17 end if; 18 end do; 19 20 $ not found, must create a new one. 21 call advstr(lvgen, hap); $ get new variable 22 countup(dovarptr, dovarmax, 'dovars'); 23 dovars(dovarptr) = hap; $ insert into list 24 dovarsz(dovarptr) = sz; $ set size of variable. 25 .f. dovarptr, 1, dovarbusy = yes; $ show in use 26 push(hap) pushint(sz) localforce = yes; $ set for -gensiz- 27 call gensiz; $ size it in local block 28 29 end subr getdovar; 1 .=member sortvars 2 subr sortvars; $ sort and assign storage for vars. 3 $ this routine scans each -mba- entry for namesets that are 4 $ defined in the current routine. it then scans the chain of 5 $ defined variables and sorts in order of increasing total size 6 $ (size*dimn). then, storage is allocated for the variable. 7 $ 8 $ the sorting method used is a list merge sort from knuth's 9 $ algorithm 5.2.4l with the suggestion given in the answer to 10 $ exercise 12 included. 11 $ 12 $ the nodes for 0 and n+1 are voa(1) and voa(voptr), 13 $ respectively, which are always available. 14 $ the array -pq- is used for the variables -p- and -q- 15 $ so that steps l4,l5 and l6,l7 can be written in common. 16 $ 17 $ since the variables are chained via the -vbeg- field of the 18 $ -voa-, it is natural to use the high order bit of this field 19 $ to replace the positive and negative links. 20 $ 21 $ the macro -vbegs- is the first bit position of the -vbeg- 22 $ field and -vbegl- is the length of the -vbeg- field. note 23 $ that .fb. voamax must be less than vbegl. 24 $ 25 .+s66 +* vbegs = 94 ** +* vbegl = 12 ** dss 67 .+s32 +* vbegs = 117 ** +* vbegl = 12 ** dst 30 .+s37 +* vbegs = 117 ** +* vbegl = 12 ** utsa 299 .+s47 +* vbegs = 117 ** +* vbegl = 12 ** dst 31 .+s10 +* vbegs = 109 ** +* vbegl = 12 ** 28 29 size mbap(ps); $ -mba- pointer 30 size s(vbegl), t(vbegl); $ list heads 31 size p(vbegl); $ temporary used in scanning list 32 size pq(vbegl); dims pq(2); $ used for -p- and -q- 33 size x(2); $ set to 1 or 2 to index -pq- 34 size addr(ps); $ cumulative address in block 35 size mdr(ps); $ address of variable in block ldsa 76 size nsha(ps); $ ha index of nameset name. 36 37 38 do mbap = 1 to mbaptr; $ process all blocks 39 if (mbdef mba(mbap) = 0) cont do; $ skip if not defined 40 $ reverse mbchains so that items 41 $ of same volume allocated storage in increasing order. 42 if mbchain mba(mbap) then $ if want reversal. 43 p = mbchain mba(mbap); $ current start. 44 s = vbeg voa(p); $ first item in list. 45 if s then $ if any elements to reverse. 46 vbeg voa(p) = 0; $ current head becomes tail. 47 while s; $ while elements to reverse. 48 t = vbeg voa(s); $ next successor. 49 vbeg voa(s) = p; $ reverse link. 50 p = s; $ move to next item in list. 51 s = t; 52 end while; 53 54 mbchain mba(mbap) = p; $ new header. 55 end if; 56 end if; 57 58 vbeg voa(1) = mbchain mba(mbap); $ set to start of list 59 t = voptr; p = mbchain mba(mbap); $ initialize pointers 60 while vbeg voa(p); $ loop until end of chain 61 s = vbeg voa(p); $ point to next in the list 62 if madr voa(p) > madr voa(s) then $ improper order 63 vbeg voa(t) = s; .f. vbegs+vbegl-1, 1, voa(t) = yes; 64 t = p; $ set up new sublist 65 end if; 66 67 p = s; $ set up for next time through 68 end while; 69 70 vbeg voa(t) = 0; .f. vbegs+vbegl-1, 1, voa(voptr) = 0; 71 72 $ two sublists have been formed. sort may now begin. 73 while 1; $ loop until sorted 74 s = 1; t = voptr; $ initialize for next pass 75 pq(1) = vbeg voa(1); pq(2) = vbeg voa(voptr); $ set heads 76 if (pq(2) = 0) quit while; $ only one list - sorted 77 while pq(2); $ loop until end of pass 78 until pq(x) = 0 ! .f. vbegl, 1, pq(x); $ q <=0 79 x = (madr voa(pq(1)) > madr voa(pq(2)))+1; $ compa 80 .f. vbegs, vbegl-1, voa(s) = pq(x); s = pq(x); 81 pq(x) = vbeg voa(pq(x)); $ set to next in list 82 end until; 83 84 vbeg voa(s) = pq(3-x); s = t; $ set new sublist 85 until pq(3-x) = 0 ! .f. vbegl, 1, pq(3-x); 86 t = pq(3-x); pq(3-x) = vbeg voa(pq(3-x)); 87 end until; 88 89 .f. vbegl, 1, pq(1) = no; .f. vbegl, 1, pq(2) = no; 90 end while; 91 92 .f. vbegs, vbegl-1, voa(s) = pq(1); $ clean up for 93 .f. vbegs, vbegl-1, voa(t) = 0; $ next pass 94 end while; 95 96 97 $ list is now sorted by length. proceed to allocate 98 $ storage and clean up tables. 99 p = vbeg voa(1); $ start of sorted list 100 mbchain mba(mbap) = p; $ set for -asm- (if it wants it) 101 addr = 0; $ set at first location in block ldsa 77 .+rep. ldsa 78 if rep_opt_g then $ if reporting global declarations mdsa 1 if voanl voa(p) then $ if global ldsa 80 nsha = mbha mba(mbap); $ save ha index of nameset name ldsa 81 end if; ldsa 82 end if; ldsa 83 ..rep 102 while p; $ loop over all variables 103 mdr = addr + ((syze voa(p)-1)/mws+1); $ set to var. addre 104 105 $ ensure that arr(0) is in block. 106 if dimn voa(p) ^= 0 & addr < (syze voa(p)-1)/mws + 1 then 107 addr = (syze voa(p)-1)/mws + 1; $ set to leave room. 108 mdr = 2*addr; $ now set starting address. 109 end if; 110 111 addr = addr + madr voa(p); $ set new block end address 112 madr voa(p) = mdr; $ set address in block 113 if voanl voa(p) then $ is global, must set in -nl- 114 nlmadr nl(voanl voa(p)) = mdr; $ set address in -nl- ldsa 84 .+rep. ldsa 85 if rep_opt_g then $ if reporting globals. ldsa 86 call putrep(rep_typ, rep_typ_g); ldsa 87 call putrep(rep_nam, naym voa(p)); $ variable name ldsa 88 call putrep(rep_int, syze voa(p)); $ size ldsa 89 call putrep(rep_int, dimn voa(p)); $ dimension ldsa 90 call putrep(rep_nam, nsha); $ nameset name ldsa 91 call putrep(rep_int, mdr); $ offset in block ldsa 92 call putrep(rep_end, 0); ldsa 93 end if; ldsa 94 ..rep 115 end if; 116 117 .f. vbegs+vbegl-1, 1, voa(p) = 0; $ ensure correct chain 118 p = vbeg voa(p); $ point to next in list 119 end while; 120 121 mblen mba(mbap) = addr; $ set length of nameset ldsa 95 .+rep. ldsa 96 $ if reporting on globals, give nameset length. ldsa 97 if rep_opt_g & (mbap>=globalblock) then ldsa 98 call putrep(rep_typ, rep_typ_n); ldsa 99 call putrep(rep_nam, nsha); ldsa 100 call putrep(rep_int, addr); $ nameset length ldsa 101 call putrep(rep_end, 0); ldsa 102 end if; ldsa 103 ..rep 122 end do; 123 124 $ clear -voanl- fields in -voa- because some asms expect zeros. 125 do p = 1 to voptr-1; $ scan -voa-. 126 if (opb voa(p)) cont do; $ skip operations. 127 voanl voa(p) = 0; $ clear field. 128 end do; 129 130 macdrop(vbegs) macdrop(vbegl) 131 end subr sortvars; 1 .=member emass 2 subr emass(storop, nargs); $ emit assignment statement 3 size a5(ps); 4 size storop(ps); $ opcode giving assignment type 5 size new(voasz); $ new voa entry build if needed 6 size a1(ps),a2(ps),a3(ps),a4(ps); 7 $ emit subroutine for store operations 8 $ up to four arguments 9 size i(ps); 10 size j(ps); 11 size nargs(ps); $ number of arguments 12 size this(voasz); $ temporary -voa- entry. dss 68 size subi(ps); $ ha index of subscript if indexed assign 13 14 $ increment the levnow counter. test for overflow, go to 15 $ go to the overflow case. 16 $ else go to simple, index, subfiel or both 17 $ depending on the parameter n defining the type of assignment 18 $ statement for which macro code is to be generated. 19 20 new = 0; 21 levnow = levnow+1; 22 if levnow > levmax then 23 do i = 1 to hamax; 24 if (ep ha(i) = 0) cont do; 25 deflev voa(ep ha(i)) = var ha(i); 26 end do; 27 .+haprobes emassreset = emassreset+1; 28 levmin = 1; levnow = 1; 29 end if; 30 dss 69 subi = 0; $ assume not indexed assignment. dss 70 31 go to l(nargs) in 2 to 5; 32 / l(2) / $ a1 = a2. 33 34 pop(a2); pop(a1); $ retrieve two arguments. 35 deflev voa(ep ha(a1)) = levnow; 36 inp2 new = ep ha(a2); 37 inp1 new = ep ha(a1); 38 39 $ we must now show that the last use of the variable to which we 40 $ have just assigned is the last one in the basic block. 41 if varluse ha(a1) >= curblock then $ last used in this block. 42 this = voa(varluse ha(a1)); $ get -voa- entry. 43 j = ep ha(a1); $ get -voa- index for variable. 44 if (inp1 this = j) db1 this = yes; $ set drop bit. 45 if (inp2 this = j) db2 this = yes; 46 if (inp3 this = j) db3 this = yes; 47 if (oup this = j) dboup this = yes; 48 voa(varluse ha(a1)) = this; $ replace entry. 49 if arglen this then $ check any arguments. 50 do i = argbeg this to argbeg this + arglen this - 1; 51 if (xarg_voa xarg(i) = j) xarg_db xarg(i) = yes; 52 end do; 53 end if; 54 end if; 55 56 isuse(a1); isuse(a2); go to rest; 57 58 / l(3) / $ a1(a2) = a3 59 pop(a3); pop(a2); pop(a1); $ retrieve three arguments. 60 deflev voa(ep ha(a1)) = levnow; 61 inp1 new = ep ha(a1); 62 inp2 new= ep ha(a3); 63 inp3 new= ep ha(a2); 64 isuse(a1); isuse(a3); 65 isusenot = hascon ha(a2); $ dont count if constant. 66 isuse(a2); isusenot = no; $ flag and reset. dss 71 subi = a2; $ a2 is subscript. 67 go to rest ; 68 / l(4) / $ .e. a1, a2, a3 = a4 69 pop(a4); pop(a3); pop(a2); pop(a1); 70 if (a2=ha_0) return; $ if length zero, op is no-op. 71 deflev voa(ep ha(a3)) = levnow; 72 isuse(a3); isuse(a4); 73 isusenot = hascon ha(a1); isuse(a1); $ count unless constant. 74 isusenot = hascon ha(a2); isuse(a2); $ count this unless constan 75 isusenot = no; $ reset flag. 76 inp1 new = ep ha(a3); 77 inp2 new = ep ha(a4); 78 inp3 new = ep ha(a1); 79 oup new = ep ha(a2); 80 bytaln new = chasflg; $ set character mode flag 81 chasflg = no; $ clear for next time 82 go to rest; 83 84 / l(5) / $ .e. a1, a2, a3(a4) = a5 85 pop(a5); pop(a4); pop(a3); pop(a2); pop(a1); $ retrieve five argum 86 if (a2=ha_0) return; $ if length zero, op is no-op. 87 isuse(a3); isuse(a5); 88 isusenot = hascon ha(a1); isuse(a1); 89 isusenot = hascon ha(a2); isuse(a2); 90 isusenot = hascon ha(a4); isuse(a4); 91 isusenot = no; $ reset flag. 92 deflev voa(ep ha(a3)) = levnow; 93 inp1 new= ep ha(a3); 94 inp2 new= ep ha(a5); 95 inp3 new= ep ha(a4); 96 oup new= ep ha(a2); 97 bytaln new = chasflg; $ set character mode flag 98 chasflg = no; $ reset 99 xarg(xargptr) = 0; 100 xarg_voa xarg(xargptr)=ep ha(a1); 101 argbeg new= xargptr; 102 arglen new = 1; 103 countup(xargptr, xargmax, 'xarg'); dss 72 subi = a4; $ a4 is subscript. 104 105 /rest/ dss 73 if subi then $ check if subscript size ok. dss 74 i = syze voa(ep ha(subi)); dss 75 if (cis_opt>0 & i>cis_opt) call ermes(71); dss 76 end if; dss 77 106 opb new = yes; 107 opcode new = storop; 108 voa(voptr)=new; 109 voaup; 110 111 end subr emass; 1 .=member emcall 2 subr emcall(n,ki,resat, argbase); $ build voa entry for call. 3 $ construct voa entry for subroutine or function call, 4 $ with arguments kept in xarg array. note argument uses. 5 $ for a function call, locate a free ha entry and then 6 $ set it to represent function value. 7 8 size n(ps); $ number of parameters. 9 size resat(ps); 10 size argbase(ps); $ arglist index of inputs. 11 size ki(ps); 12 size i(ps); $ do loop temporary 13 size hcode(ps); $ hash-code for ha function search 14 size j(ps), k(ps); 15 size new(voasz); 16 size this(voasz); $ for last use values. 17 18 new = 0; 19 opb new = yes; 20 opcode new = ki; 21 inp3 new = proclineno; $ record line no of call statement 22 23 if n then $ if any arguments. 24 arglen new = n; 25 argbeg new = xargptr; 26 if (xargptr+n)>xargmax then 27 call ermes(8); 28 call genexit; $ overflow case. 29 end if; 30 31 do i = 1 to n; $ put argument pointers into xarg 32 xarg(xargptr+i-1) = 0; $ clear -xarg- entry 33 call setq(arglist(argbase+i)); $ ensure sized. 34 xarg_voa xarg(xargptr+i-1) = ep ha(arglist(argbase+i)); 35 36 $ now set the last use bit for this prior useage of 37 $ any arguments. 38 if var ha(arglist(argbase+i)) then $ is a variable or co 39 if varluse ha(arglist(argbase+i)) >= curblock then 40 this = voa(varluse ha(arglist(argbase+i))); 41 j = ep ha(arglist(argbase+i)); 42 if (inp1 this = j) db1 this = yes; 43 if (inp2 this = j) db2 this = yes; 44 if (inp3 this = j) db3 this = yes; 45 if (oup this = j) dboup this = yes; 46 voa(varluse ha(arglist(argbase+i))) = this; 47 if arglen this then 48 do k = argbeg this to argbeg this + 49 arglen this - 1; $ all args. 50 if (xarg_voa xarg(k) = j) 51 xarg_db xarg(k) = yes; 52 end do; 53 end if; 54 end if; 55 end if; 56 end do; 57 58 xargptr = xargptr + n; 59 isusenot = yes; $ dont count arguments. 60 do i = 1 to n; $ process all arguments. 61 isuse(arglist(argbase+i)); 62 end do; 63 64 isusenot = no; 65 end if; 66 67 naym new = arglist(argbase); 68 syze new = syze voa(ep ha(arglist(argbase))); dsy 9 deflev new = levnow; $ set definition level ldsa 104 .+rep. dsx 37 ldsa 105 $ if rep_opt_c selected, report call. arguments are name of ldsa 106 $ caller, name of called procedure, and number of arguments. ldsa 107 if rep_opt_c then ldsa 108 call putrep(rep_typ, rep_typ_c); $ call ldsa 109 call putrep(rep_nam, subinfo(1)); $ caller name ldsa 110 call putrep(rep_nam, arglist(argbase)); $ called name ldsa 111 call putrep(rep_int, n); ldsa 112 call putrep(rep_end, 0); ldsa 113 end if; ldsa 114 ..rep 69 /ret/ 70 if (ki = op_call) go to calcase; 72 73 $ locate empty ha-slot to correspond to returned function value 74 hcode = arglist(argbase); $ use ha index fo hash-code 75 haprobe(i, hcode); 76 if (hainuse ha(i) = no) haquit; 77 haend; 78 79 hainuse ha(i) = yes; 80 ep ha (i) = voptr; 81 amode new = amode voa(ep ha(arglist(argbase))); 82 resat = i; voa(voptr) = new; voaup; 83 return; 84 85 /calcase/ 86 seblk new = endblock; voa(voptr) = new; voaup; 87 if endblock = no then 88 endblock = yes; 89 else call blkend; end if; 90 resat = 0; 91 92 end subr emcall; 1 .=member emit1 2 subr emit1(op,a1,resat); $ give voa entry for unary operation 3 size a1(ps); 4 size resat(ps); 5 size op(ps); 6 size j(ps); $ ha index during search 7 size hcode(ps); $ hash code to begin search 8 size sz(ps); $ size of result 9 size new(voasz); $ new voa entry built here if needed 10 size def1(ps), defj(ps); $ deflev values. 11 hcode = a1 * op; $ random value from inputs 12 haprobe(j, hcode); $ search the ha 13 if (hainuse ha(j) = no) go to notfound; 14 if (var ha(j)) hacont; $ ignore variables 15 if (ep ha(j) = 0) hacont; $ ignore if not iv voa 16 if (deflev voa(ep ha(j)) < levmin) go to notfound; 17 if (opcode voa(ep ha(j)) ^= op) hacont; 18 if (inp1 voa(ep ha(j)) ^= ep ha(a1)) hacont; 19 go to found; $ formally identical op. found 20 haend; $ end ha probe 21 /found/ 22 def1 = deflev voa(ep ha(a1)); defj = deflev voa(ep ha(j)); 23 if (defj < def1) go to notfound; $ arg reassigned. 24 if var ha(a1) = no then $ if op, must be avail in this block. 25 if (def1 < levmin) go to notfound; 26 end if; 27 resat = j; $ redundant calculation. 28 return; 29 /notfound/ 30 new = 0; 31 deflev new = levnow; 32 opcode new = op; 33 inp1 new = ep ha(a1); 34 opb new = yes; 35 if realopcd(op) then $ mode is real 36 sz = rlsz; $ size of real 37 amode new = amode_real; $ set to real. 38 elseif op = op_nb ! op = op_fb then 39 sz = mps; $ these return pointer size 40 elseif builtin(op) then sz = mws; 41 else 42 sz = syze voa(ep ha(a1)); 43 end if; 44 45 syze new = sz; 46 hainuse ha(j) = yes; 47 ep ha(j)=voptr; 48 isuse(a1); 49 voa(voptr) = new; voaup; 50 resat = j; 51 52 end subr emit1; 1 .=member emit2 2 subr emit2(op,a1,a2,resat); $ give voa entry for binary operation 3 size a1(ps); 4 size a2(ps); 5 size op(ps); 6 size sz(ps); $ size of result 7 size sz1(ps), sz2(ps); $ sizes of inputs 8 size c1(ps), c2(ps); $ string capacities for size of !!. 9 $ (the input arguments and the result arguments are all ha 10 $ item references). 11 size j(ps); 12 size k(ps); 13 size resat(ps); 14 size new(voasz); $ new voa entry built here if needed 15 size hcode(ps); $ hash-code for search 16 $ check to see if this opcode represents a commutative 17 $ operation. 18 $ if it does, rearrange arguments so that the argument with 19 $ the largest voa pointer appears as first argument. 20 if commutes(op) then 21 if ep ha(a1) > ep ha(a2) then $ reorder 22 j=a1; a1=a2; a2=j; end if; 23 end if; 24 $ search the ha array, beginning at a random 25 $ location determined by the opcode and inputs, bypassing 26 $ all entries of variable type. 27 $ search wil find either empty location, or reference to a 28 $ formally identical operation. 29 30 hcode = op + a1 + a2; $ random bits from inputs 31 haprobe(j, hcode); 32 if (hainuse ha(j) = no) go to notfound; 33 if (var ha(j)) hacont; $ ignore variables 34 if (ep ha(j) = 0) hacont; $ ignore if not in voa 35 $ if op of previous block, reuse entry 36 if (deflev voa(ep ha(j)) < levmin) go to notfound; 37 if (opcode voa(ep ha(j)) ^= op) hacont; 38 if (inp1 voa(ep ha(j)) ^= ep ha(a1)) hacont; 39 if (inp2 voa(ep ha(j)) ^= ep ha(a2)) hacont; 40 go to found; $ formally identical op. 41 haend; $ end ha search 42 /found/ 43 size defent(ps), defen1(ps), defen2(ps); 44 defent=deflev voa(ep ha(j)); defen1=deflev voa(ep ha(a1)); 45 defen2=deflev voa(ep ha(a2)); 46 if (defent < defen1) go to notfound; $ if first input changed. 47 if (defent < defen2) go to notfound; $ if second input changed. 48 $ inputs which are operations must have been computed 49 $ in the current block. 50 if var ha(a1) = no then 51 if (defen1 < levmin) go to notfound; end if; 52 if var ha(a2) = no then 53 if (defen2 < levmin) go to notfound; end if; 54 resat = j; $ operation is redundant. 55 return; 56 57 /notfound/ 58 sz = 0; $ becomes nonzero when size of result known 59 new=0; 60 opcode new=op; 61 deflev new = levnow; 62 $ real operations have size 1 for comparison, size mws 63 $ for integer-valued functions, and otherwise size rlsz. 64 if realopcd(op) then $ if real operation. 65 if realcomparison(op) then $ if comparison, 66 sz = 1; $ set size to 1. 67 else 68 sz = rlsz; 69 amode new = amode_real; 70 end if; 71 elseif builtin(op) then $ if built-in function 72 sz = mws; $ size of integer. 73 end if; 74 $ now if fetching indexed real quantity, 75 $ set amode field to amode_real 76 if op = op_xload & amode voa(ep ha(a1)) = amode_real then 77 amode new = amode_real; 78 sz = rlsz; $ size of real. 79 end if; 80 inp1 new=ep ha(a1); 81 inp2 new=ep ha(a2); 82 opb new=yes; 83 isuse(a2); isuse(a1); 84 if op=op_xload then $ if indexed load 85 inp3 new = a2; $ save ha index of subscript dss 78 $ report warning if size greater than index size. dss 79 if (cis_opt>0 & syze voa(inp2 new)>cis_opt) call ermes(71); 86 end if; 87 88 if sz=0 then $ if size not yet known, compute it 89 sz1 = syze voa(inp1 new); 90 sz2 = syze voa(inp2 new); 91 $ set syze as max of input sizes 92 sz = sz1; if sz=op_gt)&(op<=op_ne) then dst 33 sz = 1; $ comparison dst 34 if arithcomparison(op) then $ check operand sizes. dst 35 if (sz1>mws ! sz2>mws) call ermes(5); dst 36 end if; 94 elseif op=op_seq ! op=op_sne then sz = 1; $ string comparis 95 elseif (op=op_in) then sz = msl; $ .in. 96 $ for .in., use length of sds length field. 97 elseif op = op_ccat then $ if string concatenation. 98 $ each input contains descriptor fields and only need 99 $ one set of descriptor fields in result. 100 if sz1>=(msl+mso) & sz2>=(msl+mso) then 101 sz = (sz1 + sz2 + mws - 1 - msl - mso)/mws * mws; 102 else 103 call ermes(64); $ print error. 104 sz = sz1 + sz2; $ if either short, take sum. 105 end if; 106 107 elseif op=op_mul then $ if multiplication 108 if (sz1<=mws)&(sz2<=mws) then $ take max if both <=mws 109 $ on s16, force size up to ws. 110 if (targetmachine = m16) sz = mws; 111 else sz = sz1+sz2; 112 end if (sz1; 113 elseif op=op_xload then sz = sz1; 114 end if; 115 end if sz=0; 116 117 syze new = sz; 118 hainuse ha(j) = yes; 119 ep ha(j)=voptr; 120 resat = j; 121 voa(voptr)=new; voaup; 122 123 end subr emit2; 1 .=member emit3 2 subr emit3(op,a1,a2,a3,resat); $ construct voa entry for extract. 3 size a1(ps); 4 size a2(ps); 5 size a3(ps); 6 size k(ws); 7 size resat(ps); 8 size op(ps); 9 size new(voasz); $ used to build new voa fentry 10 size hcode(ps); $ hash code computed 11 size j(ps); $ ha index during search 12 size sz(ps); $ size of extractor 13 size con(ps); $ value if length of extracter is constant 14 size defent(ps), defen1(ps), defen2(ps), defen3(ps); 15 $ emit subroutine for triadic(extract)op 16 hcode = (op .ex. a1) * (a2 .ex. a3); $ hash inputs 17 haprobe(j, hcode); $ search the ha 18 if (hainuse ha(j) = no) go to notfound; 19 if ( var ha(j)) hacont; $ ignore variables 20 if( ep ha(j) = 0) hacont; $ ignre if no voa item 21 if (deflev voa(ep ha(j)) < levmin) go to notfound; 22 $ reuse op from pevious basic block 23 if (opcode voa(ep ha(j)) ^= op) hacont; 24 if (inp1 voa(ep ha(j)) ^= ep ha(a1)) hacont; 25 if (inp2 voa(ep ha(j)) ^= ep ha(a2)) hacont; 26 if (inp3 voa(ep ha(j)) ^= ep ha(a3)) hacont; 27 go to found; $ formally identical op. found. 28 haend; $ end ha probe 29 /found/ 30 $ the operation is formally redundant, now check that no 31 $ inputs of type operation have been redefined since the prior 32 $ calculation, and that both the operation and any 33 $ operation-type inputs have been computed in the current 34 $ basic block. 35 36 defent = deflev voa(ep ha(j)); defen1 = deflev voa(ep ha(a1)); 37 defen2 = deflev voa(ep ha(a2)); defen3 = deflev voa(ep ha(a3)); 38 if (defent < defen1) go to notfound; 39 if (defent < defen2) go to notfound; 40 if (defent < defen3) go to notfound; 41 $ inputs have not changed, see if inputs available in block. 42 if var ha(a1) = no then $ if a1 is op. 43 if (defen1 < levmin) go to notfound; end if; 44 if var ha(a2) = no then $ if a2 is op. 45 if (defen2 < levmin) go to notfound; end if; 46 if var ha(a3) = no then $ if a3 is op. 47 if (defen3 < levmin) go to notfound; end if; 48 resat = j; $ operation is redundant. 49 return; 50 51 /notfound/ 52 new = 0; 53 opcode new = op; 54 deflev new = levnow; 55 inp1 new = ep ha(a1); 56 inp2 new = ep ha(a2); 57 inp3 new = ep ha(a3); 58 isuse(a3); 59 isusenot = hascon ha(a1); isuse(a1); 60 isusenot = hascon ha(a2); isuse(a2); 61 isusenot = no; 62 opb new = yes; 63 bytaln new = chexflg; $ set character mode flag 64 chexflg = no; $ clear for next time 65 $ compute size of result, exploiting length if constant 66 con = 0; 67 if hascon ha(a2) then $ if length is constant,put in con. 68 con = conval(a2); end if; 69 70 sz = 0; 71 if op=op_fext then $ if .f. extract, 72 $ use length if is constant, else word size. 73 if con 74 then sz = con; 75 else sz = mws; end if; 76 elseif op=op_eext then $ if .e. extract, 77 $ use length if is constant, else size of source. 78 if (con) sz = con; 79 elseif op=op_sext then $ if .s. extract, 80 $ use length of appropriate sds if constant, else source size. 81 if con then 82 sz = mws*((con*mcs + msl + mso + mws-1)/mws); 83 end if; 84 end if; 85 86 if (sz=0) sz = syze voa(ep ha(a3)); 87 syze new = sz; 88 hainuse ha(j) = yes; 89 ep ha(j)=voptr; 90 resat = j; 91 voa(voptr)=new; voaup; 92 93 end subr emit3; 1 .=member setlabl 2 subr setlabl(h, labnum); $ note use as label 3 4 $ this routine receives as input an ha pointer -h- and returns 5 $ a label number 'labnum'. it first checks the 'labno' field 6 $ in the ha , which if non-zero, indicates that the 7 $ label has been used previously. in this case, it returns this 8 $ labno. otherwise, the lablist ptr is incremented, and its new 9 $ value is recorded in the ha and returned as the labnum. 10 11 size h(ps); $ ha pointer 12 size labnum(ps); $ label number 13 14 labnum = labno ha(h); $ retur if use as label already noted 15 if (labnum) return; 16 $ label not used before 17 countup(lablistptr, lablistlen, 'setlabl'); 18 labno ha(h) = lablistptr; $ note that name has use as label 19 lablist(lablistptr) = 0; 20 labha lablist(lablistptr) = h; $ link to ha 21 labnum = lablistptr; $ record label number 22 23 end subr setlabl; 1 .=member setq 2 subr setq(a); $ check validity as input. 3 $ verify that ha(a) represents an item which can receive 4 $ or produce a value. if the item is a accessible global 5 $ variable not yet in the ha, use the information saved 6 $ in xha and nl to construct new voa entry. 7 $ in any event, if cannot locate item, create a local 8 $ variable of word-size, to help user continue in 9 $ the absence of the size declaration. 10 11 size i(ps); $ do loop index 12 size a(ps); 13 size new(voasz); $ for building new voa item 14 size xhax(ps); $ pointer to xha, non zero for global 15 size nlp(ps); $ pointeg to nl 16 $ test to see if quantity or calc.if so, ok 17 $ set used and set lastdef 18 $ if other, then error 19 if (var ha(a) = no) go to ret; 20 if (ep ha(a) ^= 0 & type voa(ep ha(a)) = quant) go to checksiz; 21 $ encountered unsized variable, 22 $ first see if global, and if so, page into ha 23 ifaglob(xhax, a) $ see if global 24 if(xhax=0) go to er; $ not global variable, report error 25 $ now page in var from global names list 26 nlp = nlno xha(xhax); $ nl org 27 ep ha(a) = voptr; $ build new voa entry 28 tracef ha(a) = nltrac nl(nlp); $ flag to trace stores 29 chinxf ha(a) = nlchinx nl(nlp); $ flag to check index range 30 $ check for special trace/check 31 if (trstorsfg) tracef ha(a) = trstorfg; $ set if trace/notrace g 32 if (chinxsfg) chinxf ha(a) = chinxfg; $ set if check/nocheck 33 do i = 1 to dbgcspcp; $ check 'check' stack 34 if dbgcspc(i) = a then $ found 35 dbgcspc(i) = 0; $ clear place 36 chinxf ha(a) = .f. i, 1, dbgcspcf; $ get special value 37 end if; 38 end do; 39 40 do i = 1 to dbgtspcp; $ check 'trace' stack 41 if dbgtspc(i) = a then $ found 42 dbgtspc(i) = 0; $ clear place 43 tracef ha(a) = .f. i, 1, dbgtspcf; $ get special value 44 end if; 45 end do; 46 47 new = 0; 48 type new = quant; 49 mblk new = nlblk nl(nlp); madr new = nlmadr nl(nlp); 50 syze new = nlsize nl(nlp); dimn new = nldimn nl(nlp); 51 naym new = a; $ link to ha 52 amode new = nlamode nl(nlp); 53 voanl new = nlp; $ point to -nl-. 54 isafnct new = nlfnct nl(nlp); $ set function flag. 55 voa(voptr) = new; voaup; 56 return; 57 58 /er/ 59 ermesarg = a; if (ntexterr = no) call ermes(7); $ report unsized 60 push(a) pushint(mws) localforce = yes; $ set up for -gensiz- 61 call gensiz; $ generate size statemant for variable 62 63 /checksiz/ 64 if (syze voa(ep ha(a)) = 0) go to er; $ not sized but in -voa-. 65 66 $ ensure that this is not a function being used as a variable. 67 if isafnct voa(ep ha(a)) & setqfok = no then $ if function. 68 ermesarg = a; call ermes(66); $ print error. 69 isafnct voa(ep ha(a)) = no; $ no longer function. 70 end if; 71 72 setqfok = no; $ clear special case flag. 73 74 /ret/ 75 76 end subr setq; 1 .=member isusep 2 subr isusep(hap); $ note use of ha(hap) as input 3 $ macro -isuse- expands into call to this routine. 4 $ if ha(hap) is operation, update lastuse field to reflect use. 5 $ else, add to usage count until overflow and set last use. 6 size hap(ps); $ ha index of item 7 size vop(ps); $ voa index of ha(hap) 8 9 vop = ep ha(hap); 10 if var ha(hap) then $ entry is variable or constant 11 varluse ha(hap) = voptr; $ set last use 12 isavar voa(vop) = yes; $ show usage as variable. 13 if (isusenot) return; $ done if no count. 14 if (varnuse voa(vop)+1 <= varnusemax) 15 varnuse voa(vop) = varnuse voa(vop) + 1; 16 return; 17 end if; 18 19 if voptr-vop <= blockmax then $ if lastuse in range. 20 lastuse voa(vop) = voptr-vop; $ set it. 21 else $ not in range. 22 keeb voa(vop) = yes; $ set overflow bit. 23 end if; 24 25 end subr isusep; 1 .=member putrep 2 .+rep. 3 subr putrep(typ, n); $ put entry to report file 4 $ if report file selected, write entry to report file. 5 size typ(ps); $ typ of entry to be written 6 size n(ws); $ integer value or ha index to write. 7 size typltrs(.cs.); dims typltrs(rep_typ_max); 8 data typltrs(rep_typ_c) = 1rc; 9 data typltrs(rep_typ_g) = 1rg; 10 data typltrs(rep_typ_n) = 1rn; 11 data typltrs(rep_typ_p) = 1rp; 12 13 size nargs(ps); $ number of arguments written 14 15 if typ = rep_typ then $ if start of line 16 put repfile ,x(8) :typltrs(n),r(1) ,x(7); 17 nargs = 0; 18 elseif typ = rep_int then 19 if nargs then put repfile ,','; end; 20 nargs = nargs + 1; 21 put repfile :n,i; $ write integer value 22 elseif typ = rep_nam then $ if want name, n is ha index 23 if nargs then put repfile ,','; end; 24 nargs = nargs + 1; 25 call sdsnamr(n); 26 put repfile :sdsnamstr,a; 27 elseif typ = rep_end then $ if end of line 28 put repfile ,skip; 29 end if; 30 end subr putrep; 31 ..rep 1 .=member purge 2 subr purge; $ cleanse tables, prepare for next routine 3 4 $ reset all stacks and clear the ha. collect statistics on 5 $ table usage. 6 7 size haused(ps); $ no of ha entries used in routine 8 size i(ps); 9 10 haused = 0; 11 do i = 1 to hamax; $ count ha load and clear ha 12 if (hainuse ha(i)) haused = haused+1; 13 ha(i) = 0; 14 end do; 15 16 if haused>loadha then 17 loadha = haused; loadrha = currsubrname; end if; 18 if namesptr > loadnames then $ update max load 19 loadnames = namesptr; loadrnames = currsubrname; end if; 20 namesptr = 1; $ reset names ptr 21 if voptr > loadvoa then $ update voa load count 22 loadvoa = voptr; loadrvoa = currsubrname; end if; 23 voptr = voafnct; $ reset voa for start of definition 24 curblock = voptr; $ set current block to start. 25 26 $ reset xargptr,voptr to next available locations 27 if xargptr > loadxarg then $ update xarg load 28 loadxarg = xargptr; loadrxarg = currsubrname; end if; 29 if valptr > loadval then $ update val load 30 loadval = valptr; loadrval = currsubrname; end if; 31 valptr=1; 32 xargptr=1; 33 if lablistptr > loadlablist then $ update lablist load 34 loadlablist = lablistptr; loadrlablist = currsubrname; end if; 35 lablistptr = 0; $ reset label list origin 36 if tlistptr>loadtlist then $ if new tlist load seen, 37 loadtlist = tlistptr; 38 loadrtlist = currsubrname; end if; 39 levmin = 1; levnow = 1; 40 lvgen = 'v.aa'; labgen = 'l.aa'; 41 $ reset local name and label names 42 argptr = 1; arglist(argptr)=0; $ clear arglist 43 44 $ show in prelude for monitoring statements. 45 preludefg = yes; $ show in prelude. 46 accesstab = 0; $ show no accesses in effect. 47 do i = 1 to mbaptr; $ now set all accesses to allow trace statem 48 .f. i, 1, accesstab = yes; $ set bit to allow variables. 49 end do; 50 51 end subr purge; 1 .=member gentrace 2 subr gentrace(fg, case); $ process debug 'trace' statement. 3 $ this generator is called for trace ,notrace debug statements. 4 $ and also for check index. 5 $ the cases are the following - 6 $ 1 - flow 2 - flow with subr name list 7 $ 3 - store 4 - store with variable name list 8 $ 5 - entry 6 - entry with subr name list 9 $ 7 - index 8 - index with variable name list 10 size nargs(ps); $ number of names in namelist 11 size fg(1); $ flag - argument 12 size case(ps); $ case of call - argument 13 size xnl(ps); $ index in nl 14 size xhax(ps); $ ptr to xha 15 size hap(ps); 16 size i(ps), j(ps); $ do loop indexes 17 18 testdebug; $ exit if debugging not wanted 19 if preludefg then $ this is global 20 go to p(case) in 1 to 8; 21 else 22 go to l(case) in 1 to 8; 23 end if; 24 25 / p(1) / $ trace/notrace flow 26 gtrflowfg = fg; $ set global flow flag 27 return; 28 / p(3) / $ trace/notrace stores 29 do i = 1 to nlptr; $ change all trace bits 30 nltrac nl(i) = fg; $ set flag 31 end do; 32 gtrstorfg = fg; $ set global flag 33 return; 34 / p(7) / $ check/nocheck index 35 do i = 1 to nlptr; $ change all check bits 36 nlchinx nl(i) = fg; $ set flag 37 end do; 38 gchinxfg = fg; $ set global flag 39 return; 40 / p(5) / $ trace/notrace entry 41 gtrentrfg = fg; $ set global flag 42 return; 43 / p(4) / / p(8) / $ trace/notrace/check/nocheck with name list 44 nargs = arglist(argptr)+1; $ get no. of args 45 argptr = argptr-nargs; $ reset pointer to -arglist- 46 do i = 0 to nargs-1; $ process each arg 47 hap = arglist(argptr+i); 48 ifaglob(xhax, hap); $ see if global 49 if xhax then $ it is in -xha- 50 xnl = nlno xha(xhax); $ get -nl- entry 51 if case > 6 then nlchinx nl(xnl) = fg; 52 else nltrac nl(xnl) = fg; end if; 53 else 54 ermesarg = hap; call ermes(51); 55 end if; 56 end do; 57 return; 58 / l(1) / $ trace flow and notrace flow statements 59 trflowfg = fg; 60 return; 61 / p(2) / / p(6) / 62 / l(2) / / l(6) / $ trace/notrace entry/flow with namelist 63 call ermes(58); $ this is an error 64 return; 65 / l(5) / $ trace entry and notrace entry statements 66 trentrfg = fg; 67 return; 68 / l(3) / $ trace store and notrace store statements 69 trstorsfg = yes; $ show statement occured 70 dbgtspcp = 0; $ clear exception stack 71 trstorfg = fg; 72 do i = 1 to hamax; $ clear bits in ha and xnl 73 tracef ha(i) = fg; end do; 74 do i = 1 to nlptr; $ clear flags for vars defined in this routin 75 if (mbdef mba(nlblk nl(i))) nltrac nl(i) = fg; 76 end do; 77 return; 78 / l(7) / $ check store range of index assignments 79 chinxfg = fg; 80 chinxsfg = yes; $ show statement occured 81 dbgcspcp = 0; $ clear exception stack 82 do i = 1 to hamax; chinxf ha(i) = fg; end do; 83 do i = 1 to nlptr; $ clear flags for vars defined here 84 if (mbdef mba(nlblk nl(i))) nlchinx nl(i) = fg; 85 end do; 86 return; 87 / l(8) / 88 / l(4) / $ trace and no trace store with namelist 89 nargs = arglist(argptr) + 1; 90 argptr = argptr - nargs; 91 do i = 0 to nargs-1; $ process args in turn 92 hap = arglist(argptr+i); $ get arg 93 if ep ha(hap) then $ var. has been sized 94 if case > 6 then chinxf ha(hap) = fg; 95 else tracef ha(hap) = fg; end if; 96 ifaglob(xhax, hap); $ see if global 97 if xhax then $ is global 98 xnl = nlno xha(xhax); $ point to -nl- 99 if mbdef mba(nlblk nl(xnl)) then $ defined here 100 if case > 6 then nlchinx nl(xnl) = fg; 101 else nltrac nl(xnl) = fg; end if; 102 end if; 103 end if; 104 else $ not sized, put in stack 105 if case > 6 then $ 'check' case 106 do j = 1 to dbgcspcp; $ search stack 107 if (dbgcspc(j) = 0 ! dbgcspc(j) = hap) quit do; 108 end do; 109 if j > dbgcspcp then $ not in stack 110 countup(dbgcspcp, dbgspcmax, 'dbgcspc'); 111 end if; 112 dbgcspc(j) = hap; $ set index 113 .f. j, 1, dbgcspcf = fg; $ set flag value 114 else 115 do j = 1 to dbgtspcp; $ search 'trace' stack 116 if (dbgtspc(j) = 0 ! dbgtspc(j) = hap) quit do; 117 end do; 118 if j > dbgtspcp then $ not in stack 119 countup(dbgtspcp, dbgspcmax, 'dbgtspc'); 120 end if; 121 dbgtspc(j) = hap; $ set value 122 .f. j, 1, dbgtspcf = fg; $ set flag value 123 end if; 124 end if; 125 end do; 126 127 end subr gentrace; 1 .=member gensert 2 subr gensert(case); $ process debug 'assert' statement. 3 $ generator for the assert statement. 4 size i(ps); $ do loop variable 5 size case(1); $ case = 0 is initial, case = 1 is ender. 6 size newlab(ps); $ label ha ptr generated 7 size nwds(ps); $ nomber of words 8 size nhap(ps); $ ha pointer of name sds 9 10 if (case = 1) go to gencode; 11 assertstp = 0; $ ptr to assert stack 12 if (debuglevel = 2) assertfg = yes; $ accumulate vars if full de 13 return; 14 15 /gencode/ $ end of assert statement. ha ptrs have been 16 $ collected in assertst. 17 $ generate: if e go to lab; call printr; /lab/ 18 if (debuglevel = no) return; $ do nothing if no debugging wanted 19 $ complile no code if assert argument is nonzero constant. 20 pop(i); $ get expression. 21 if hascon ha(i) then $ if constant expression. 22 if (conval(i)) return; $ if nonzero constant. 23 end if; 24 push(i); $ restore expression. 25 labget(newlab) push(newlab) 26 call genifgo(op_if); 27 if debuglevel = 1 then $ minimal assert facility wanted 28 pushname(nhap, debugnames(dbg_asfl)); $ push name of simple r 29 call gencall(call_noparms); $ generate call 30 labdef(newlab); $ define label 31 return; $ done with this case 32 end if; 33 34 pushname(nhap, debugnames(dbg_prhd)); $ print header routine 35 endblock = no; $ dont end a block 36 pushint(proclineno); $ parameter is line no. 37 arglist(argptr) = 0; $ one argument 38 call gencall(call_parms); $ call routine 39 do i = 1 to assertstp; $ pass aar name, val, and size 40 $ only accumulate names of variables, so ignore if not in ha 41 if (ep ha(assertst(i)) = 0) cont do; 42 if (isafnct voa(ep ha(assertst(i)))) cont do; $ if function 43 if (dimn voa(ep ha(assertst(i)))) cont do; $ dont print arra 44 nwds = (syze voa(ep ha(assertst(i))) - 1) / mws + 1; 45 pushname(nhap, debugnames(dbg_prvr)); $ push name of routine 46 endblock = no; $ dont end block 47 call sdsnamr(assertst(i)); $ get name 48 call getxsds(nhap, sdsnamstr); $ build constant 49 push(nhap); pushint(nwds); push(assertst(i)); $ push parms 50 arglist(argptr) = 2; $ 3 parameters 51 call gencall(call_parms); $ generate call 52 end do; 53 54 labdef(newlab) $ define label 55 assertfg = no; $ end of assertion 56 57 end subr gensert; 1 .=member trflowr 2 subr trflowr; 3 $ debug trace routine for flow trace. checks trflowfg to see if 4 $ the current routine should be traced. 5 testdebug; $ see if debug code wanted 6 $ if so, it generates a call 7 $ to print routine. the global -trflowrp- indicates which type 8 $ of code block is being executed. 9 $ (eg label, while, until, if, etc) 10 size dlab(ps); $ debug label 11 size param(ws); $ parameter to be passed to runtime routine 12 size i(ps); $ do loop variable 13 size savelab(ps); 14 size newlab(ps); 15 size nhap(ps); $ ha pointer of name 16 17 $ control flow for these types, in addition to trace calls 18 $ fields of param 19 +* flowtyp = .f. 01, 03, ** $ type 20 +* flowblock = .f. 04, 10, ** $ block no. 21 +* flowlino = .f. 17, 16, ** $ line no. 22 23 if trflowp = flowend then $ at a return statement - call 24 $ ending print routine. 25 pushname(nhap, debugnames(dbg_prfl)); $ set name 26 endblock = no; $ dont end block 27 call gencall(call_noparms); $ call routine 28 return; 29 end if; 30 31 $ assign values to run-time globals 32 param = 0; 33 flowtyp param = flowp trflowp; $ type of code block 34 if flowp trflowp ^= flowiff then $ for all cases except if-false 35 $ gnerate a new identification number and store it in csa 36 countup(flowgen, flowgenlim, 'flowgen'); 37 ifnum csa(csaptr) = flowgen; 38 flowblock param = flowgen; 39 else 40 flowblock param = ifnum csa(csaptr); $ get block number. 41 end if; 42 43 flowlino param = proclineno; 44 if trflowp = flowifgt then $ if go to (true) 45 $ generate ifnot c go to newlab; call flowr go to lab; /newlab/ 46 savelab = arglist(argptr - 1); 47 labget(newlab) 48 arglist(argptr - 1) = newlab; 49 call genifgo(op_ifnot); 50 else 51 $ for if statements which do not have else parts, must generate 52 $ an else part of form go to dlab;/elab/ call trace; /dlab/ 53 $ so that the number of times the condition is 54 $ false may be counted. 55 if flowiftyp trflowp then 56 labget(dlab) push(dlab) call gengol(op_goto); 57 if trflowp = flowifsf then 58 labdef(endlbl csa(csaptr)); 59 else 60 labdef(bodylbl csa(csaptr)) 61 end if; 62 end if; 63 end if; 64 65 pushname(nhap, debugnames(dbg_trfl)); $ push name 66 endblock = no; $ dont end block 67 pushint(param); $ push parameter 68 $ for label blocks, set debugtab(3) = label name 69 if trflowp = flowlab then 70 call sdsnamr(trflowl); $ get label name as sds 71 call getxsds(nhap, sdsnamstr); $ build constant 72 push(nhap); $ push it 73 end if; 74 75 arglist(argptr) = (trflowp = flowlab); $ set no. of parms 76 call gencall(call_parms); $ call routine 77 if trflowp = flowifgt then $ if go to - true 78 $ emit...go to lab; /savelab/ 79 push(savelab) call gengol(op_goto); 80 labdef(newlab) return; 81 end if; 82 83 if flowiftyp trflowp then labdef(dlab) end if; 84 85 end subr trflowr; 1 .=member trstorr 2 subr trstorr(target); 3 $ generates call to prstorer for debugging trace of variable 4 $ stores. it is assumed that the top entry in the voa is an 5 $ assignment. first the ha entry of the variable is examined 6 $ to see if the variable should be traced. 7 $ the value of trstorp indicates the type of the assignment. 8 size param(ws); $ parameter passed to run time routine 9 size nwds(ps); $ number of words of target 10 size nwdsp(ps); $ voa ptr to either in1 or in2 11 size target(ps); $ ha ptr to target variable 12 size nhap(ps); $ ha pointer for name 13 size nparms(ps); $ number of params to debug call rbkn 10 size nparmv(ps); dims nparmv(6); $ number of parameters. rbkn 11 data nparmv = 3, 5, 5, 5, 4, 3; $ values. 16 17 $ fields of param 18 +* vsize = .f. 1, 8, ** $ size of target (in words) 19 +* vlino = .f. 17, 16, ** $ line number of assignment 20 +* vopcod = .f. 9, 3, ** $ type of store 21 +* vindx = .f. 12, 1, ** $ flag indicating indexed store 22 23 testdebug; $ see if debug code wanted 24 param = 0; 25 if syze voa(inp1 voa(voptr-1)) > syze voa(inp2 voa(voptr-1)) then 26 $ determine which is larger, source or target, size passed 27 $ to run-time routine is the smaller of the two. 28 nwdsp = inp2 voa(voptr-1); $ source 29 else 30 nwdsp = inp1 voa(voptr-1); $ target 31 end if; 32 33 nwds = (syze voa(nwdsp)-1)/mws+1; $ set size in words 34 vsize param = nwds; $ size of target 35 vlino param = proclineno; 36 vopcod param = trstorp; $ type of assignment 37 vindx param = trstori; $ indexed flag 38 nparms = nparmv(trstorp) + trstori; $ number of parms. 39 pushname(nhap, debugnames(dbg_prst+nparms-3)); $ push routine nam 40 endblock = no; $ dont end block 41 call sdsnamr(target); $ get sds for name of variable 42 call getxsds(nhap, sdsnamstr); $ build constant 43 push(nhap); $ push name 44 pushint(param); $ push parameter 45 push(trstor1); $ push value 46 if trstori then $ indexed assignment 47 push(trstor2); $ push index 48 end if; 49 50 if trstorp > 1 & trstorp < 5 then $ field assignment 51 if trstori then 52 push(trstor5); push(trstor4); 53 else 54 push(trstor4); push(trstor3); $ field pos and length 55 end if; 56 57 elseif trstorp = 5 then $ .ch. assignment 58 push(trstors); $ push position 59 end if; 60 61 arglist(argptr) = nparms-1; $ set no. of parameters 62 call gencall(call_parms); $ generate call 63 64 end subr trstorr; 1 .=member chinxr 2 subr chinxr(target, indexvar); 3 $ generates call to indexr to check range of indexed store. 4 $ the global oarameter chinxrp contains the voaptr to 5 $ indexed store operation. 6 size target(ps); $ ha ptr to target of store 7 size indexvar(ps); $ ha pointer for index. 8 9 size nhap(ps); $ ha pointer for name 10 testdebug; $ check if debug statements wanted 11 $ check index range 12 if (arb voa(ep ha(target))) return; $ dont checks arg arrays 13 pushname(nhap, debugnames(dbg_cinx)); $ push routine name 14 endblock = no; $ dont end block 15 call sdsnamr(target); $ get var name as sds 16 call getxsds(nhap, sdsnamstr); $ build constant 17 push(nhap); $ push name 18 push(indexvar); $ push index 19 pushint(dimn voa(ep ha(target))); $ push dimension 20 pushint(proclineno); $ push line no. 21 arglist(argptr) = 3; $ 4 parameters. 22 call gencall(call_parms); $ generate call 23 24 end subr chinxr; 1 .=member trentrr 2 subr trentrr; 3 $ checks status of trentr flag and generates call to off-line 4 $ trace routine accordingly. 5 size i(ps); $ do loop variable 6 size nwds(ps); $ number of words 7 size nhap(ps); $ ha pointer of name 8 9 testdebug; $ see if debug statements wanted 10 if trentrp = entrrout then $ entry subr case 11 pushname(nhap, debugnames(dbg_pren)); $ push oroutine name 12 endblock = no; $ dont end block 13 call gencall(call_noparms); $ generate call to it 14 return; 15 end if; 16 17 if trentrp = entrend then $ exit function case 18 pushname(nhap, debugnames(dbg_prex)); $ push routine name 19 endblock = no; $ dont end block 20 pushint(proclineno); $ push line number 21 if fswitch then $ see if function 22 pushint(((syze voa(voafnct))-1)/mws+1); $ push no. of word 23 push(naym voa(voafnct)); $ push function value 24 end if; 25 26 arglist(argptr) = fswitch*2; $ set no. of parms 27 call gencall(call_parms); $ call debug routine 28 return; 29 end if; 30 31 $ argument case. hap is biased by 2 32 pushname(nhap, debugnames(dbg_prar)); $ push routine name 33 endblock = no; $ dont end block 34 call sdsnamr(trentrp-2); $ get sds for name of arg 35 call getxsds(nhap, sdsnamstr); $ build constant 36 push(nhap); $ push it 37 pushint(((syze voa(ep ha(trentrp-2)))-1)/mws+1); $ push no. words 38 push(trentrp-2); $ push value 39 arglist(argptr) = 2; $ 3 parameters 40 call gencall(call_parms); $ generate call to debug routine 41 42 end subr trentrr; 1 .=member tabdump 2 subr tabdump(lo,hi,ifall); $ dump selected tables. 3 $ give symbolic dump of selected tables. list voa entires lo 4 $ through all. the parameter -ifall- will eventually be used 5 $ to give selective dump. 6 size lo(ps), hi(ps), ifall(ps); 7 8 if ifall then 9 call voadump(lo, hi); 10 call xargdump; 11 call dumpaq('val', val, 1, valptr-1); 12 call hadump; 13 call xhadump; 14 call nldump(1, nlptr); 15 call mbadump; 16 call csadump(1, csaptr); 17 else $ short dump 18 call voadump(lo, hi); 19 call xargdump; 20 call csadump(1, csaptr); 21 end if; 22 23 end subr tabdump; 1 .=member nldump 2 subr nldump(lo, hi); $ dump names list nl 3 size lo(ps), hi(ps); $ lo and high indices to dump 4 size i(ps); $ do loop index 5 size nlwd(nlsz); $ copy of nl entry being dumped 6 size lines(ps); $ number of lines for dump 7 size l(ps); $ index of line being printed 8 size lp(ps); $ position in current line 9 +* lablabel = 10' i size dimn madr mblk xha chnx trac amod name ==nl== '** 11 endl textl(' dump of global names list - nl'); endl 12 $ we write two entries per line 13 lines = (hi - lo + 2)/2; $ number of lines to print 14 do l = 1 to lines; 15 if (l - 20*(l/20))=1 then 16 endl textl(lablabel) tabl(60) textl(lablabel) endl 17 end if; 18 i = l + lo - 1; 19 while i<=hi; 20 intl(i); 21 nlwd = nl(i); $ word to dump 22 intl((nlsize nlwd)) 23 intl((nldimn nlwd)) 24 intlp((nlmadr nlwd), 6) 25 intl((nlblk nlwd)) 26 intl((nlha nlwd)) 27 intl((nlchinx nlwd)) 28 intl((nltrac nlwd)) 29 intl((nlamode nlwd)) 30 skipl(1) 31 call xsdsnamr(nlha nlwd); textl(sdsnamstr) 32 i = i + lines; 33 getlpos(lp); $ get positio 34 if lp<60 then tabl(60); end if; 35 end while; 36 endl 37 end do; 38 endl 39 40 end subr nldump; $ end - nldump 1 .=member hadump 2 subr hadump; $ list contents of ha 3 size i(ps); $ index 4 size l(ps); $ line being printed 5 +* hatitle = 6' i ep var scon labn trcf chnx lbin char name = ha ='** 7 size lines(ps); $ number of lines to list 8 size h(hasz); $ entry being dumped 9 size lp(ps); $ position in line 10 size atright(1); $ on when just listed entry at right of page 11 12 endl 13 textl(' ha contents') endl 14 atright = yes; 15 lines = 0; 16 do i = 1 to hamax; 17 h = ha(i); 18 if (hainuse h = 0) cont do; $ ignore if not used 19 if atright then 20 endl; 21 22 lines = lines + 1; 23 if (lines - 20*(lines/20))=1 then $ list label 24 endl textl(hatitle) tabl(60) textl(hatitle) endl 25 end if; 26 atright = no; 27 else 28 tabl(60); $ advance for right entry 29 atright = yes; $ indicate that now at right 30 end if; 31 32 intl(i) 33 intl((ep h)) 34 intl((var h)) 35 intl((hascon h)) 36 intl((labno h)) 37 intl((tracef h)) 38 intl((chinxf h)) 39 intl((namintern h)) 40 intl((nchars h)) 41 if (var h) ! (labno h) then $ if name or label, list name 42 until yes; $ quit if should not list name. 43 if ep h then $ if this is in -voa-. 44 if (const voa(ep h)) quit until; $ no name if c 45 end if; 46 47 skipl(1) naml(i) 48 end until; 49 end if; 50 end do; 51 endl 52 53 end subr hadump; 1 .=member voadump 2 subr voadump(lo, hi); $ list voa contents. 3 $ this routine generates a symbolic dump of the voa from 4 $ locations -lo- through -hi-. 5 $ the -ha-, -xha-, and -nl- are also dumped. 6 7 size lo(ps); $ starting location for dump 8 size hi(ps); $ 1 + last index to list. 9 size hap(ps); $ ha index if in ha. 10 size i(ps); $ voa index 11 size l(ps); $ line number during xarg dump 12 size v(voasz); $ voa entry being dumped 13 size tlines(ps); $ number of lines since title last listed. 14 size opcodeval(ps); $ value of opcode 15 size naymval(ps); $ value of naym field 16 size vlenval(ps); $ value of vlen 17 size vbegval(ps); $ value of vbeg 18 +* optitle = 19' i opcd syze oup inp1 inp2 inp3 db luse abeg alen dflv kb a 20m eb ch naym'** 21 +* vartitle = 22' i syze dimn const temb type madr mblk arg argn lxty sign vbeg vle 23n dflv kb am xf nuse naym'** 24 size oplab(sds(5)); dims oplab(nopcodes); 25 data oplab = 26 ' +', ' -', ' gt', ' lt',' ge', $ 1-5 27 ' le', ' eq', ' ne', ' *', ' /', $ 6-10 28 ' or', '.seq.', ' and', ' exor', '.sne.', $ 11-15 29 ' .nb.', ' .fb.', '.not.', 'fcall', 'scall', $ 16-20 30 ' a=b', ' data', ' f x=', ' io', ' ret', $ 21-25 31 ' =.f.', ' if', 'label', ' goto', ' goby', $ 26-30 32 '=a(i)', 'a(i)=', 'f a(=', 'ifnot', ' .cc.', $ 31-35 33 ' .in.', '= .e.', '= .s.', ' e x=', '.s.x=', $ 36-40 34 'e.a(=', 's.a(=', 'rl +', 'rl -', 'rl gt', $ 41-45 35 'rl lt', 'rl ge', 'rl le', 'rl eq', 'rl ne', $ 46-50 36 'rl *', 'rl /', 'rl -', 'float', ' ifix', $ 51-55 37 ' abs', ' iabs', ' aint', ' int', ' amod', $ 56-60 38 ' mod', ' sign', 'isign', ' dim', ' idim', $ 61-65 39 ' exp', ' alog', 'alg10', ' sin', ' cos', $ 66-70 40 ' tanh', ' sqrt', ' atan', 'atan2', ' list', $ 71-75 41 '.pad.'; $ 76 42 43 endl textl(' voa dump from ') intl(lo) textl(' to ') intl(hi-1) 44 endl endl endl 45 46 $ list variables first 47 textl(' variables, temporaries, constants (opb=no)'); endl; 48 tlines = 0; 49 do i = lo to hi-1; 50 v = voa(i); 51 if (opb v = yes) cont do; $ ignore operations 52 tlines=tlines + 1; 53 if (tlines - 20*(tlines/20)) = 1 then 54 endl textl(vartitle) endl 55 end if; 56 intl(i) 57 intl((syze v)) 58 intl((dimn v)) 59 intlp((const v), 6) 60 intl((temb v)) 61 intl((type v)) 62 intlp((madr v), 6) 63 intl((mblk v)) 64 intl((arb v)) 65 intl((argno v)) 66 intl((lextype v)) 67 intl((signbit v)) 68 vbegval = vbeg v; 69 intl(vbegval) 70 vlenval = vlen v; 71 intl(vlenval) 72 intl((deflev v)) 73 intlp((keeb v), 3) 74 naymval = naym v; 75 intlp((amode v), 3) 76 intlp((isafnct v), 3) 77 intlp((varnuse v), 5) 78 intl(naymval) 79 skipl(2) 80 $ if variable, print name 81 $ if string constant, print first word of constant in display 82 $ if non-string constant, print first word in octal 83 $ if temporary, print 'temporary' 84 $ if subroutine or function, print first word of name 85 if temb v then textl(' temporary') 86 elseif const v then 87 if lextype v = rztok ! lextype v = sstok ! 88 lextype v = strtok 89 then wordl(val(vbegval)); 90 else 91 if signbit v then charl(1r-); end if; $ note 92 $ folded constants, negative result 93 call octlr(val(vbegval)); 94 if syze v < 17 then $ if small, print integer 95 skipl(2) intl(val(vbegval)); end if; 96 end if; 97 else $ not constant, print first word of name 98 naml(naymval); end if; 99 endl 100 end do; 101 102 setlpos(1); charl(1r1) endl; $ page eject 103 104 textl(' operations (opb=yes)'); endl 105 tlines = 0; 106 do i = lo to hi-1; 107 v = voa(i); 108 if (opb v = no) cont do; 109 tlines = tlines + 1; 110 if (tlines -20*(tlines/20)) = 1 then 111 endl textl(optitle) endl end if; 112 113 intl(i) 114 opcodeval = opcode v; 115 intl(opcodeval) 116 skipl(1) 117 textl(( oplab(opcode v)) ) 118 intl((syze v)) 119 intl((oup v)) 120 intl((inp1 v)) 121 intl((inp2 v)) 122 intl((inp3 v)) 123 intl( (dboup v)*1000 +(db1 v)*100 + (db2 v)*10 + (db3 v) ) 124 intl((lastuse v)) 125 intl((argbeg v)) 126 intl((arglen v)) 127 intl((deflev v)) 128 intlp((keeb v), 3) 129 intlp((amode v), 3) 130 intlp((seblk v), 3) 131 intlp((bytaln v), 3) 132 naymval = naym v; 133 intl(naymval) 134 skipl(2) 135 $ if -data- statement, print name of target 136 $ if -call-, print name of called routine 137 if opcodeval=op_call then textl('call ') end if; 138 if opcodeval = op_data ! opcodeval=op_fcall 139 ! opcodeval=op_call then 140 naml(naymval); 141 end if; 142 143 if blkendtype(opcodeval)>=7 & blkendtype(opcodeval)<=10 then 144 naml(naym voa(inp1 v)); 145 textl(' =') end if; 146 147 148 $ if label, list name enclosed in /. 149 if opcodeval=op_lab then 150 charl(1r/) naml(naymval) charl(1r/) 151 end if; 152 153 endl 154 end do; 155 156 end subr voadump; 1 .=member xargdump 2 subr xargdump; $ dump xarg. 3 size i(ps), l(ps); $ loop indices. 4 size tlines(ps); $ number of lines. 5 6 $ list xarg contents, 5 elements per line. 7 skipl(20) textl('xarg contents') endl 8 textl(' i rep d voa') endl 9 if (xargptr<=1) return; 10 tlines = (xargptr+4)/5; $ number of lines 11 do l = 1 to tlines; 12 i = l; 13 while i < xargptr; 14 if i^=l then skipl(5) end if; 15 intl(i) charl(1r.) 16 intlp(xarg_rep xarg(i), 4) intlp(xarg_db xarg(i), 2) 17 intl(xarg_voa xarg(i)) 18 i = i + tlines; 19 end while; 20 endl 21 end do; 22 endl 23 24 end subr xargdump; 1 .=member mbadump 2 subr mbadump; $ list contents of mba. 3 size i(ps); $ loop index. 4 size hap(ps); $ ha index for nameset entry. 5 if mbaptr then $ list mba contents. 6 endl textl('contents of machine block array (mba).') endl 7 textl(' i used def chain lengh xha ha name') endl 8 do i = 1 to mbaptr; 9 intl(i) intl(mbused mba(i)) 10 intl(mbdef mba(i)) intlp(mbchain mba(i), 6) 11 intlp(mblen mba(i), 6) intl(mbxha mba(i)) 12 hap = mbha mba(i); intl(hap) 13 if hap then $ if in ha, give name 14 skipl(1) naml(hap) end if; 15 endl 16 end do; 17 endl 18 end if; 19 20 return; 21 end subr mbadump; 1 .=member xhadump 2 subr xhadump; $ list contents of xha 3 size i(ps); $ index 4 size l(ps); $ line being printed 5 +* xhatitle = 6' i nlno link mba bif char name == xha =='** 7 size lines(ps); $ number of lines to list 8 size h(xhasz); $ entry being dumped 9 size lp(ps); $ position in line 10 size atright(1); $ on when just listed entry at right of page 11 12 endl textl(' xha contents') endl 13 atright = yes; 14 lines = 0; 15 do i = 1 to xhamax; 16 h = xha(i); 17 if (h=0) cont do; $ ignore zero entries 18 19 if atright then 20 lines = lines + 1; endl 21 if (lines - 20*(lines/20))=1 then $ list label 22 endl textl(xhatitle) tabl(60) textl(xhatitle) endl 23 end if; 24 atright = no; 25 else 26 tabl(60); $ advance for right entry 27 atright = yes; $ indicate that now at right 28 end if; 29 30 intl(i) 31 intl((nlno h)) 32 intl((xlink h)) 33 intl((xnsblk h)) 34 intl((xhabif h)) $ builtin function index 35 intl((xnchars h)) 36 skipl(1) call xsdsnamr(i); textl(sdsnamstr) 37 end do; 38 endl endl 39 40 end subr xhadump; 1 .=member csadump 2 subr csadump(clow, chi); $ list contents of -csa- 3 $ dump of compound statement array routine 4 size clow(ps); $ low index of array 5 size chi(ps); $ hi index 6 size i(ps); $ do loop variable 7 size csam(csasz); $ csa entry 8 size types(sds(7)); dims types(cstypes); $ names of cs types 9 data 10 types(cstype_subr) = 'sub': types(cstype_fnct) = 'fnct': 11 types(cstype_while)= 'whil': types(cstype_until) = 'untl': 12 types(cstype_if) = 'if': types(cstype_do) = 'do': 13 types(cstype_prog) = 'prog':types(cstype_nameset) = 'nameset'; 14 15 16 textl(' ') endl 17 textl(' c o s a d u m p') endl 18 textl(' typ tlbl blbl elbl dolo dohi inc var sign') 19 textl(' iftyp') endl 20 do i = clow to chi; 21 csam = csa(i); $ elemt of stack 22 intl(i) textl(types(cstype csam)) tabl(15) 23 intl(testlbl csam) intl(bodylbl csam) intl(endlbl csam) 24 intl(dolop csam) intl(dohip csam) intl(doincp csam) 25 intl(dovarp csam) intl(dosignp csam) 26 intl(csiftype csam) endl 27 end do; 28 29 end subr csadump; 1 .=member arastar 2 subr arastar(lib,max,tot,rout); $compute usage of arrays 3 size lib(ws+1); $ array name 4 size max(ps); $ max no of words in array 5 size tot(ps); $ no of words used 6 size rout(ws+1); $ routine in which max usage occurred 7 textl(lib) tabl(15) intl(max) 8 skipl(5) intl(tot) skipl(5) textl(rout) 9 tabl(45) intl(max-tot) endl 10 totwaste = totwaste + (max-tot); 11 return; 12 end subr arastar; 1 .=member genexit 2 subr genexit; $ generator phase exit routine 3 $ the gen part of compiler is to exit through this routine 4 $ if global -exitcode- is non-zero, abnormal end is indicated, 5 $ 0 indicates normal exit. 6 $ this routine collects compilation statistics, signs off, etc. 7 8 size i(ps); $ do loop index 9 size xhaused(ps); $ no of words in xha occupied ldsb 30 size termcode(ws); $ termination code. 10 12 textl(' ') endl $ blank line 13 $ first we check that parsing has terminated after end 14 $ of routine, issuing diagnostic otherwise 15 if voptr ^= voafnct then $ non-standard end ldsc 13 terml(yes); $ this will go to terminal output 16 nerrors = nerrors+1; $ indicate error 17 call lstlin; $ list input line. mgfc 25 .+s10 error_s10; $ give s10 error character. 18 textl(error_notice) textl('not terminating at end of routine') 19 endl ldsc 14 terml(no); $ end of terminal output 20 end if; 22 23 call clossio(tokenfile, iorc); 24 25 if crossrefoption then $ complete reference file. 26 crefput(0); $ indicate end of file. 27 if crbuffptr then $ flush buffer if has data. 28 call wtrwsio(crfile, iorc, crbuff, 1, crbuffmax); 29 end if; 30 $ if proc directory wanted, generate it. 31 if proclist then $ if producing directory, 32 call rewisio(crfile, iorc, access_read); 33 call pdsort; $ produce directory. 34 end if; 35 call clossio(crfile, iorc); 36 end if; 37 38 if (lcs_opt=0) go to endofstat; $ if no want statistics. 39 call stitlr(1, 'statistics for this parse.'); 40 ejectlp(20); $ put statistics listing on new page if wont fit 41 42 textl('little parse statistics.') endl 43 textl(' array max used procedure unused') endl 44 +* arastat(nam,max,tot,rout) = 45 call arastar(nam, max, tot, rout); ** 46 47 arastat('ha' ,hamax ,loadha ,loadrha ); 48 arastat('names' ,namesmax ,loadnames ,loadrnames ); 49 arastat('nl' ,nlmax ,nlptr , ' ' ); 50 arastat('tlist' ,tlistmax ,loadtlist ,loadrtlist); 51 arastat('val' ,valmax ,loadval ,loadrval ); 52 arastat('voa' ,vomax*2 ,loadvoa*2 ,loadrvoa ); 53 arastat('xarg' ,xargmax ,loadxarg ,loadrxarg ); 54 55 xhaused = 0; $ reset used count for xha 56 do i = 1 to xhamax; 57 if (xnameptr xha(i) = 0) cont do; $ ignore if empty 58 xhaused = xhaused + 1; $ update used count 59 end do; 60 61 arastat('xha' ,xhamax ,xhaused ,' ' ); 62 arastat('xnames' ,xnamesmax ,xnamesptr ,' ' ); 63 64 textl(' ') endl 65 textl('unused memory words ') intl(totwaste) endl endl endl 66 .+haprobes. 67 tintl('number of times blkend reset deflev ',blkendreset);endl 68 tintl('number of times emass reset deflev',emassreset); 69 tintl('ha examined ', tothaprobes) textl(' times ') endl 70 tintl('ha entries examined ', tothaexam) endl 71 ..haprobes 72 .+ifconstat. 73 if ifcontot then $ report on constant ifs found 74 textl('found') intl(ifcontot) 75 textl(' if''s with constant inputs.') intl(ifcongotos) 76 textl(' changed to goto''s.') endl 77 end if; 78 ..ifconstat 79 .+ncfstat. 80 if ncftot then $ if any negative constants folded 81 tintl('total number of negative constants', ncftot) endl 82 end if; 83 ..ncfstat 84 85 /endofstat/ $ here when statistics listed. 86 87 terml(yes); $ this goes to terminal 88 if nerrors then 89 intl(nerrors) textl(' errors detected.') endl 92 end if; 93 ldsa 115 .+rep. ldsa 116 if rep_opt then $ if reporting, close report file. ldsa 117 file repfile access = release; ldsa 118 end if; ldsa 119 ..rep 94 terml(no); $ end of terminal listing ldsb 31 ldsb 32 ldsb 33 $ determine termination code. ldsb 34 ldsb 35 termcode = 0; ldsb 36 if (nwarnings) termcode = 4; ldsb 37 if (nerrors) termcode = 8; ldsb 38 95 if voawrt then $ if writing voa file 96 vof = 0; $ clear frame 97 vof_code vof = voaeof_code; $ indicate end of file 98 vofhdrseq = vofhdrseq+1; vof_hdrseq vof = vofhdrseq; 99 write voafile, vof; 100 file voafile access = release; 101 else 102 terml(yes); $ write this to terminal file 103 endl textl('end of compilation - not writing voa file') endl 104 terml(no); call clsterm; ldsb 39 call ltlfin(0, termcode); 106 end if; 107 108 if exitcode then $ if quit due to error, abort 109 call lstlin; $ list input line. 110 terml(yes); $ output this to terminal mgfc 26 .+s10 error_s10; $ give s10 error character. 111 textl(error_notice) 112 textl(' abnormal termination due to previous error') endl 113 textl('procedure ') textl(currsubrname) endl 114 call clsterm; $ close terminal output file 115 call ltlfin(1,1); $ and abort job 116 end if; 117 118 terml(no); call clsterm; $ close terminal file ldsb 40 call ltlterm(2, termcode); 120 121 end subr genexit; 122 $ this concludes the gen phase of the little compiler. 123 $ (just wait until we write a big compiler.)