home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / fweb153.zip / fweb-1.53 / web / ratfor.c < prev    next >
Text File  |  1995-09-23  |  68KB  |  3,522 lines

  1. #if(0)
  2.   FTANGLE v1.53, created with UNIX on "Thursday, September 21, 1995 at 15:06."  \
  3.   COMMAND LINE: "web/ftangle web/ratfor -A -# --F -= 1.53/web/ratfor.c" \
  4.   RUN TIME: "Saturday, September 23, 1995 at 16:17." \
  5.   WEB FILE:    "web/ratfor.web" \
  6.   CHANGE FILE: (none)
  7. #endif
  8. #define _RATFOR_h  
  9. #define _ratfor_  /* Used in \.{r\_type.web}. */ \
  10.  
  11. #define stringg  (eight_bits)02 /* Extended ASCII alpha should not appear. (The funny \
  12.     spelling is to avoid conflict with the VAX' \.{stdlib}.) */
  13. #define constant  (eight_bits)03 /* Numerical constant. */
  14. #define begin_Xmeta  or_or
  15. #define end_Xmeta  star_star
  16. #define cdir  (eight_bits)06 /* Brackets compiler directive.. */
  17. #define colon_colon  (eight_bits)011 /* \Cpp\ and \Fortran--90: `$\CF$'. */ \
  18.  
  19. #define join  (eight_bits)0177 /* |ASCII| delete will not appear. */ \
  20.  
  21. #define ID0  0200 /* $128 =$ end of the 7-bit ASCII codes. */
  22. #define TOKEN1(a)((a)<ID0)/* Is |a|~a single-byte token? */ \
  23.  
  24. #define MACRO_ARGUMENT  0377 /* See the related definition and discussion of \
  25.                 |MOD0|. */
  26. #define BASE2  0400 /* |0xFF + 1 = 0x100 = 256| */ \
  27.  
  28. #define MODULE_NAME  10240 /* |024000= 10240 = (0250-0200)*0400| */
  29. #define MODULE_NUM  20480 /* |050000 = 20480 = (0320-0200)*0400| */
  30. #define LINE_NUM  53248L /* |0150000==0320*0400| */ \
  31.  
  32. #define IDENTIFIER(left,right) \
  33. ((sixteen_bits)(((left)-ID0)*BASE2+(sixteen_bits)(right))) \
  34. /* Construct two-byte token out of its constituents. */ \
  35.  
  36. #define LEFT(a,id)((eight_bits)(((a)/BASE2+(id))))/* Make left-hand byte out of \
  37.                     |sixteen_bits|. */
  38. #define RIGHT(a)((eight_bits)(((a)%BASE2)))/* Make right-hand byte. */ \
  39.  
  40. #define ignore  0 /* Control code of no interest to \.{TANGLE}. */ \
  41.  
  42. #define begin_comment0  (eight_bits)0376 /* Sent from |input_ln|; marker for long comment. */
  43. #define begin_comment1  (eight_bits)0375 /* As above; marker for short comment. */ \
  44.  
  45. #define module_number  (eight_bits)0201 /* Code returned by |get_output| for mod.\ numbers. */
  46. #define identifier  (eight_bits)0202 /* Code returned by |get_output| for identifiers. */
  47. #define id_keyword  (eight_bits)0203 /* As above, but for expandable keyword. */ \
  48.  
  49. #define L_switch  (eight_bits)0257 /* Control code for `\.{@L}'. */
  50. #define begin_FORTRAN  (eight_bits)0260
  51. #define begin_RATFOR  (eight_bits)0261
  52. #define begin_C  (eight_bits)0262
  53. #define begin_LITERAL  (eight_bits)0263 \
  54.  
  55. #define verbatim  (eight_bits)0264 /* Can't be~|02| as for \.{fweave}, because \
  56.                 |stringg| is defined to be that. */ \
  57.  
  58. #define invisible_cmnt  (eight_bits)0265 /* Control code for `\.{@\%}'. */
  59. #define compiler_directive  (eight_bits)0266 /* No longer used. */
  60. #define Compiler_Directive  (eight_bits)0267 /* Control code for `\.{@?}'. */
  61. #define no_index  (eight_bits)0300 /* Control code for `\.{@-}'. */
  62. #define yes_index  (eight_bits)0301 /* Control code for `\.{@+}'. */ \
  63.  
  64. #define ascii_constant  (eight_bits)0302 /* Control code for `\.{@'}'. */
  65. #define begin_vcmnt  (eight_bits)0303 /* Control code for `\.{@\slashstar}'. */
  66. #define big_line_break  (eight_bits)0304 /* Control code for `\.{@\#}'. */ \
  67.  
  68. #define begin_bp  (eight_bits)0305
  69. #define insert_bp  (eight_bits)0306 \
  70.  
  71. #define begin_meta  (eight_bits)017 /* Control code for |"@("|. */
  72. #define end_meta  (eight_bits)027 \
  73.  
  74. #define TeX_string  (eight_bits)0307
  75. #define xref_roman  (eight_bits)0310
  76. #define xref_typewriter  (eight_bits)0311
  77. #define xref_wildcard  (eight_bits)0312 \
  78.  
  79. #define control_text  (eight_bits)0313 /* Control code for `\.{@t}', `\.{@\^}', etc. */ \
  80.  
  81. #define begin_nuweb  (eight_bits)0314
  82. #define no_mac_expand  (eight_bits)0315 /* Control code for `\.{@\~}' */
  83. #define set_line_info  (eight_bits)0316 /* Expt'l control code for `\.{@Q}'. */ \
  84.  
  85. #define formatt  (eight_bits)0320 /* Control code for `\.{@f}'. */ \
  86.  
  87. #define limbo_text  (eight_bits)0323 /* Control code for `\.{@l}'. */
  88. #define op_def  (eight_bits)0324 /* Control code for `\.{@v}'. */
  89. #define macro_def  (eight_bits)0325 /* Control code for `\.{@W}'. */ \
  90.  
  91. #define ignore_defn  (eight_bits)0327 /* Stuff to here should be ignored when scanning defn. */ \
  92.  
  93. #define new_output_file  (eight_bits)0331 /* Control code for `\.{@o}'. */ \
  94.  
  95. #define definition  (eight_bits)0332 /* Control code for `\.{@d}'. */
  96. #define undefinition  (eight_bits)0333 /* Control code for `\.{@u}'. */
  97. #define WEB_definition  (eight_bits)0334 /* Control code for `\.{@m}'. */ \
  98.  
  99. #define m_ifdef  (eight_bits)0335
  100. #define m_ifndef  (eight_bits)0336
  101. #define m_if  (eight_bits)0337
  102. #define m_else  (eight_bits)0340
  103. #define m_elif  (eight_bits)0341
  104. #define m_endif  (eight_bits)0342
  105. #define m_for  (eight_bits)0343
  106. #define m_endfor  (eight_bits)0344
  107. #define m_line  (eight_bits)0345
  108. #define m_undef  (eight_bits)0346 \
  109.  
  110. #define end_of_buffer  (eight_bits)0347 \
  111.  
  112. #define begin_code  (eight_bits)0350 /* Control code for `\.{@a}'. */
  113. #define module_name  (eight_bits)0351 /* Control code for `\.{@<}'. */ \
  114.  
  115. #define new_module  (eight_bits)0352 /* Control code for `\.{@\ }' and `\.{@*}'. */ \
  116.  
  117. #define cur_end  cur_state.end_field /* Current ending location in |tok_mem|. */
  118. #define cur_byte  cur_state.byte_field /* Location of next output byte in |tok_mem|. */
  119. #define cur_name  cur_state.name_field /* Pointer to current name being expanded. */
  120. #define cur_repl  cur_state.repl_field /* Pointer to current replacement text. */
  121. #define cur_mod  cur_state.mod_field /* Current module number being expanded. */ \
  122.  
  123. #define cur_language  cur_state.language /* Current language. */
  124. #define cur_global_language  cur_state.global_params.Language \
  125. /* Global language for this level. */ \
  126.  \
  127. /* Current flags. */
  128. #define cur_params  cur_state.params /*  Local flags. */
  129. #define cur_global_params  cur_state.global_params /*  Global flags. */ \
  130.  \
  131. /* Current macro buffer params. */
  132. #define macrobuf  cur_state.macro_buf
  133. #define macrobuf_end  cur_state.macro_buf_end \
  134.  
  135. #define semi  01 /* Kludge! */ \
  136.  
  137. #define SILENT  (boolean)NO
  138. #define COMPLAIN  (boolean)YES \
  139.  
  140. #define OUTER_MACRO  0xFF
  141. #define OUTER_UNMACRO  0xFE
  142. #define UNDEFINED_MACRO  0xFD \
  143.  
  144. #define MAX_XLEVELS  200 \
  145.  
  146. #define equiv  equiv_or_xref /* Info corresponding to names. */
  147. #define EQUIV  ASCII HUGE*/* For casting into the above field. */ \
  148.  \
  149. /* Note that the following function retrieves not only regular \WEB\ \
  150. macros, but also built-in functions. */
  151. #define MAC_LOOKUP(cur_val)(cur_val<MODULE_NAME? \
  152. (text_pointer)(name_dir+(cur_val))->equiv:NULL) \
  153.  
  154. #define macro  0 /* For appending a macro; distinguishes from a module. */ \
  155.  \
  156.  \
  157. /* The following are the values of the |macro_type| field of \
  158. |name_pointer|s. */
  159. #define NOT_DEFINED  0
  160. #define DEFERRED_MACRO  1 /* Numbers chosen so that |DEFERRED_MACRO + \
  161.     scanning_defn| gives the two choices. */
  162. #define IMMEDIATE_MACRO  2
  163. #define FILE_NAME  3 /* Used to prevent truncations from affecting file names. */ \
  164.  
  165. #define MAKE_RECURSIVE  052 /* To allow a WEB macro to be recursive, preface its \
  166.     definition by this symbol, as in `\.{@m *R R}'.  (Recursive macros \
  167.     are not presently implemented.) */ \
  168.  
  169. #define AUTO_INSERT  0133
  170. #define END_AUTO_INSERT  0135 \
  171.  \
  172. /* Guard against overflow of the macro buffer. */
  173. #define MCHECK(n,reason)if(mp+(n)>macrobuf_end) \
  174. mbuf_full((unsigned long)(n),(outer_char*)reason) \
  175.  
  176. #define BP_MARKER  1 \
  177.  
  178. #define PROPER_END(end) \
  179. end= (np+1)->byte_start; \
  180. if(*end==BP_MARKER&&np!=npmax)end= ((BP*)end)->byte_start \
  181.  
  182. #define MAX_ID_LENGTH  32 /* Truncated identifiers can't be longer than this. */ \
  183.  
  184. #define UNNAMED_MODULE  0
  185. #define N_IDBUF  100 \
  186.  
  187. #define fatal_RAT_ERROR(s1,s2,s3){ \
  188. RAT_error(ERROR,OC(s1),0);FATAL(R,s2,s3);} \
  189.  
  190. #define COPY_COMMENTS  NO
  191. #define SAVE_COMMENTS  YES \
  192.  
  193. #define current_cmd  lbl[wlevel].cmd
  194. #define do_or_while  (current_cmd==do_CMD||current_cmd==while_CMD) \
  195.  
  196. #define s_top  lbl[wlevel].Top
  197. #define s_next  lbl[wlevel].Next
  198. #define was_next  lbl[wlevel].was_Next
  199. #define s_break  lbl[wlevel].Break
  200. #define was_break  lbl[wlevel].was_Break
  201. #define s_case  lbl[wlevel].Case
  202. #define s_default  lbl[wlevel].Default
  203. #define icase  lbl[wlevel].Icase \
  204.  
  205. #define DONT_PRINT_IF_0  YES
  206. #define PRINT_IF_0  NO \
  207.  
  208. #define TO_OUTPUT  NO /* First  argument of |copyd|. */
  209. #define TO_MEMORY  YES \
  210.  
  211. #define SAVE_IN_MEM(a){if(cur_case->txt.next>=cur_case->txt.end) \
  212. resize(&cur_case->txt.start,BIG_SAVE8, \
  213. &cur_case->txt.next, \
  214. &cur_case->txt.end); \
  215. *(cur_case->txt.next++)= (eight_bits)(a);} \
  216.  
  217. #define SAVE_16  {SAVE_IN_MEM(a0)SAVE_IN_MEM(a1)}/* Store a 16-bit token. */ \
  218.  
  219. #define XPN_CASES  YES
  220. #define DONT_XPN_CASES  NO \
  221.  
  222. #define BLEVELS  100 \
  223.  
  224. #define copy_to(r_after)copy_2to(NOT_BEFORE,r_after) \
  225.  
  226. #define BRACE_ONLY  1 /* In some situations such as after |switch|, only a brace \
  227.             is expected. */ \
  228.  
  229. #define unmatched(l,r) \
  230. RAT_error(WARNING,OC("Ignored '%c' not matched with %s"),2,XCHR(r),qdelim(l)) \
  231.  
  232. #define inserted(n,l0,r0,l,level) \
  233. RAT_error(WARNING,OC("Inserted %d '%c' to balance '%c' at %s level %d"),5,n,XCHR(r0),XCHR(l0),qdelim(l),level) \
  234.  \
  235. /* Copy, then immediately output. */
  236. #define COPY_TO(r)psave_buffer= SAVE_AFTER(&save_buffer,BIG_SAVE8,r); \
  237. copy_out(save_buffer,psave_buffer,!macro) \
  238.  
  239. #define COPY_2TO(r_before,r_after) \
  240. psave_buffer= save_out(&save_buffer,BIG_SAVE8,r_before,r_after); \
  241. copy_out(save_buffer,psave_buffer,!macro) \
  242.  
  243. #define INDENT  indent_level++;blank_out(1)
  244. #define OUTDENT  indent_level--;out_pos-= indnt_size \
  245.  
  246. #define LABEL(lbl)out_label(DONT_PRINT_IF_0,(STMT_LBL)(lbl))/* Statement label. */
  247. #define NUMBER(lbl)out_label(PRINT_IF_0,(STMT_LBL)(lbl))/* Ordinary integer, \
  248.                             including~0. */ \
  249.  
  250. #define PARENS  copyd(TO_OUTPUT,XPN_CASES,050,051,NO)/* Copies text between \
  251.                 (and including) parens. */ \
  252.  
  253. #define NL  out_char(012)
  254. #define LP  out_char(050)
  255. #define RP  out_char(051)
  256. #define COMMA  out_char(054)
  257. #define NOT  out_char(041)
  258. #define EQUALS  out_char(075)
  259. #define MINUS  out_char(055)
  260. #define EQ_EQ  out_char(eq_eq)
  261. #define OR  out_char(or_or)
  262. #define LT  out_char(074)
  263. #define GT  out_char(076) \
  264.  
  265. #define IF(stmt_num)LABEL(stmt_num);id0(id__IF)
  266. #define THEN  id0(id__THEN);NL
  267. #define ELSE  id0(id__ELSE)
  268. #define ENDIF  id0(id__ENDIF);if(symbolic_label)id0(symbolic_label);NL
  269. #define ENDWHERE  id0(id__ENDWHERE);NL
  270. #define GOTO(stmt)id0(id__GOTO);LABEL(stmt);NL
  271. #define CONTINUE(stmt)LABEL(stmt);id0(id__CONTINUE);NL
  272. #define RETURN  id0(id__RETURN);NL
  273. #define END  id0(id__END);NL \
  274.  
  275. #define END_DO  id0(id__END);id0(id__DO);NL
  276. #define END_SELECT  id0(id__END);id0(id__SELECT);NL \
  277.  
  278. #define NOT_LOOP(id,msg)not_loop(OC(id),OC(msg)) \
  279.  
  280. #define SAVE8  200 /* Default length of buffer for parenthesized stuff like \
  281.             |if(...). */
  282. #define BIG_SAVE8  10000 /* Default length for |case| text. */ \
  283.  
  284. #define id__ignore  ignore \
  285.  
  286. #define UNEXPECTED(id)unexpected(OC(id)) \
  287.  
  288. #define NSWITCHES  20 /* Nesting level for |switch| statements. */
  289. #define NCASES  257 /* Number of |case| labels in a |switch|. */
  290. #define cur_switch  switches[switch_level] \
  291.  
  292.  
  293.  
  294.  
  295. #ifndef part
  296. #define part 0 /* Standard value, when the files aren't split. */
  297. #else
  298. #if(part != 1 && part != 2 && part != 3)
  299. #define part 1 /* Should issue error message here. */
  300. #endif
  301. #endif /* |part| */
  302.  
  303.  
  304.  
  305.  
  306. #if(part == 0 || part == 1)
  307. #define part1_or_extern
  308. #define SET1(stuff)  =  stuff
  309. #define TSET1(stuff)  =  stuff
  310. #else
  311. #define part1_or_extern extern
  312. #define SET1(stuff)
  313. #define TSET1(stuff)
  314. #endif
  315.  
  316.  
  317.  
  318.  
  319.  
  320. #include "typedefs.h"
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327. #include "map.h"
  328.  
  329.  
  330.  
  331.  
  332. typedef struct
  333. {
  334. eight_bits HUGE*tok_start;/* Pointer into |tok_mem| (for a module or \
  335. regular macro).  For an internal macro, points to the internal function. */
  336. sixteen_bits text_link;/* Relates replacement texts  (0 for a macro). */
  337. boolean Language;/* Which language referenced this name. */
  338. eight_bits nargs;/* Number of macro arguments. */
  339. unsigned moffset:8,/* Offset to macro replacement text from start. */
  340. recursive:1,/* Is this macro allowed to be recursive? */
  341. var_args:1,/* Can it have variable number of arguments? */
  342. module_text:1,/* Distinguishes from preprocessor fragment. */
  343. built_in:1;/* Is it a built-in function (internal macro)? */
  344. }text;
  345.  
  346. typedef text HUGE*text_pointer;
  347.  
  348.  
  349.  
  350. typedef struct{
  351. eight_bits HUGE*end_field;/* Ending location of replacement text. */
  352. eight_bits HUGE*byte_field;/* Present location within replacement text. */
  353. name_pointer name_field;/* |byte_start| index for text being output. */
  354. text_pointer repl_field;/* |tok_start| index for text being output. */
  355. sixteen_bits mod_field;/* Module number, or zero if not a module. */
  356. PARAMS global_params,params;/* Various flags. */
  357. eight_bits HUGE*macro_buf,HUGE*macro_buf_end;/* Current macro buffer. */
  358. }output_state;
  359.  
  360. typedef output_state HUGE*stack_pointer;
  361.  
  362.  
  363.  
  364. /* Precedence of the various operators. */
  365. typedef enum{BAD_TOKEN,OR_OR,AND_AND,BIT_OR,BIT_XOR,BIT_AND,LOG_EQ,LOG_LT,
  366. BIT_SHIFT,PLUS_MINUS,TIMES,EXP,UNARY,HIGHEST_UNARY}PRECEDENCE;
  367.  
  368. /* An operator, together with its precedence. */
  369. typedef struct
  370. {
  371. eight_bits token;
  372. PRECEDENCE precedence;
  373. }OP;
  374.  
  375. /* The actual data value. */
  376. typedef union
  377. {
  378. long i;/* All integers are long, to humor the pc people. */
  379. double d;/* We handle just one floating-point type. */
  380. sixteen_bits id;/* An identifier token. */
  381. OP op;
  382. }VALUE;
  383.  
  384. /* Type of the data value. The relative order must be preserved here, \
  385. because it is used in the type promotion routine |promote|. */
  386. typedef enum{Int,Double,Id,Op}TYPE;
  387.  
  388. /* Complete data structure for the token; includes links to the next and \
  389. last |VAL| structures. */
  390. typedef struct val
  391. {
  392. VALUE value;/* The actual data value or operator token. */
  393. TYPE type;/* The type of value stored in |value|. */
  394. struct val HUGE*last,HUGE*next;/* Link to the last and next values. */
  395. }VAL;
  396.  
  397.  
  398.  
  399. typedef struct
  400. {
  401. sixteen_bits token[MAX_XLEVELS];
  402. int level;
  403. }XIDS;
  404.  
  405.  
  406.  
  407. #if(0)
  408. IN_COMMON boolean truncate_ids;/* Truncate identifers? */
  409. IN_COMMON unsigned short tr_max[];/* Truncate to this length. */
  410. IN_COMMON name_pointer npmax;/* |name_ptr - 1|. */
  411. #endif
  412.  
  413. /* Back-pointer structure points back to the original name in |name_dir|. */
  414. typedef struct Bp
  415. {
  416. ASCII c;/* Dummy byte that always remains~|BP_MARKER|. */
  417. LANGUAGE Language;
  418. CONST ASCII HUGE*byte_start,HUGE*byte_end;/* Points to original, \
  419. untruncated name. */
  420. struct Bp HUGE*next;/* Links to next back-pointer structure, in \
  421. case a truncated name came from more than one original name. */
  422. struct Trunc HUGE*Root;
  423. }BP;
  424.  
  425. /* Info about a truncated identifier. */
  426. typedef struct Trunc
  427. {
  428. boolean Language;/* All languages associated with this name. */
  429. size_t num[NUM_LANGUAGES];
  430. /* \# of instances of the truncated name. */
  431. ASCII HUGE*id,HUGE*id_end;/* Truncated variable name. */
  432. BP HUGE*first,HUGE*last;/* First and last back-pointer structures. */
  433. struct Trunc HUGE*next;/* Next structure in truncated chain. */
  434. }TRUNC;
  435.  
  436.  
  437.  
  438. IN_RATFOR int switch_level RSET(0);
  439.  
  440. /* The starting and ending positions of a token string. */
  441. typedef struct
  442. {
  443. eight_bits HUGE*start,HUGE*next,HUGE*end;
  444. }TEXT;
  445.  
  446. /* The info for one |case| or |default|. */
  447. typedef struct
  448. {
  449. STMT_LBL label;/* Statement label assigned to this |case|. */
  450. TEXT case_txt;/* The token string for the |case| value. */
  451. CASE_TYPE value;/* The numerical value of the above string. */
  452. TEXT txt;/* The body of the |case| or |default|. */
  453. boolean is_default;/* Distinguishes between |default| and |case|. */
  454. }CASE;
  455.  
  456. IN_RATFOR CASE HUGE*cur_case;/* A pointer to the current case being processed. */
  457.  
  458. /* A whole |switch|. */
  459. typedef struct
  460. {
  461. CASE HUGE*cases;/* The array of cases. */
  462. unsigned short ncases;/* How many cases? */
  463. boolean has_default;/* At most one |default| is allowed. */
  464. }SWITCH;
  465.  
  466. IN_RATFOR SWITCH HUGE*switches;/* Switches may be nested, so we need an array. */
  467.  
  468.  
  469.  
  470.  
  471. #include "t_type.h" /* Function prototypes for everything. */
  472.  
  473.  
  474.  
  475.  
  476. /* The shorter length here is primarily to keep the stack under control. \
  477. Now that |N_MSGBUF| is used  dynamically, maybe this statement isn't \
  478. necessary. */
  479. #ifdef SMALL_MEMORY
  480. #define N_MSGBUF 2000
  481. #else
  482. #define N_MSGBUF 10000
  483. #endif
  484.  
  485.  
  486.  
  487.  
  488.  
  489. EXTERN long max_texts;/* Number of replacement texts, must be $< 10240$. */
  490. EXTERN text HUGE*text_info;/* Dynamic array. */
  491. EXTERN text_pointer text_end;/* End of above. */
  492.  
  493. EXTERN long dtexts_max;/* Number of deferred replacement texts. */
  494. EXTERN text HUGE*txt_dinfo;/* Dynamic array. */
  495. EXTERN text_pointer textd_end;
  496.  
  497. EXTERN text_pointer text_ptr,txt_dptr;/* First unused position in |text_info| \
  498.                     and in |txt_dinfo|. */
  499.  
  500. EXTERN long max_toks;/* Number of bytes in compressed code. */
  501. EXTERN eight_bits HUGE*tok_mem;/* Dynamic array. */
  502. EXTERN eight_bits HUGE*tok_m_end;
  503.  
  504. EXTERN long max_dtoks;/* Number of bytes in deferred macros. */
  505. EXTERN eight_bits HUGE*tok_dmem;/* Dynamic array. */
  506. EXTERN eight_bits HUGE*tokd_end;
  507.  
  508. EXTERN eight_bits HUGE*tok_ptr,HUGE*tok_dptr;/* First unused position in \
  509.             |tok_mem| and in |tok_dmem|. */
  510. EXTERN eight_bits HUGE*mx_tok_ptr,HUGE*mx_dtok_ptr;/* Largest value \
  511.     assumed by |tok_ptr|  and |tok_ptrd|; for statistics. */
  512.  
  513. EXTERN text_pointer macro_text;
  514.  
  515.  
  516.  
  517. EXTERN output_state cur_state;/* |cur_end|, |cur_byte|, |cur_name|, \
  518.     |cur_repl|, |cur_mod|, |cur_global_language|, and |cur_language|. */
  519.  
  520. EXTERN long stck_size;/* Number of simultaneous levels of macro expansion. */
  521. EXTERN output_state HUGE*stack;/* Dynamic array: Info for non-current levels. */
  522. EXTERN stack_pointer stck_end;/* End of |stack|. */
  523. EXTERN stack_pointer stck_ptr;/* First unused loc.\ in the output state stack. */
  524.  
  525.  
  526.  
  527. IN_COMMON STMT_LBL max_stmt;/* See \.{common.web}. */
  528.  
  529. EXTERN sixteen_bits outp_line[NUM_LANGUAGES]
  530. #ifdef _FTANGLE_h
  531. #if(part == 0 || part == 1)
  532. = {1,1,1,1,1,1,1,1}
  533. #endif /* |part == 1| */
  534. #endif /* |_FTANGLE_h| */
  535. ;
  536.  
  537.  
  538.  
  539. EXTERN boolean mac_protected,in_string;
  540. EXTERN text_pointer macro_text;
  541. EXTERN long cur_val;
  542. EXTERN OUTPUT_STATE out_state;
  543. EXTERN int indent_level,out_pos,rst_pos,indnt_size;
  544. EXTERN eight_bits sent;
  545.  
  546. IN_COMMON STMT_LBL max_stmt;
  547. IN_COMMON sixteen_bits outp_line[];
  548.  
  549.  
  550.  
  551. /* Expandable input tokens. */
  552. IN_RATFOR sixteen_bits
  553. id_block,id_blockdata,id_break,
  554. id_case,
  555. #if(0)
  556. id_continue,
  557. #endif
  558. id_default,id_do,
  559. id_else,id_elseif,id_end,
  560. id_endif,
  561. id_for,
  562. #if(0)
  563. id_goto,
  564. #endif
  565. id_if,
  566. id_next,id_procedure,id_repeat,
  567. id_return,id_switch,id_then,id_until,
  568. id_while;
  569.  
  570. IN_RATFOR sixteen_bits id_function,id_program,id_subroutine;
  571.  
  572. IN_RATFOR sixteen_bits
  573. id_contains,id_elsewhere,id_endinterface,id_endtype,id_endmodule,
  574. id_endselect,id_endwhere,id_interface,id_module,id_type,id_where;
  575.  
  576. /* Non-expandable input tokens. */
  577. IN_RATFOR sixteen_bits id_data;
  578.  
  579. /* Output tokens. */
  580. IN_RATFOR sixteen_bits
  581. id__CASE,id__CONTINUE,id__DEFAULT,
  582. id__DO,id__ELSE,id__ELSEIF,id__END,
  583. id__ENDIF,id__EXIT,id__GOTO,id__IF,
  584. id__RETURN,id__THEN,
  585. id__WHILE;
  586.  
  587. /* More output tokens for \Fortran--90. */
  588. IN_RATFOR sixteen_bits
  589. id__CONTAINS,id__CYCLE,id__ENDWHERE,id__INTERFACE,id__MODULE,
  590. id__SELECT,id__TYPE,id__WHERE;
  591.  
  592.  
  593. /* The following tokens are printed as the result of \Ratfor\ translation. \
  594. (The lengths are filled in by |ini_out_tokens|.) */
  595. IN_RATFOR SPEC out_tokens[]
  596. #if(part == 0 || part == 1)
  597. = {
  598. {"CASE",0,NULL,&id__CASE},
  599. {"CONTINUE",0,NULL,&id__CONTINUE},
  600. {"DEFAULT",0,NULL,&id__DEFAULT},
  601. {"DO",0,NULL,&id__DO},
  602. {"ELSE",0,NULL,&id__ELSE},
  603. {"ELSEIF",0,NULL,&id__ELSEIF},
  604. {"END",0,NULL,&id__END},
  605. {"ENDIF",0,NULL,&id__ENDIF},
  606. {"EXIT",0,NULL,&id__EXIT},
  607. {"GOTO",0,NULL,&id__GOTO},
  608. {"IF",0,NULL,&id__IF},
  609. {"RETURN",0,NULL,&id__RETURN},
  610. {"THEN",0,NULL,&id__THEN},
  611. {"WHILE",0,NULL,&id__WHILE},
  612. {"",0,NULL,NULL}
  613. }
  614. #endif
  615. ;
  616.  
  617. IN_RATFOR SPEC out90_tokens[]
  618. #if(part == 0 || part == 1)
  619. = {
  620. {"CONTAINS",0,NULL,&id__CONTAINS},
  621. {"CYCLE",0,NULL,&id__CYCLE},
  622. {"ENDWHERE",0,NULL,&id__ENDWHERE},
  623. {"INTERFACE",0,NULL,&id__INTERFACE},
  624. {"MODULE",0,NULL,&id__MODULE},
  625. {"SELECT",0,NULL,&id__SELECT},
  626. {"TYPE",0,NULL,&id__TYPE},
  627. {"WHERE",0,NULL,&id__WHERE},
  628. {"",0,NULL,NULL}
  629. }
  630. #endif
  631. ;
  632.  
  633. /* The following is used during \FORTRAN-88\ |case| expansion to see \
  634. whether the last |case| ended with |break|. */
  635. eight_bits break_tokens[3];
  636.  
  637. /* These are the special \Ratfor\ tokens that are expanded. */
  638. IN_RATFOR SPEC spec_tokens[]
  639. #if(part == 0 || part == 1)
  640. = {
  641. {"block",0,x_block,&id_block},
  642. {"blockdata",0,x_blockdata,&id_blockdata},
  643. {"break",0,x_break,&id_break},
  644. {"case",0,(X_FCN(*)(VOID))x_case,&id_case},
  645. {"default",0,(X_FCN(*)(VOID))x_default,&id_default},
  646. {"do",0,x_do,&id_do},
  647. {"else",0,x_else,&id_else},
  648. {"elseif",0,x_els_if,&id_elseif},
  649. {"end",0,x_end,&id_end},
  650. {"endif",0,x_en_if,&id_endif},
  651. {"for",0,x_for,&id_for},
  652. {"function",0,x_function,&id_function},
  653. {"if",0,x_if,&id_if},
  654. {"next",0,x_next,&id_next},
  655. {"procedure",0,x_procedure,&id_procedure},
  656. {"program",0,x_program,&id_program},
  657. {"repeat",0,x_repeat,&id_repeat},
  658. {"return",0,x_return,&id_return},
  659. {"switch",0,x_switch,&id_switch},
  660. {"subroutine",0,x_subroutine,&id_subroutine},
  661. {"then",0,x_then,&id_then},
  662. {"until",0,x_until,&id_until},
  663. {"while",0,x_while,&id_while},
  664. {"",0,NULL,NULL}
  665. }
  666. #endif
  667. ;
  668.  
  669. /* \Fortran--90. */
  670. IN_RATFOR SPEC spec90_tokens[]
  671. #if(part == 0 || part == 1)
  672. = {
  673. {"contains",0,x_contains,&id_contains},
  674. {"endinterface",0,x_en_interface,&id_endinterface},
  675. {"endmodule",0,x_en_module,&id_endmodule},
  676. {"endselect",0,x_en_select,&id_endselect},
  677. {"endtype",0,x_en_type,&id_endtype},
  678. {"endwhere",0,x_en_where,&id_endwhere},
  679. {"interface",0,x_interface,&id_interface},
  680. {"module",0,x_module,&id_module},
  681. {"type",0,x_type,&id_type},
  682. {"where",0,x_where,&id_where},
  683. {"",0,NULL,NULL}
  684. }
  685. #endif
  686. ;
  687.  
  688.  
  689.  
  690. IN_RATFOR sixteen_bits sym_label RSET(0);
  691.  
  692.  
  693.  
  694. IN_RATFOR boolean saved_token RSET(NO);/* Is there another byte waiting? */
  695. IN_RATFOR eight_bits last_a;/* The byte that was saved. */
  696. IN_RATFOR int last_bytes;
  697. /* Length (either~1 or~2) of the token just read. Used to \
  698.             back up properly. */
  699.  
  700.  
  701.  
  702. IN_RATFOR eight_bits HUGE*cmnt_buf RSET(NULL),
  703. HUGE*cmnt_buf_end RSET(NULL),
  704. HUGE*cmnt_pos RSET(NULL);
  705.  
  706.  
  707. typedef struct
  708. {
  709. CMD cmd;/* The command that initiated this block. */
  710. STMT_LBL Top,Next,Break;/* Statement labels for loops. */
  711. STMT_LBL Case,Default;/* Labels for next |case| or |default|. */
  712. sixteen_bits Icase;/* Identifier token for current comparand. */
  713. unsigned was_Break:1,/* Did a |break| occur? */
  714. was_Next:1;/* Did a |@r next| occur? */
  715. }LBL;
  716.  
  717. IN_RATFOR LBL HUGE*lbl,HUGE*lbl_end;/* Dynamic array. */
  718. IN_RATFOR BUF_SIZE max_lbls;/* Dynamic allocation length. */
  719.  
  720. IN_RATFOR int wlevel RSET(0);
  721. /* Current level of expansion that can be broken out of \
  722.             with a |break| or |next|.  This is incremented for \
  723.             such things as |do|, but not for such things as \
  724.             |if|. */
  725.  
  726.  
  727.  
  728. IN_RATFOR boolean balanced RSET(YES);
  729. IN_RATFOR ASCII cur_delim RSET('\0');
  730.  
  731.  
  732.  
  733. IN_RATFOR eight_bits HUGE*save_buffer RSET(NULL),HUGE*psave_buffer;
  734.  
  735.  
  736.  
  737. IN_RATFOR outer_char HUGE*cmd_fmt;
  738. IN_RATFOR ASCII HUGE*cmd_msg,HUGE*cmd_end;
  739. IN_RATFOR BUF_SIZE cmd_fsize,cmd_size;
  740.  
  741.  
  742.  
  743. IN_COMMON double g_ratio;
  744. IN_COMMON CASE_TYPE max_spread;
  745. IN_COMMON unsigned short marginal_cases;
  746.  
  747. IN_EVAL VAL HUGE*val_ptr,HUGE*val_heap;
  748.  
  749.  
  750.  
  751. /* For pc's, the file is split into two compilable parts using the \
  752. compiler-line macro |part|, which must equal either~1 or~2. */
  753. #if(part != 2)
  754.  
  755.  
  756. SRTN
  757. is_Rat_present(VOID)
  758. {
  759. Rat_is_loaded= YES;
  760. }
  761.  
  762.  
  763.  
  764. boolean
  765. Rat_OK FCN((msg))
  766. outer_char*msg C1("")
  767. {
  768. return YES;
  769. }
  770.  
  771.  
  772.  
  773. SRTN
  774. ini_RAT_tokens FCN((language0))
  775. LANGUAGE language0 C1("")
  776. {
  777. switch(language0)
  778. {
  779. case RATFOR_90:
  780. ini_special_tokens(language0,spec90_tokens);
  781. ini_out_tokens(out90_tokens);
  782.  
  783. /* The previous case falls through to here! */
  784. case RATFOR:
  785. ini_special_tokens(language0,spec_tokens);/* Initialize special tokens. */
  786. ini_out_tokens(out_tokens);/*  Printed during Ratfor expansion. */
  787. break;
  788.  
  789. default:
  790. CONFUSION("ini_RAT_tokens","Language should be RATFOR-like here");
  791. }
  792.  
  793. ini_univ_tokens(language0);
  794.  
  795. {
  796. ASCII HUGE*pd;
  797.  
  798. /* Store the phrase ``|break;|''. */
  799. break_tokens[0]= LEFT(id_break,ID0);
  800. break_tokens[1]= RIGHT(id_break);
  801. break_tokens[2]= 073;
  802.  
  803. pd= x_to_ASCII(OC("data"));
  804. id_data= ID_NUM(pd,pd+4);
  805. }
  806.  
  807.  
  808. }
  809.  
  810.  
  811.  
  812. int
  813. chk_lbl(VOID)
  814. {
  815. sixteen_bits a;
  816.  
  817. if(next_byte()==072)
  818. {
  819. sym_label= (sixteen_bits)cur_val;/* Remember symbolic label. */
  820.  
  821. if(TOKEN1(a= next_byte()))BACK_UP
  822. else
  823. {/* Labelled identifier. */
  824. a= IDENTIFIER(a,next_byte());/* Labelled token. */
  825.  
  826. if(name_dir[a].expandable)
  827. {/* It's a labelled \Ratfor\ token. */
  828. cur_val= a;
  829. return YES;
  830. }
  831. else
  832. {/* Nothing special about this label; spit it out. */
  833. BACK_UP
  834. cur_val= sym_label;
  835. sym_label= ignore;
  836.  
  837. checking_label= YES;
  838. out_char(identifier);
  839. checking_label= NO;
  840.  
  841. return-1;
  842. }
  843. }
  844. }
  845.  
  846. /* The identifier isn't followed by a colon, so it isn't a label. */
  847. sym_label= ignore;
  848. BACK_UP
  849. return NO;
  850. }
  851.  
  852.  
  853.  
  854. SRTN
  855. RAT_error FCN(VA_ALIST((err_type,msg,n VA_ARGS)))
  856. VA_DCL(
  857. ERR_TYPE err_type C0("Is it warning or error?")
  858. CONST outer_char msg[]C0("Error message.")
  859. int n C2("Number of arguments to follow."))
  860. {
  861. VA_LIST(arg_ptr)
  862. outer_char HUGE*temp,HUGE*temp1;
  863. int last_level;
  864. #if(NUM_VA_ARGS == 1)
  865. ERR_TYPE err_type;
  866. CONST outer_char*msg;
  867. int n;
  868. #endif
  869.  
  870. temp= GET_MEM("RAT_error:temp",N_MSGBUF,outer_char);
  871. temp1= GET_MEM("RAT_error:temp1",N_MSGBUF,outer_char);
  872.  
  873. VA_START(arg_ptr,n);
  874.  
  875. #if(NUM_VA_ARGS == 1)
  876. err_type= va_arg(arg_ptr,ERR_TYPE);
  877. msg= va_arg(arg_ptr,char*);
  878. va_arg(arg_ptr,int);
  879. #endif
  880.  
  881. vsprintf((char*)temp1,(CONST char*)msg,arg_ptr);
  882. va_end(arg_ptr);
  883.  
  884.  
  885. if(
  886. nsprintf(temp,OC("RATFOR %s (Output l. %u in %s):  %s."),4,err_type==ERROR?"ERROR":"WARNING",OUTPUT_LINE,params.OUTPUT_FILE_NAME,temp1)>=(int)(N_MSGBUF))OVERFLW("temp","");
  887.  
  888. last_level= MAX(rlevel-1,0);
  889.  
  890.  
  891. if(
  892. nsprintf(temp1,OC("%s  Expanding \"%s\" (loop level %d) beginning at output line %u.  \
  893. In \"%s %s\" beginning at line %u."),7,(char*)temp,(char*)cmd_name(begun[last_level].cmd),begun[last_level].level,begun[last_level].line,(char*)cmd_name(begun[0].cmd),(char*)name_of(begun[0].name),begun[0].line)>=(int)(N_MSGBUF))OVERFLW("temp1","");
  894.  
  895. printf("\n%s\n",(char*)temp1);/* Error msg to the terminal. */
  896. OUT_MSG(to_ASCII(temp1),NULL);/* Error msg to the file. */
  897.  
  898. mark_error;
  899.  
  900. FREE_MEM(temp,"RAT_error:temp",N_MSGBUF,char);
  901. FREE_MEM(temp1,"RAT_error:temp1",N_MSGBUF,char);
  902. }
  903.  
  904.  
  905.  
  906. SRTN
  907. output_ended FCN(VA_ALIST((msg,n VA_ARGS)))
  908. VA_DCL(
  909. CONST outer_char msg[]C0("Error message.")
  910. int n C2("Number of arguments to follow."))
  911. {
  912. VA_LIST(arg_ptr)
  913. char HUGE*temp;
  914.  
  915. temp= GET_MEM("output_ended:temp",N_MSGBUF,char);
  916.  
  917. VA_START(arg_ptr,n);
  918.  
  919. #if(NUM_VA_ARGS==1)
  920. {
  921. char*fmt0= va_arg(arg_ptr,char*);
  922.  
  923. va_arg(arg_ptr,int);
  924. vsprintf((char*)temp,fmt0,arg_ptr);
  925. }
  926. #else
  927. vsprintf(temp,(CONST char*)msg,arg_ptr);
  928. #endif
  929. va_end(arg_ptr);
  930.  
  931.  
  932. RAT_error(ERROR,OC("Output ended %s"),1,temp);
  933. FATAL(R,"ABORTING!","");
  934. }
  935.  
  936.  
  937.  
  938. outer_char HUGE*
  939. cmd_name FCN((cmd))
  940. CMD cmd C1("Type of command.")
  941. {
  942. switch(cmd)
  943. {
  944. case _DO_CMD:
  945. return OC("$DO");
  946.  
  947. case blockdata_CMD:return OC("blockdata");
  948. case break_CMD:return OC("break");
  949. case case_CMD:return OC("case");
  950. case contains_CMD:return OC("contains");
  951. case default_CMD:return OC("default");
  952. case do_CMD:return OC("do");
  953. case for_CMD:return OC("for");
  954. case function_CMD:return OC("function");
  955. case if_CMD:return OC("if");
  956. case interface_CMD:return OC("interface");
  957. case module_CMD:return OC("module");
  958. case next_CMD:return OC("next");
  959. case program_CMD:return OC("program");
  960. case repeat_CMD:return OC("repeat");
  961. case return_CMD:return OC("return");
  962. case subroutine_CMD:return OC("subroutine");
  963. case switch_CMD:return OC("switch");
  964. case type_CMD:return OC("type");
  965. case until_CMD:return OC("until");
  966. case where_CMD:return OC("where");
  967. case while_CMD:return OC("while");
  968. default:return OC("UNKNOWN CMD");
  969. }
  970. }
  971.  
  972.  
  973.  
  974. SRTN
  975. not_switch FCN((s))
  976. CONST outer_char s[]C1("Error message.")
  977. {
  978.  
  979. RAT_error(ERROR,OC("Misplaced keyword: \
  980. \"%s\" must be used only inside \"switch\""),1,s);
  981. }
  982.  
  983.  
  984. SRTN didnt_expand FCN((c0,c,op))
  985. eight_bits c0 C0("")
  986. eight_bits c C0("")
  987. CONST char*op C1("")
  988. {
  989.  
  990. RAT_error(ERROR,OC("Was expecting '%c', not '%c', after \"%s\"; \
  991. expansion aborted"),3,XCHR(c0),XCHR(c),op);
  992. }
  993.  
  994.  
  995. boolean
  996. char_after FCN((c))
  997. outer_char c C1("Character expected next.")
  998. {
  999. if((ASCII)(next_byte())!=XORD(c))
  1000. {
  1001.  
  1002. RAT_error(WARNING,OC("Inserted '%c' after \"%s\""),1,c,cmd_name(begun[rlevel-1].cmd));
  1003. BACK_UP
  1004. return NO;
  1005. }
  1006.  
  1007. return YES;
  1008. }
  1009.  
  1010.  
  1011.  
  1012. eight_bits
  1013. next_byte(VOID)
  1014. {
  1015. eight_bits a0;/* The next byte. */
  1016. sixteen_bits a;/* Next two-byte token. */
  1017. static boolean ended_module= NO;
  1018. long cur_val0;/* Incoming value of |cur_val|. */
  1019.  
  1020. /* Check if there's a byte already waiting. */
  1021. if(saved_token)
  1022. {
  1023. saved_token= NO;
  1024. return last_a;
  1025. }
  1026.  
  1027. cur_val0= cur_val;/* Trouble if we don't restore the state of |cur_val|. */
  1028.  
  1029. WHILE()
  1030. {
  1031. if(DONE_LEVEL)
  1032. {
  1033. if(!ended_module)
  1034. {
  1035. cur_val= -(long)cur_mod;
  1036. if(cur_val!=ignore)OUT_CHAR(module_number);
  1037. ended_module= YES;
  1038. }
  1039.  
  1040. if(!pop_level())
  1041. {
  1042. a0= ignore;
  1043. break;
  1044. }
  1045.  
  1046. ended_module= NO;
  1047. }
  1048.  
  1049. if(TOKEN1(a0= *cur_byte++))
  1050. {
  1051. if(a0==ignore&&!in_string)
  1052. continue;/* Forget about null bytes. */
  1053.  
  1054. if(rlevel>0&&a0==begin_language)
  1055. {/* Skip the |begin_language|--|NUWEB_OFF| pair. */
  1056. cur_byte++;
  1057. continue;
  1058. }
  1059.  
  1060. last_bytes= 1;
  1061. break;
  1062. }
  1063.  
  1064.  
  1065. {
  1066. a= IDENTIFIER(a0,last_a= *cur_byte++);
  1067. last_bytes= 2;
  1068.  
  1069. /* Expand the two-byte token. */
  1070. switch(a/MODULE_NAME)
  1071. {
  1072. case 0:/* An identifier. */
  1073.  
  1074. if(is_deferred(a))continue;/* Execute deferred macro def'n. */
  1075.  
  1076. /* If it's a macro, expand it. */
  1077. if(!mac_protected&&
  1078. (macro_text= (text_pointer)mac_lookup(a))!=NULL)
  1079. {
  1080. eight_bits HUGE*p;
  1081. long cur_val0= cur_val;
  1082.  
  1083. cur_val= a;/* In case it's a built-in function. */
  1084. p= xmacro(macro_text,&cur_byte,cur_end,macrobuf);
  1085. cur_val= cur_val0;
  1086. push_level(NULL,p,mp);
  1087. break;
  1088. }
  1089. else if(!balanced&&language==RATFOR&&
  1090. (a==id_function||a==id_program||a==id_subroutine))
  1091. {
  1092.  
  1093. RAT_error(ERROR,OC("Inserted missing '%c' at beginning of function"),1,XCHR(cur_delim));
  1094. cur_byte-= 2;
  1095. saved_token= NO;
  1096. a0= cur_delim;
  1097. goto return_next_byte;
  1098. }
  1099. else
  1100. {
  1101. saved_token= YES;
  1102. goto return_next_byte;
  1103. }
  1104.  
  1105. case 1:/* Module name. */
  1106. x_mod_a(a);
  1107. break;
  1108.  
  1109. default:
  1110. cur_val= a-MODULE_NUM;
  1111. if(cur_val>UNNAMED_MODULE)cur_mod= (sixteen_bits)cur_val;
  1112. OUT_CHAR(module_number);
  1113. }
  1114. }
  1115.  
  1116.  
  1117. }
  1118.  
  1119. return_next_byte:
  1120. cur_val= cur_val0;
  1121. return a0;
  1122. }
  1123.  
  1124.  
  1125.  
  1126. SRTN
  1127. skip_newlines FCN((save_comments))
  1128. boolean save_comments C1("")
  1129. {
  1130. eight_bits a;
  1131.  
  1132. if(save_comments)
  1133. {/* Allocate a buffer to hold the comments. */
  1134. cmnt_pos= cmnt_buf= GET_MEM("cmnt_buf",SAVE8,eight_bits);
  1135. cmnt_buf_end= cmnt_buf+SAVE8;
  1136. }
  1137.  
  1138. while((a= copy_comment(save_comments))==012);
  1139.  
  1140. if(a==ignore)
  1141. output_ended(OC("while skipping newlines"),0);
  1142.  
  1143. BACK_UP
  1144. }
  1145.  
  1146.  
  1147. eight_bits
  1148. copy_comment FCN((save_comments))
  1149. boolean save_comments C1("")
  1150. {
  1151. eight_bits a;
  1152.  
  1153. WHILE()
  1154. if((a= next_byte())!=stringg)return a;
  1155. /* Beginning of string. */
  1156. else if(save_comments)
  1157. {/* Save in preallocated buffer, for later use with \
  1158. |flush_comments|. */
  1159. *cmnt_pos++= a;
  1160. in_string= YES;
  1161. while((a= next_byte())!=stringg)
  1162. {
  1163. if(cmnt_pos==cmnt_buf_end)
  1164. resize(&cmnt_buf,SAVE8,&cmnt_pos,&cmnt_buf_end);
  1165.  
  1166. *cmnt_pos++= a;
  1167. }
  1168. *cmnt_pos++= a;
  1169. in_string= NO;
  1170. }
  1171. else
  1172. {/* Copy directly to output. */
  1173. OUT_CHAR(stringg);
  1174. while((a= get_output())!=stringg);
  1175. }
  1176.  
  1177. DUMMY_RETURN(ignore);
  1178. }
  1179.  
  1180.  
  1181.  
  1182. SRTN
  1183. flush_comments(VOID)
  1184. {
  1185. eight_bits*p;
  1186.  
  1187. if(!cmnt_buf)return;/* Nothing left in buffer. */
  1188.  
  1189. for(p= cmnt_buf;p<cmnt_pos;p++)out_char(*p);/* Print out saved stuff. */
  1190. if(cmnt_pos>cmnt_buf)NL;/* If there was a comment, issue a newline. */
  1191.  
  1192. FREE_MEM(cmnt_buf,"cmnt_buf",SAVE8,eight_bits);
  1193. cmnt_buf= cmnt_buf_end= cmnt_pos= NULL;
  1194. }
  1195.  
  1196.  
  1197.  
  1198. SRTN
  1199. id0 FCN((cur_val))
  1200. sixteen_bits cur_val C1("Token to print out.")
  1201. {
  1202. if(cur_val==ignore)return;
  1203.  
  1204. if(out_state==NUM_OR_ID)C_putc(' ');/* Space properly between identifiers. */
  1205.  
  1206. out_ptrunc(cur_val);/* Output a possibly truncated identifier; see \
  1207.             \.{ftangle.web}. */
  1208. out_state= NUM_OR_ID;
  1209. }
  1210.  
  1211.  
  1212.  
  1213. int
  1214. save_lbls FCN((cmd,top0,next0,break0,n_used))
  1215. CMD cmd C0("The current command.")
  1216. STMT_LBL top0 C0("Label number for top of block.")
  1217. STMT_LBL next0 C0("Go here on |next|.")
  1218. STMT_LBL break0 C0("Go here on |break|.")
  1219. int n_used C1("Number of labels used in this expansion.")
  1220. {
  1221. /* Advance the level counter; check for overflow. */
  1222. if(++wlevel>=(int)max_lbls)OVERFLW("stmt labels","");
  1223.  
  1224. current_cmd= cmd;/* Save type of block. */
  1225. s_top= top0;/* Top of block. */
  1226. s_next= next0;/* Jump here on |@r next|. */
  1227. s_break= break0;/* Jump here on |@r break|. */
  1228. was_break= was_next= NO;/* Did one occur during loop? */
  1229.  
  1230. max_stmt+= n_used;/* Advance the statement counter to ensure unique \
  1231.                 labels. */
  1232.  
  1233. s_case= s_default= 0;
  1234. icase= ignore;
  1235.  
  1236. return wlevel;
  1237. }
  1238.  
  1239.  
  1240.  
  1241. SRTN
  1242. out_label FCN((suppress_0,stmt_num))
  1243. boolean suppress_0 C0("Suppress if zero?")
  1244. STMT_LBL stmt_num C1("Statement number to print.")
  1245. {
  1246. outer_char temp[N_IDBUF];
  1247. outer_char*p;
  1248.  
  1249. if(stmt_num==(STMT_LBL)0&&suppress_0)return;
  1250.  
  1251. /* In \Fortran, the statement number must be $\le 99999$. */
  1252. if(stmt_num>(STMT_LBL)99999)
  1253. {
  1254. stmt_num= (STMT_LBL)99999;
  1255.  
  1256. RAT_error(WARNING,OC("Automatic statement number out of bounds; %ld assumed"),1,stmt_num);
  1257. }
  1258.  
  1259.  
  1260. if(
  1261. nsprintf(temp,OC("%ld"),1,stmt_num)>=(int)(N_IDBUF))OVERFLW("temp","");
  1262.  
  1263. OUT_CHAR(constant);
  1264. for(p= temp;*p;p++)
  1265. OUT_CHAR(XORD(*p));
  1266. OUT_CHAR(constant);
  1267. }
  1268.  
  1269.  
  1270.  
  1271. SRTN
  1272. copyd FCN((to_memory,xpn_cases,l,r,semi_allowed))
  1273. boolean to_memory C0("To memory?")
  1274. boolean xpn_cases C0("Expand |case| statements?")
  1275. ASCII l C0("Left-hand delimiter.")
  1276. ASCII r C0("Right-hand delimiter.")
  1277. boolean semi_allowed C1("Is a semicolon allowed in the text to be \
  1278. copied?")
  1279. {
  1280. int bal,bal0[BLEVELS];
  1281. LINE_NUMBER starting_line;
  1282. eight_bits(*output_rtn)(VOID);
  1283. sixteen_bits a,last_token;
  1284. sixteen_bits l0= ignore,r0= ignore;
  1285. boolean found_semi;
  1286. boolean balanced0= balanced;/* Save since possible recursion. */
  1287. ASCII cur_delim0= cur_delim;
  1288.  
  1289.  
  1290.  
  1291. switch(l)
  1292. {
  1293. case 0173:
  1294. l0= 050;r0= 051;
  1295. break;
  1296.  
  1297. case 050:
  1298. l0= 0173;r0= 0175;
  1299. break;
  1300.  
  1301. default:
  1302. CONFUSION("copyd","Invalid left delimiter");
  1303. }
  1304.  
  1305.  
  1306.  
  1307. if(l==0173&&xpn_cases)/* We should be positioned after the brace. */
  1308. {
  1309. if(DONE_LEVEL&&!pop_level())
  1310. output_ended(OC("after '{'"),0);
  1311.  
  1312. bal0[bal= 1]= 0;/* Don't copy the opening brace. */
  1313. }
  1314. else
  1315. {
  1316. if((ASCII)(next_byte())!=l)
  1317. {
  1318.  
  1319. RAT_error(ERROR,OC("Missing opening delimiter '%c'; \
  1320. text not copied"),1,XCHR(l));
  1321. return;
  1322. }
  1323.  
  1324. /* Include the opening delimiter in the copy. */
  1325. BACK_UP
  1326. bal0[bal= 0]= 0;
  1327. }
  1328.  
  1329. starting_line= OUTPUT_LINE;
  1330.  
  1331. /* Normally we copy the stuff directly to the output. However, if we're \
  1332.     processing a |switch|, we store it. */
  1333. output_rtn= to_memory?next_byte:get_output;
  1334.  
  1335. /* We use |last_token| to help check for a semicolon just before the closing \
  1336. delimiter. */
  1337. last_token= ignore;
  1338. found_semi= NO;
  1339.  
  1340. /* For use with check in |get_output|. */
  1341. balanced= NO;
  1342. cur_delim= r;
  1343.  
  1344. WHILE()
  1345. {
  1346. a= (sixteen_bits)(*output_rtn)();/* Copy a token to the output, \
  1347. and remember it. */
  1348.  
  1349. if(to_memory&&a==(sixteen_bits)stringg)
  1350. in_string= BOOLEAN(!in_string);
  1351.  
  1352. if(!in_string)
  1353. {
  1354. if(a==ignore)
  1355. output_ended(OC("while scanning for '%c'.  Scan began \
  1356. with delimiter '%c' at line %u"),3,XCHR(r),XCHR(l),starting_line);
  1357.  
  1358. if(a==(sixteen_bits)l)bal0[++bal]= 0;
  1359. else if(a==(sixteen_bits)r)
  1360. {
  1361. if(bal<=0)
  1362. {
  1363. if(!to_memory)out_pos--;/* Kill off what was already output. */
  1364. unmatched(l,r);
  1365. continue;
  1366. }
  1367. else
  1368. {
  1369. if(bal0[bal]!=0)
  1370. {
  1371. inserted(bal0[bal],l0,r0,l,bal);
  1372.  
  1373. while(bal0[bal]--)
  1374. if(to_memory)SAVE_IN_MEM(r0)
  1375. else OUT_CHAR(r0);
  1376. }
  1377.  
  1378. if(--bal==0)
  1379. {
  1380. if(semi_allowed&&last_token&&last_token!=073)
  1381. {
  1382.  
  1383. RAT_error(WARNING,OC("Supplied missing ';' before \
  1384. delimiter '%c'"),1,r);
  1385.  
  1386. if(to_memory)SAVE_IN_MEM(073)
  1387. else OUT_CHAR(073);
  1388. }
  1389.  
  1390. if(to_memory)SAVE_IN_MEM(r)
  1391.  
  1392. /* We've successfully found the end of the scan. */
  1393. balanced= YES;
  1394. cur_delim= '\0';
  1395. break;
  1396. }
  1397. }
  1398. }
  1399.  
  1400.  
  1401. else if(a==l0)bal0[bal]++;
  1402. else if(a==r0)
  1403. {
  1404. if(bal0[bal]<=0)
  1405. {
  1406. if(!to_memory)out_pos--;
  1407. unmatched((ASCII)l0,(ASCII)r0);
  1408. continue;
  1409. }
  1410. else bal0[bal]--;
  1411. }
  1412.  
  1413.  
  1414. else if(a!=stringg)
  1415. {
  1416. if(a==073)
  1417. if(semi_allowed)found_semi= YES;
  1418. else
  1419. RAT_error(ERROR,OC("Spurious semicolon"),0);
  1420.  
  1421. if(chk_stmts)
  1422. if(!to_memory&&a==id_keyword)last_token= ignore;
  1423. else last_token= a;/* Remember last character so we can check \
  1424.                 for semicolon. */
  1425. }
  1426. }
  1427.  
  1428.  
  1429.  
  1430. if(to_memory)
  1431. {
  1432. if(TOKEN1(a))
  1433. {
  1434. SAVE_IN_MEM(a)/* Store it if necessary. */
  1435.  
  1436. switch(a)
  1437. {
  1438. case dot_const:
  1439. case begin_language:
  1440. SAVE_IN_MEM(*cur_byte++);
  1441. break;
  1442.  
  1443. case new_output_file:
  1444.  
  1445. RAT_error(ERROR,OC("@o command not allowed inside switch"),0);
  1446. }
  1447. }
  1448. else
  1449. {
  1450. if(xpn_cases)
  1451.  
  1452. {
  1453. eight_bits a0,a1;
  1454.  
  1455.  
  1456. a= IDENTIFIER(a0= (eight_bits)a,a1= next_byte());
  1457.  
  1458. if(a==id_switch)
  1459. {
  1460. SAVE_16;/* |switch|. */
  1461. copyd(TO_MEMORY,DONT_XPN_CASES,050,051,NO);/* $(\dots)$ */
  1462. skip_newlines(COPY_COMMENTS);
  1463. copyd(TO_MEMORY,DONT_XPN_CASES,0173,0175,YES);/* |{body;}| */
  1464. }
  1465. else if(a==id_case)x_case();
  1466. else if(a==id_default)x_default();
  1467. else SAVE_16;
  1468. }
  1469.  
  1470.  
  1471. else
  1472. {/* For inner |switches|, just copy tokens. */
  1473. SAVE_IN_MEM(a)
  1474. SAVE_IN_MEM(next_byte())
  1475. }
  1476. }
  1477. }
  1478.  
  1479.  
  1480. }
  1481.  
  1482. balanced= balanced0;
  1483. cur_delim= cur_delim0;
  1484. }
  1485.  
  1486.  
  1487.  
  1488. SRTN
  1489. cp_fcn_body(VOID)
  1490. {
  1491. brace_level++;
  1492. copyd(TO_OUTPUT,XPN_CASES,0173,0175,YES);
  1493.  
  1494. if(--brace_level==0)
  1495. {
  1496. END;/* Automatically insert an |@r end| statement. */
  1497. cur_fcn= NO_FCN;/* No longer inside a function. */
  1498. rlevel--;
  1499. }
  1500. }
  1501.  
  1502.  
  1503.  
  1504. SRTN
  1505. stmt FCN((to_memory,brace_only))
  1506. boolean to_memory C0("")
  1507. boolean brace_only C1("Is only a left brace allowed next?")
  1508. {
  1509. sixteen_bits a;
  1510.  
  1511. EAT_AUTO_SEMI;
  1512. skip_newlines(COPY_COMMENTS);
  1513.  
  1514. if((a= next_byte())!=0173)
  1515. {
  1516. if(a==ignore)
  1517. output_ended(OC("at beginning of statement"),0);
  1518.  
  1519. /* Issue error message if was expecting brace. */
  1520. if(brace_only)
  1521. {
  1522.  
  1523. RAT_error(WARNING,OC("Inserted '{'"),0);
  1524. BACK_UP
  1525. copyd(to_memory,XPN_CASES,0173,0175,YES);
  1526. return;
  1527. }
  1528.  
  1529. if(TOKEN1(a))
  1530. {/* Definitely not a compound statement. */
  1531. BACK_UP
  1532. x_stmt();
  1533. }
  1534. else
  1535. {/* Check if it's a Ratfor token that needs to be \
  1536. expanded. */
  1537. SPEC HUGE*s;
  1538.  
  1539. a= IDENTIFIER(a,next_byte());
  1540.  
  1541. for(s= spec_tokens;s->len!=0;s++)
  1542. if(a==*s->pid&&s->expand!=NULL)
  1543. {
  1544. (*s->expand)();
  1545. return;/* Successfully expanded special token. */
  1546. }
  1547. BACK_UP
  1548. x_stmt();
  1549. }
  1550. }
  1551. else copyd(to_memory,XPN_CASES,0173,0175,YES);/* Scan compound \
  1552.             statement. */
  1553. }
  1554.  
  1555.  
  1556.  
  1557.  
  1558. SRTN
  1559. x_stmt(VOID)
  1560. {
  1561. eight_bits a;
  1562.  
  1563. WHILE()
  1564. {
  1565. if((a= get_output())==ignore)
  1566. output_ended(OC("during scan of simple \
  1567. statement "),0);
  1568.  
  1569. if(a==073&&!in_string)break;
  1570. }
  1571.  
  1572. /* Does a verbatim comment follow? If so, it's bracketed by |stringg|. */
  1573. if((a= next_byte())!=stringg){BACK_UP return;}
  1574.  
  1575. if(*cur_byte!=012){BACK_UP return;}
  1576.  
  1577. /* Copy verbatim comment. */
  1578. OUT_CHAR(a);
  1579. while((a= get_output())!=stringg);
  1580. }
  1581.  
  1582.  
  1583.  
  1584.  
  1585. eight_bits HUGE*
  1586. save_out FCN((pp,nmax,r_before,r_after))
  1587. eight_bits HUGE**pp C0("Address of pointer to buffer where result is \
  1588. saved.")
  1589. int nmax C0("Length of above buffer.")
  1590. eight_bits r_before C0("Stop before here.")
  1591. eight_bits r_after C1("Stop after here.")
  1592. {
  1593. eight_bits a,l;
  1594. eight_bits HUGE*p,HUGE*p_end;
  1595. LINE_NUMBER starting_line;
  1596. int bal,bal0[BLEVELS];
  1597.  
  1598. /* If a save buffer hasn't already been allocated, do that. */
  1599. if(!(*pp))
  1600. *pp= GET_MEM("*pp",nmax,eight_bits);/* Send back the buffer \
  1601. address, so we can free later. */
  1602. p= *pp;
  1603. p_end= p+nmax-1;/* End of buffer. When we get this far, we must \
  1604.                 reallocate. The $-1$~is because we might \
  1605.                 increment~|p| by~2. */
  1606.  
  1607. switch(r_after)
  1608. {
  1609. case 051:
  1610. l= (eight_bits)050;
  1611. bal= 1;
  1612. break;
  1613.  
  1614. case 0175:
  1615. l= (eight_bits)0173;
  1616. bal= 1;
  1617. break;
  1618.  
  1619. default:
  1620. l= '\0';
  1621. bal= 0;
  1622. break;
  1623. }
  1624.  
  1625. bal0[bal]= 0;
  1626.  
  1627. starting_line= OUTPUT_LINE;/* Remember where the scan started, in case \
  1628.                     there is an error. */
  1629.  
  1630. if(in_string)
  1631. CONFUSION("save_out","Shouldn't be inside string here");
  1632.  
  1633. WHILE()
  1634. {
  1635. if(p>=p_end)resize(pp,nmax,&p,&p_end);/* Reallocate the save \
  1636. buffer. */
  1637.  
  1638. if(TOKEN1(a= next_byte()))
  1639. {
  1640. if(!in_string)
  1641.  
  1642. {
  1643. if(a==ignore)
  1644. output_ended(OC("while scanning from line %u \
  1645. for delimiter (r_before = '%c', r_after = '%c')"),3,starting_line,XCHR(r_before),XCHR(r_after));
  1646.  
  1647. if(a==l)bal0[++bal]= 0;
  1648. else if(a==r_after&&r_after!=NOT_AFTER)
  1649. {
  1650. if(l&&bal<=0)
  1651. {
  1652. p--;
  1653. unmatched(l,r_after);
  1654. continue;
  1655. }
  1656. else
  1657. {
  1658. if(bal0[bal]!=0)
  1659. {
  1660. inserted(bal0[bal],0173,0175,l,bal);
  1661.  
  1662. while(bal0[bal]--)
  1663. {
  1664. *p++= 0175;
  1665. if(p>=p_end)resize(pp,nmax,&p,&p_end);
  1666. }
  1667. }
  1668.  
  1669. if(l)bal--;
  1670. if(bal==0)
  1671. {/* Found right-hand delimiter. */
  1672. *p= '\0';/* Mark end of tokens. */
  1673. return p;
  1674. }
  1675. }
  1676. }
  1677.  
  1678.  
  1679. else if(a==r_before&&r_before!=NOT_BEFORE)
  1680. {
  1681. BACK_UP;
  1682. *p= '\0';
  1683. return p;
  1684. }
  1685. else if(a==0173)bal0[bal]++;
  1686. else if(a==0175)
  1687. {
  1688. if(bal0[bal]<=0)
  1689. {
  1690. p--;
  1691. unmatched(0173,0175);
  1692. continue;
  1693. }
  1694. else bal0[bal]--;
  1695. }
  1696.  
  1697.  
  1698. }
  1699.  
  1700.  
  1701.  
  1702.  
  1703. {
  1704. *p++= a;
  1705.  
  1706. switch(a)
  1707. {
  1708. case stringg:
  1709. in_string= BOOLEAN(!in_string);
  1710. break;
  1711.  
  1712. case dot_const:
  1713. case begin_language:
  1714. *p++= *cur_byte++;
  1715. break;
  1716. }
  1717. }
  1718.  
  1719.  
  1720. }
  1721. else
  1722. {
  1723. *p++= a;
  1724. *p++= next_byte();
  1725. }
  1726. }
  1727.  
  1728. DUMMY_RETURN(NULL);
  1729. }
  1730.  
  1731.  
  1732.  
  1733.  
  1734. outer_char*
  1735. qdelim FCN((delim))
  1736. ASCII delim C1("")
  1737. {
  1738. static outer_char q0[4];
  1739.  
  1740. sprintf((char*)q0,delim?"'%c'":"?",XCHR(delim));
  1741. return q0;
  1742. }
  1743.  
  1744.  
  1745.  
  1746. SRTN
  1747. resize FCN((pp,nmax,pq,pp_end))
  1748. eight_bits HUGE**pp C0("Addr of ptr to beginning of buffer")
  1749. int nmax C0("Resizing increment")
  1750. eight_bits HUGE**pq C0("Address of current pointer")
  1751. eight_bits HUGE**pp_end C1("Addr of ptr to end of buffer")
  1752. {
  1753. int old_len= PTR_DIFF(int,*pq,*pp);/* Old length.  Should this be |size_t|? */
  1754. int new_len= old_len+nmax;/* New length. */
  1755.  
  1756. *pp= (eight_bits HUGE*)REALLOC(*pp,
  1757. new_len*sizeof(eight_bits),
  1758. old_len*sizeof(eight_bits));
  1759. *pq= *pp+old_len;/* New next position to which to accrete. */
  1760. *pp_end= *pp+new_len-1;/* New end. */
  1761. }
  1762.  
  1763.  
  1764. #endif /* Part 1 */
  1765.  
  1766. #if(part != 1)
  1767.  
  1768.  
  1769. SRTN
  1770. alloc_Rat(VOID)
  1771. {
  1772.  
  1773.  
  1774. ALLOC(LBL,lbl,"lb",max_lbls,0);
  1775. lbl_end= lbl+max_lbls;
  1776.  
  1777.  
  1778.  
  1779. ALLOC(outer_char,cmd_fmt,"cf",cmd_fsize,0);
  1780. ALLOC(ASCII,cmd_msg,"cg",cmd_size,0);
  1781. cmd_end= cmd_msg+cmd_size;
  1782.  
  1783.  
  1784.  
  1785. begun= GET_MEM("begun",max_lbls,BEGUN);
  1786.  
  1787.  
  1788. }
  1789.  
  1790.  
  1791.  
  1792. SRTN
  1793. out_cmd FCN(VA_ALIST((emit_continue,abbrev,beginning,fmt0,n VA_ARGS)))
  1794. VA_DCL(
  1795. boolean emit_continue C0("Put a |continue| in case of label.")
  1796. outer_char abbrev C0("Abbreviation of command.")
  1797. CONST outer_char beginning[]C0("Beginning part of message.")
  1798. CONST outer_char*fmt0 C0("Format of the message.")
  1799. int n C2("Number of arguments to message."))
  1800. {
  1801. VA_LIST(arg_ptr)
  1802. #if(NUM_VA_ARGS == 1)
  1803. boolean emit_continue;
  1804. char abbrev;
  1805. CONST outer_char*beginning;
  1806. CONST outer_char*fmt0;
  1807. int n;
  1808. #endif
  1809.  
  1810. VA_START(arg_ptr,n);
  1811.  
  1812. #if(NUM_VA_ARGS == 1)
  1813. emit_continue= va_arg(arg_ptr,boolean);
  1814. abbrev= va_arg(arg_ptr,char);
  1815. beginning= va_arg(arg_ptr,char*);
  1816. fmt0= va_arg(arg_ptr,char*);
  1817. va_arg(arg_ptr,int);
  1818. #endif
  1819.  
  1820.  
  1821. {
  1822. static outer_char brkset[3]= "*?";/* Prototype list of possible characters to \
  1823.             be searched for in the command-line list. */
  1824. char*strpbrk();
  1825. boolean found_abbrev;
  1826.  
  1827.  
  1828. brkset[1]= abbrev;
  1829. found_abbrev= BOOLEAN(STRPBRK(abbrev_cmds,brkset)!=NULL);
  1830.  
  1831. if(suppress_cmds){if(found_abbrev)return;}
  1832. else{if(!found_abbrev)return;}
  1833. }
  1834.  
  1835.  
  1836.  
  1837. if(emit_continue)
  1838. {
  1839. CONTINUE(ignore);/* In case there's a statement label. */
  1840. }
  1841.  
  1842. /* Make prettier format. */
  1843.  
  1844. if(
  1845. nsprintf(cmd_fmt,OC("--- %s \"%s%s\" ---"),3,beginning,cmd_name(begun[rlevel-1].cmd),fmt0)>=(int)(cmd_fsize))OVERFLW("cmd_fmt","");
  1846.  
  1847.  
  1848. {
  1849. outer_char HUGE*p;
  1850. ASCII HUGE*q;
  1851. eight_bits HUGE*s,HUGE*s1;
  1852.  
  1853.  
  1854. p= cmd_fmt;
  1855. q= cmd_msg;
  1856.  
  1857. while(*p)
  1858. {
  1859. if(q>=cmd_end)
  1860. OVERFLW("cmd_msg","cg");
  1861.  
  1862. if(*p=='%'&&*(p+1)=='s')
  1863. {
  1864. p+= 2;
  1865.  
  1866. /* For compilers that don't implement variable arguments, the following \
  1867. calls return a string beginning with \.{"KLUDGE"}. (See \
  1868. \.{proto.hweb}.) This doesn't work right on the MAC, since it seems to \
  1869. put copies of identical strings into different locations. Thus, the \
  1870. \Ratfor\ comments look strange. To kill off those comments, use the \.{-k} \
  1871. option. */
  1872. s= va_arg(arg_ptr,eight_bits*);
  1873. s1= va_arg(arg_ptr,eight_bits*);
  1874.  
  1875. while(s<s1)
  1876. *q++= *s++;
  1877. }
  1878. else
  1879. *q++= XORD(*p++);
  1880. }
  1881.  
  1882. va_end(arg_ptr);
  1883.  
  1884. /* Translate it to the output. */
  1885. OUT_MSG(cmd_msg,q);
  1886. }
  1887.  
  1888. ;
  1889.  
  1890. if(Fortran88&&symbolic_label)
  1891. {
  1892. id0(symbolic_label);OUT_CHAR(072);
  1893. }
  1894. }
  1895.  
  1896.  
  1897.  
  1898. SRTN
  1899. expanding FCN((cmd))
  1900. CMD cmd C1("Type of identifier being expanded.")
  1901. {
  1902. if(rlevel>=(int)max_lbls)OVERFLW("Nesting","");
  1903.  
  1904. begun[rlevel].cmd= cmd;
  1905. begun[rlevel].name= rlevel?cur_fcn:NO_FCN;
  1906. begun[rlevel].symbolic= sym_label;/* For |do| or |switch|. */
  1907. begun[rlevel].function= BOOLEAN(CHOICE(rlevel,is_function,NO));
  1908. begun[rlevel].line= OUTPUT_LINE;
  1909. begun[rlevel].level= wlevel;
  1910. rlevel++;
  1911. }
  1912.  
  1913.  
  1914.  
  1915. X_FCN
  1916. x_while(VOID)
  1917. {
  1918. eight_bits HUGE*a= NULL,HUGE*pa;
  1919.  
  1920. expanding(while_CMD);
  1921. save_lbls(while_CMD,max_stmt,max_stmt,max_stmt+1,2);
  1922.  
  1923. /* Is parenthesized condition present? */
  1924.  
  1925. {
  1926. eight_bits c;
  1927.  
  1928. if((c= next_byte())!='(')
  1929. {
  1930. didnt_expand('(',c,"while");
  1931. return;
  1932. }
  1933. };
  1934. pa= SAVE_AFTER(&a,SAVE8,051);/* Save the condition. */
  1935.  
  1936.  
  1937. out_cmd(YES,'w',OC(""),OC("(%s)"),2,a,pa);/* Comment to output. */
  1938.  
  1939. if(Fortran88)
  1940. {
  1941. id0(id__DO);id0(id__WHILE);LP;copy_out(a,pa,!macro);RP;
  1942. NL;/* |@n DO WHILE|$(\dots)$ */
  1943. }
  1944. else
  1945. {
  1946. IF(s_top);LP;copy_out(a,pa,!macro);RP;THEN;
  1947. }
  1948. INDENT;
  1949. stmt(TO_OUTPUT,0);/* Body. */
  1950. if(!Fortran88){GOTO(s_top);}
  1951. OUTDENT;
  1952.  
  1953. if(Fortran88){END_DO;}
  1954. else
  1955. {
  1956. ENDIF;
  1957. if(was_break){CONTINUE(s_break);}
  1958. }
  1959.  
  1960. wlevel--;
  1961. rlevel--;
  1962. FREE_MEM(a,"while:a",SAVE8,eight_bits);
  1963. }
  1964.  
  1965.  
  1966.  
  1967. X_FCN
  1968. x_break(VOID)
  1969. {
  1970. sixteen_bits a;
  1971.  
  1972. /* Check that we're in a loop or |switch|. */
  1973. if(wlevel==0&&switch_level==0)
  1974. {
  1975. NOT_LOOP("break"," or \"switch\"");
  1976. COPY_TO(073);
  1977. return;
  1978. }
  1979.  
  1980. expanding(break_CMD);
  1981.  
  1982. was_break= YES;/* Remember that at least one \
  1983.             |break| statement happened during this loop. */
  1984.  
  1985.  
  1986. out_cmd(YES,'b',OC(""),OC(""),0);/* Comment to output. */
  1987.  
  1988. if(Fortran88&&do_or_while)
  1989. {
  1990. id0(id__EXIT);
  1991.  
  1992. if(TOKEN1(a= next_byte()))BACK_UP
  1993. else id0(IDENTIFIER(a,next_byte()));
  1994.  
  1995. NL;/* The |do_or_while| is used since |EXIT| can only \
  1996. be used inside of |do|'s or |while|'s. */
  1997. }
  1998. else{GOTO(s_break);}
  1999.  
  2000. char_after(';');/* |break| must be immediately followed by semicolon. */
  2001. rlevel--;
  2002. }
  2003.  
  2004.  
  2005.  
  2006. SRTN
  2007. not_loop FCN((id,msg))
  2008. CONST outer_char id[]C0("Errant identifier name.")
  2009. CONST outer_char msg[]C1("Error message.")
  2010. {
  2011.  
  2012. RAT_error(WARNING,OC("Misplaced keyword: \
  2013. \"%s\" must appear inside loop%s; command ignored"),2,id,msg);
  2014. }
  2015.  
  2016.  
  2017.  
  2018. X_FCN
  2019. x_next(VOID)
  2020. {
  2021. sixteen_bits a;
  2022.  
  2023. /* Check that |next| occurs inside loop. */
  2024. if(wlevel==0)
  2025. {
  2026. NOT_LOOP("next","");
  2027. COPY_TO(073);
  2028. return;
  2029. }
  2030.  
  2031. expanding(next_CMD);
  2032.  
  2033. was_next= YES;/* At least one |next| occurred during this loop. */
  2034.  
  2035. out_cmd(YES,'n',OC(""),OC(""),0);
  2036.  
  2037. if(Fortran88&&do_or_while)
  2038. {
  2039. id0(id__CYCLE);
  2040.  
  2041. if(TOKEN1(a= next_byte()))BACK_UP
  2042. else id0(IDENTIFIER(a,next_byte()));
  2043.  
  2044. NL;
  2045. }
  2046. else{GOTO(s_next);}
  2047.  
  2048. char_after(';');
  2049. rlevel--;
  2050. }
  2051.  
  2052.  
  2053.  
  2054. X_FCN
  2055. x_repeat(VOID)
  2056. {
  2057. sixteen_bits a;
  2058. eight_bits HUGE*u= NULL,HUGE*pu;
  2059.  
  2060. expanding(repeat_CMD);
  2061. save_lbls(repeat_CMD,max_stmt,max_stmt+1,max_stmt+2,3);
  2062.  
  2063.  
  2064. out_cmd(YES,'p',OC(""),OC(""),0);/* Comment to output. */
  2065.  
  2066. CONTINUE(s_top);
  2067. INDENT;
  2068. stmt(TO_OUTPUT,0);
  2069. OUTDENT;
  2070. if(was_next)LABEL(s_next);
  2071.  
  2072. skip_newlines(SAVE_COMMENTS);
  2073.  
  2074. /* Check for optional |@r until|. */
  2075. if(TOKEN1(a= next_byte()))BACK_UP
  2076. else
  2077. {
  2078. a= IDENTIFIER(a,next_byte());
  2079.  
  2080. if(a==id_until)
  2081. {
  2082. flush_comments();
  2083. rlevel--;
  2084. expanding(until_CMD);
  2085.  
  2086.  
  2087. {
  2088. eight_bits c;
  2089.  
  2090. if((c= next_byte())!='(')
  2091. {
  2092. didnt_expand('(',c,"until");
  2093. return;
  2094. }
  2095. };
  2096. pu= SAVE_AFTER(&u,SAVE8,051);/* The |until| condition. */
  2097.  
  2098. out_cmd(NO,'p',OC(""),OC("(%s)"),2,u,pu);
  2099.  
  2100. IF(ignore);LP;NOT;
  2101. LP;copy_out(u,pu,!macro);RP;
  2102. RP;
  2103. FREE_MEM(u,"repeat:u",SAVE8,eight_bits);
  2104. }
  2105. else BACK_UP
  2106. }
  2107.  
  2108. GOTO(s_top);
  2109. flush_comments();
  2110.  
  2111. if(was_break){CONTINUE(s_break);}
  2112.  
  2113. wlevel--;
  2114. rlevel--;
  2115. }
  2116.  
  2117.  
  2118. X_FCN
  2119. x_do(VOID)
  2120. {
  2121. eight_bits b;
  2122. sixteen_bits a;
  2123.  
  2124. /* Is the next a statement number? */
  2125. b= next_byte();BACK_UP
  2126.  
  2127. /* Don't expand the ordinary Fortran numbered |do|. */
  2128. if(b==constant)
  2129. {
  2130. id0(id_do);/* Numbered |do|. */
  2131. return;
  2132. }
  2133.  
  2134. /* Expand the Ratfor |do|. */
  2135. expanding(do_CMD);
  2136. save_lbls(do_CMD,0L,max_stmt,max_stmt+1,2);
  2137.  
  2138.  
  2139. out_cmd(YES,'d',OC(""),OC(""),0);/* Comment to output. */
  2140.  
  2141. /* The following |if| accounts for the possibility of a semicolon or left \
  2142. brace immediately following the |do|. */
  2143. if(!TOKEN1(a= next_byte()))
  2144. a= IDENTIFIER(a,next_byte());
  2145.  
  2146. BACK_UP
  2147.  
  2148. if(!(a==id_while))
  2149. {
  2150. id0(id__DO);if(!Fortran88)LABEL(s_next);COPY_2TO(0173,073);NL;
  2151. INDENT;
  2152. stmt(TO_OUTPUT,0);
  2153. OUTDENT;
  2154. if(Fortran88)
  2155. {
  2156. id0(id__END);id0(id__DO);
  2157. if(symbolic_label)id0(symbolic_label);
  2158. NL;
  2159. }
  2160. else
  2161. {
  2162. CONTINUE(s_next);
  2163. if(was_break){CONTINUE(s_break);}
  2164. }
  2165. }
  2166.  
  2167. wlevel--;
  2168. rlevel--;
  2169. }
  2170.  
  2171.  
  2172.  
  2173. X_FCN
  2174. x_for(VOID)
  2175. {
  2176. eight_bits HUGE*a= NULL,HUGE*b= NULL,HUGE*c= NULL,
  2177. HUGE*pa,HUGE*pb,HUGE*pc;
  2178.  
  2179. expanding(for_CMD);
  2180. save_lbls(for_CMD,max_stmt,max_stmt+1,max_stmt+2,3);
  2181.  
  2182. /* Check for parenthesized list. */
  2183.  
  2184. {
  2185. eight_bits c;
  2186.  
  2187. if((c= next_byte())!='(')
  2188. {
  2189. didnt_expand('(',c,"for");
  2190. return;
  2191. }
  2192. };
  2193. pa= SAVE_AFTER(&a,SAVE8,073);/* Initialization. */
  2194. pb= SAVE_AFTER(&b,SAVE8,073);/* Test. */
  2195. pc= SAVE_AFTER(&c,SAVE8,051);/* Reinitialization. */
  2196.  
  2197.  
  2198. out_cmd(YES,'f',OC(""),OC("(%s;%s;%s)"),6,a,pa,b,pb,c,pc);/* Comment to output. */
  2199.  
  2200. /* Initialization. */
  2201. if(pa>a){copy_out(a,pa,!macro);NL;}
  2202.  
  2203. /* Conditional. */
  2204. if(pb>b)
  2205. {IF(s_top);LP;copy_out(b,pb,!macro);RP;THEN;}
  2206. else{CONTINUE(s_top);}
  2207.  
  2208. /* Body. */
  2209. INDENT;
  2210. stmt(TO_OUTPUT,0);
  2211.  
  2212. /* Reinitialization. */
  2213. if(was_next){CONTINUE(s_next);}
  2214. if(pc>c)
  2215. {
  2216.  
  2217. out_cmd(NO,'f',OC("Reinitialization of"),OC("(%s;%s;%s)"),6,a,pa,b,pb,c,pc);
  2218. copy_out(c,pc,!macro);NL;
  2219. }
  2220. GOTO(s_top);
  2221. OUTDENT;
  2222. if(pb>b){ENDIF;}
  2223. if(was_break){CONTINUE(s_break);}
  2224. wlevel--;
  2225. rlevel--;
  2226. FREE_MEM(a,"for:a",SAVE8,eight_bits);
  2227. FREE_MEM(b,"for:b",SAVE8,eight_bits);
  2228. FREE_MEM(c,"for:c",SAVE8,eight_bits);
  2229. }
  2230.  
  2231.  
  2232.  
  2233. X_FCN
  2234. x_if(VOID)
  2235. {
  2236. expanding(if_CMD);
  2237.  
  2238. out_cmd(YES,'i',OC(""),OC(""),0);
  2239.  
  2240. xpn_body(id__IF,YES,id__THEN);
  2241.  
  2242. /* Hunt for |else| or |elseif|. */
  2243. WHILE()
  2244. if(!
  2245. xpn_else(id_if,id_elseif,id__IF,YES,id__THEN))break;
  2246.  
  2247. ENDIF;
  2248. flush_comments();
  2249. rlevel--;
  2250. }
  2251.  
  2252.  
  2253.  
  2254.  
  2255. SRTN
  2256. xpn_body FCN((token1,scan_parens,token2))
  2257. sixteen_bits token1 C0("")
  2258. boolean scan_parens C0("")
  2259. sixteen_bits token2 C1("")
  2260. {
  2261. LABEL(ignore);id0(token1);
  2262.  
  2263. if(scan_parens)PARENS;
  2264. if(token2)id0(token2);
  2265. NL;
  2266.  
  2267. INDENT;
  2268. stmt(TO_OUTPUT,0);
  2269. OUTDENT;
  2270. }
  2271.  
  2272.  
  2273.  
  2274. boolean
  2275. xpn_else FCN((id_x,id_else_x,token1,scan_parens,token2))
  2276. sixteen_bits id_x C0("")
  2277. sixteen_bits id_else_x C0("")
  2278. sixteen_bits token1 C0("")
  2279. boolean scan_parens C0("")
  2280. sixteen_bits token2 C1("")
  2281. {
  2282. sixteen_bits a;
  2283.  
  2284. skip_newlines(SAVE_COMMENTS);
  2285.  
  2286. if(TOKEN1(a= next_byte()))
  2287. {/* Not a keyword. */
  2288. BACK_UP
  2289. return NO;
  2290. }
  2291. else
  2292. {
  2293. a= IDENTIFIER(a,next_byte());
  2294.  
  2295. if(a==id_else_x)
  2296. {/* |@r elseif| */
  2297. flush_comments();
  2298. ELSE;
  2299. xpn_body(token1,scan_parens,token2);
  2300. return YES;
  2301. }
  2302.  
  2303. if(a!=id_else)
  2304. {/* Neither |else if| nor |else|. */
  2305. BACK_UP
  2306. return NO;
  2307. }
  2308. else
  2309. {/* |@r else| */
  2310. flush_comments();
  2311. ELSE;
  2312.  
  2313. if(TOKEN1(a= next_byte()))BACK_UP
  2314. else
  2315. {/* Possible |@r if| or |@r where|. */
  2316. a= IDENTIFIER(a,next_byte());
  2317.  
  2318. if(a==id_x)/* |else if|  or |else where */
  2319. {
  2320. xpn_body(token1,scan_parens,token2);
  2321. return YES;
  2322. }
  2323. else BACK_UP
  2324. }
  2325.  
  2326. if(out_pos>rst_pos)NL;/* Terminate the |else|. */
  2327.  
  2328. INDENT;
  2329. stmt(TO_OUTPUT,0);/* Expand body of |else|. */
  2330. OUTDENT;
  2331. return NO;
  2332. }
  2333. }
  2334. }
  2335.  
  2336.  
  2337.  
  2338. X_FCN
  2339. x_else(VOID)
  2340. {
  2341. UNEXPECTED("else");
  2342. }
  2343.  
  2344. X_FCN
  2345. x_els_if(VOID)
  2346. {
  2347. UNEXPECTED("elseif");
  2348. }
  2349.  
  2350.  
  2351.  
  2352. X_FCN
  2353. x_end(VOID)
  2354. {
  2355. UNEXPECTED("end");
  2356. }
  2357.  
  2358. X_FCN
  2359. x_en_if(VOID)
  2360. {
  2361. UNEXPECTED("endif");
  2362. }
  2363.  
  2364. X_FCN
  2365. x_en_interface(VOID)
  2366. {
  2367. UNEXPECTED("endinterface");
  2368. }
  2369.  
  2370. X_FCN
  2371. x_en_module(VOID)
  2372. {
  2373. UNEXPECTED("endmodule");
  2374. }
  2375.  
  2376. X_FCN
  2377. x_en_select(VOID)
  2378. {
  2379. UNEXPECTED("endselect");
  2380. }
  2381.  
  2382. X_FCN
  2383. x_en_type(VOID)
  2384. {
  2385. UNEXPECTED("endtype");
  2386. }
  2387.  
  2388. X_FCN
  2389. x_en_where(VOID)
  2390. {
  2391. UNEXPECTED("endwhere");
  2392. }
  2393.  
  2394. X_FCN
  2395. x_procedure(VOID)
  2396. {
  2397. UNEXPECTED("procedure");
  2398. }
  2399.  
  2400. X_FCN
  2401. x_then(VOID)
  2402. {
  2403. UNEXPECTED("then");
  2404. }
  2405.  
  2406. X_FCN
  2407. x_until(VOID)
  2408. {
  2409. UNEXPECTED("until");
  2410. }
  2411.  
  2412.  
  2413.  
  2414. X_FCN
  2415. x_where(VOID)
  2416. {
  2417. expanding(where_CMD);
  2418.  
  2419. out_cmd(YES,'h',OC(""),OC(""),0);
  2420.  
  2421. xpn_body(id__WHERE,YES,id__ignore);
  2422.  
  2423. xpn_else(id_where,id_elsewhere,id__WHERE,NO,id__ignore);
  2424.  
  2425. ENDWHERE;
  2426. rlevel--;
  2427. }
  2428.  
  2429.  
  2430.  
  2431. SRTN
  2432. unexpected FCN((id))
  2433. CONST outer_char id[]C1("Error message.")
  2434. {
  2435.  
  2436. RAT_error(WARNING,OC("Unexpected keyword \"%s\" ignored"),1,id);
  2437. }
  2438.  
  2439.  
  2440.  
  2441. X_FCN
  2442. x_switch(VOID)
  2443. {
  2444. eight_bits HUGE*a= NULL,HUGE*pa;
  2445. outer_char temp[N_IDBUF];
  2446. unsigned short k;
  2447. boolean computed_goto= NO;
  2448. CASE_TYPE cmin= 0,cmax;/* Minimum and maximum |case| values. */
  2449. CASE_TYPE mcases= 0;/* Spread in the case value. */
  2450. unsigned short num_cases;/* Number of cases. */
  2451.  
  2452. expanding(switch_CMD);
  2453.  
  2454. if(switches==NULL)switches= GET_MEM("switches",NSWITCHES,SWITCH);
  2455.  
  2456. ++switch_level;
  2457. if(cur_switch.cases==NULL)
  2458. cur_switch.cases= GET_MEM("cur_switch.cases",NCASES,CASE);
  2459. cur_switch.ncases= 0;
  2460. cur_switch.has_default= NO;
  2461.  
  2462. /* Allocate the zeroth case.  This won't be used, except if there's text \
  2463. before the first |case|. */
  2464. cur_case= &cur_switch.cases[0];
  2465. cur_case->txt.next= cur_case->txt.start= 
  2466. GET_MEM("cur_case->txt.start",BIG_SAVE8,eight_bits);
  2467. cur_case->txt.end= cur_case->txt.start+BIG_SAVE8;
  2468.  
  2469. save_lbls(switch_CMD,0L,s_next,max_stmt,1);
  2470.  
  2471. /* Look for the parenthesized expression. */
  2472.  
  2473. {
  2474. eight_bits c;
  2475.  
  2476. if((c= next_byte())!='(')
  2477. {
  2478. didnt_expand('(',c,"switch");
  2479. return;
  2480. }
  2481. };
  2482. pa= SAVE_AFTER(&a,SAVE8,051);/* Save the expression. */
  2483.  
  2484.  
  2485. out_cmd(YES,'s',OC(""),OC("(%s)"),2,a,pa);/* Comment to output. */
  2486.  
  2487. if(Fortran88)
  2488. {
  2489. id0(id__SELECT);id0(id__CASE);LP;copy_out(a,pa,!macro);RP;NL;
  2490. }
  2491. INDENT;
  2492. stmt(TO_MEMORY,BRACE_ONLY);/* Read the |switch| into memory. */
  2493.  
  2494. if(Fortran88)
  2495. {
  2496. computed_goto= NO;
  2497. }
  2498. else
  2499. {
  2500. unsigned short k;
  2501. VAL val;
  2502.  
  2503.  
  2504. /* We need to find the minimum and maximum |case| value. */
  2505. cmin= LONG_MAX;/* See |limits.h|. */
  2506. cmax= LONG_MIN+1;/* The |+1| takes care of an \.{scc} bug. */
  2507.  
  2508. for(k= 1;k<=cur_switch.ncases;k++)
  2509. {
  2510. cur_case= &cur_switch.cases[k];
  2511.  
  2512. if(cur_case->is_default)continue;
  2513.  
  2514. /* Call up the expression evaluator to reduce the |case| text to an \
  2515. integer. */
  2516. {
  2517. extern boolean eval_msgs;
  2518.  
  2519. eval_msgs= NO;
  2520. EVALUATE(val,cur_case->case_txt.start,cur_case->case_txt.next);
  2521. eval_msgs= YES;
  2522. }
  2523.  
  2524. switch(val.type)
  2525. {
  2526. case Int:
  2527. cur_case->value= (CASE_TYPE)(val.value.i);
  2528. break;
  2529.  
  2530. case Double:
  2531.  
  2532. RAT_error(WARNING,OC("Case value %#g of type double truncated to int"),1,val.value.d);
  2533. cur_case->value= (CASE_TYPE)(val.value.d);
  2534. break;
  2535.  
  2536. default:
  2537. /* The case didn't evaluate to an integer. */
  2538. computed_goto= NO;
  2539. goto not_integer;
  2540. }
  2541.  
  2542. /* Running determination of the minimum and maximum |case| value. */
  2543. if(cur_case->value<cmin)cmin= cur_case->value;
  2544. if(cur_case->value>cmax)cmax= cur_case->value;
  2545. }
  2546.  
  2547. if(cur_switch.ncases==1&&s_default!=0)
  2548. {
  2549. mcases= 0;
  2550. computed_goto= YES;
  2551. goto not_integer;
  2552. }
  2553. else mcases= (cmax-cmin+1);/* Spread in the cases. */
  2554.  
  2555. if((num_cases= cur_switch.ncases-(unsigned short)(s_default!=0))==0)
  2556. {
  2557. computed_goto= NO;
  2558. goto not_integer;
  2559. }
  2560. computed_goto= BOOLEAN((num_cases>marginal_cases&&
  2561. mcases<max_spread)?YES:
  2562. ((double)mcases)/num_cases<=g_ratio);
  2563.  
  2564. not_integer:;
  2565. }
  2566.  
  2567. ;
  2568.  
  2569. if(computed_goto)
  2570. {
  2571. CASE_TYPE m;/* Indexes case values. */
  2572. unsigned short k;/* Indexes the cases. */
  2573.  
  2574.  
  2575. /* Generate computed |goto| to handle the cases; fill in any gaps. */
  2576. OUTDENT;
  2577. if(mcases>0){id0(id__GOTO);LP;}
  2578.  
  2579. for(m= 0;m<mcases;m++,m<mcases?COMMA:RP)
  2580. LABEL(label_case(cmin,m));
  2581.  
  2582. if(mcases>0)
  2583. {
  2584. COMMA;LP;copy_out(a,pa,!macro);RP;
  2585. MINUS;LP;NUMBER(cmin-1);RP;NL;
  2586. }
  2587.  
  2588. /* Handle the out-of-bound statements. (If the previous |goto| was out of \
  2589. range, control passes to here.) */
  2590. GOTO(s_default?s_default:(was_break= YES,s_break));
  2591. INDENT;
  2592.  
  2593. /* Output the various cases. */
  2594. for(k= 1;k<=cur_switch.ncases;k++)
  2595. {
  2596. cur_case= &cur_switch.cases[k];
  2597.  
  2598. show_cmd(cur_case);
  2599. OUTDENT;
  2600. CONTINUE(cur_case->label);
  2601. INDENT;
  2602. copy_out(cur_case->txt.start,cur_case->txt.next,!macro);
  2603. rlevel--;
  2604. }
  2605. }
  2606.  
  2607.  
  2608. else
  2609. {
  2610. boolean case_ended_with_break= NO;
  2611. boolean made_temp= YES;/* Did we construct a temporary integer for the \
  2612.                 |switch|? */
  2613.  
  2614. /* |made_temp == NO| means the expression is a single identifier. */
  2615. if(!Fortran88&&(made_temp= BOOLEAN(!((pa-a)==2&&!TOKEN1(*a)))))
  2616. {
  2617. /* Make a temporary integer identifier to effect the comparisons. */
  2618.  
  2619. if(
  2620. nsprintf(temp,OC("I%d"),1,s_break)>=(int)(N_IDBUF))OVERFLW("temp","");
  2621. to_ASCII(temp);
  2622. icase= ID_NUM((ASCII HUGE*)temp,(ASCII HUGE*)(temp+STRLEN(temp)));
  2623.  
  2624. id0(icase);EQUALS;copy_out(a,pa,!macro);NL;
  2625. }
  2626.  
  2627. for(k= 1;k<=cur_switch.ncases;k++)
  2628.  
  2629. {
  2630. cur_case= &cur_switch.cases[k];
  2631.  
  2632. if(Fortran88)
  2633. if(k==1)s_case= max_stmt++;
  2634. else
  2635. {
  2636.  
  2637. {
  2638. CASE HUGE*last_case= &cur_switch.cases[k-1];
  2639.  
  2640.  
  2641. if(PTR_DIFF(long,last_case->txt.next,last_case->txt.start)>=3)
  2642. case_ended_with_break= 
  2643. BOOLEAN(MEMCMP(last_case->txt.next-3,break_tokens,3)==0);
  2644. else case_ended_with_break= NO;
  2645. }
  2646.  
  2647.  
  2648. if(!case_ended_with_break){GOTO(s_case);}
  2649. }
  2650.  
  2651. show_cmd(cur_case);
  2652. OUTDENT;
  2653. if(Fortran88)
  2654. {
  2655. id0(id__CASE);
  2656.  
  2657. if(cur_case->is_default)id0(id__DEFAULT);
  2658. else
  2659. {
  2660. if(*cur_case->case_txt.start!=050)LP;
  2661. copy_out(cur_case->case_txt.start,cur_case->case_txt.next,
  2662. !macro);
  2663. if(*(cur_case->case_txt.next-1)!=051)RP;
  2664. }
  2665. NL;
  2666. INDENT;
  2667. if(k>1&&!case_ended_with_break)
  2668. {
  2669. CONTINUE(s_case);
  2670. s_case= max_stmt++;
  2671. }
  2672. }
  2673. else
  2674. {
  2675. if(cur_case->is_default){CONTINUE(s_default);}
  2676. else
  2677. {
  2678. IF(s_case);LP;NOT;LP;
  2679. /* The |made_temp?: form of the next command crashed the Apollo \
  2680. compiler. */
  2681. if(made_temp)id0(icase);else copy_out(a,pa,!macro);
  2682. EQ_EQ;
  2683. copy_out(cur_case->case_txt.start,
  2684. cur_case->case_txt.next,!macro);
  2685. RP;RP;
  2686. GOTO(s_case= max_stmt++);
  2687. }
  2688. INDENT;
  2689. }
  2690.  
  2691. /* Recall the text stored previously. */
  2692. copy_out(cur_case->txt.start,cur_case->txt.next,!macro);
  2693.  
  2694. rlevel--;
  2695. }
  2696.  
  2697.  
  2698.  
  2699. if(!Fortran88)
  2700. {
  2701. CONTINUE(s_case);/* Finish off the last |case|. */
  2702. if(s_default)
  2703. {
  2704. GOTO(s_default);/* Jump to the |default|, if present. */
  2705. }
  2706. }
  2707. }
  2708.  
  2709.  
  2710. OUTDENT;
  2711.  
  2712. if(Fortran88)
  2713. {
  2714. if(was_break)LABEL(s_break);
  2715. id0(id__END);id0(id__SELECT);
  2716. if(symbolic_label)id0(symbolic_label);
  2717. NL;
  2718. }
  2719. else if(was_break){CONTINUE(s_break);}
  2720.  
  2721. wlevel--;
  2722. rlevel--;
  2723. switch_level--;
  2724.  
  2725. FREE_MEM(a,"switch:a",SAVE8,eight_bits);
  2726. }
  2727.  
  2728.  
  2729.  
  2730. SRTN
  2731. show_cmd FCN((cur_case))
  2732. CONST CASE HUGE*cur_case C1("")
  2733. {
  2734. if(cur_case->is_default)
  2735. {
  2736. expanding(default_CMD);
  2737.  
  2738. out_cmd(NO,'t',OC(""),OC(":"),0);
  2739. }
  2740. else
  2741. {
  2742. expanding(case_CMD);
  2743.  
  2744. out_cmd(NO,'c',OC(""),OC(" %s:"),2,cur_case->case_txt.start,cur_case->case_txt.next);
  2745. }
  2746. }
  2747.  
  2748.  
  2749.  
  2750. STMT_LBL
  2751. label_case FCN((cmin,m))
  2752. CASE_TYPE cmin C0("")
  2753. CASE_TYPE m C1("")
  2754. {
  2755. CASE_TYPE num= cmin+m;
  2756. unsigned short k;
  2757.  
  2758. /* Check for ordinary cases. */
  2759. for(k= 1;k<=cur_switch.ncases;k++)
  2760. {
  2761. cur_case= &cur_switch.cases[k];
  2762.  
  2763. if(!cur_case->is_default&&cur_case->value==num)
  2764. return cur_case->label= s_case= max_stmt++;
  2765. }
  2766.  
  2767. /* Look for |default|. */
  2768. for(k= 1;k<=cur_switch.ncases;k++)
  2769. if(cur_case->is_default)return s_default;
  2770.  
  2771. return s_break;/* A gap. */
  2772. }
  2773.  
  2774.  
  2775. X_FCN x_case(VOID)
  2776. {
  2777. if(switch_level==0)
  2778. {
  2779. not_switch(OC("case"));
  2780. return;
  2781. }
  2782.  
  2783. expanding(case_CMD);
  2784.  
  2785.  
  2786.  
  2787. *cur_case->txt.next= '\0';/* Terminate previous text. */
  2788.  
  2789. /* Get address of next available |CASE| structure. */
  2790. cur_case= &cur_switch.cases[++cur_switch.ncases];
  2791.  
  2792. /* If that hasn't been allocated yet, do so. */
  2793. if(cur_case->case_txt.start==NULL)
  2794. {
  2795. cur_case->case_txt.start= 
  2796. GET_MEM("cur_case->case_txt.start",SAVE8,eight_bits);
  2797. cur_case->case_txt.end= cur_case->case_txt.start+SAVE8;
  2798.  
  2799. cur_case->txt.start= 
  2800. GET_MEM("cur_case->txt.start",BIG_SAVE8,eight_bits);
  2801. cur_case->txt.end= cur_case->txt.start+BIG_SAVE8;
  2802. }
  2803.  
  2804. /* Initialize the pointer to beginning of buffer. */
  2805. cur_case->txt.next= cur_case->txt.start;
  2806.  
  2807. ;
  2808. cur_case->case_txt.next= SAVE_AFTER(&cur_case->case_txt.start,SAVE8,072);
  2809. cur_case->is_default= NO;
  2810.  
  2811.  
  2812. {
  2813. unsigned short k;
  2814. CONST CASE HUGE*old_case;
  2815.  
  2816. for(k= 1;k<cur_switch.ncases;k++)
  2817. {
  2818. old_case= &cur_switch.cases[k];
  2819.  
  2820. if(web_strcmp((CONST ASCII HUGE*)cur_case->case_txt.start,
  2821. (CONST ASCII HUGE*)cur_case->case_txt.next,
  2822. (CONST ASCII HUGE*)old_case->case_txt.start,
  2823. (CONST ASCII HUGE*)old_case->case_txt.next)==EQUAL)
  2824. {
  2825.  
  2826. RAT_error(ERROR,OC("Duplicate case value in switch"),0);
  2827. break;
  2828. }
  2829. }
  2830. }
  2831.  
  2832.  
  2833.  
  2834. rlevel--;
  2835. }
  2836.  
  2837.  
  2838.  
  2839. X_FCN
  2840. x_default(VOID)
  2841. {
  2842. if(switch_level==0)
  2843. {
  2844. not_switch(OC("default"));
  2845. return;
  2846. }
  2847.  
  2848. expanding(default_CMD);
  2849.  
  2850. if(cur_switch.has_default)
  2851.  
  2852. RAT_error(ERROR,OC("Only one default allowed per switch"),0);
  2853. else cur_switch.has_default= YES;
  2854.  
  2855.  
  2856.  
  2857. *cur_case->txt.next= '\0';/* Terminate previous text. */
  2858.  
  2859. /* Get address of next available |CASE| structure. */
  2860. cur_case= &cur_switch.cases[++cur_switch.ncases];
  2861.  
  2862. /* If that hasn't been allocated yet, do so. */
  2863. if(cur_case->case_txt.start==NULL)
  2864. {
  2865. cur_case->case_txt.start= 
  2866. GET_MEM("cur_case->case_txt.start",SAVE8,eight_bits);
  2867. cur_case->case_txt.end= cur_case->case_txt.start+SAVE8;
  2868.  
  2869. cur_case->txt.start= 
  2870. GET_MEM("cur_case->txt.start",BIG_SAVE8,eight_bits);
  2871. cur_case->txt.end= cur_case->txt.start+BIG_SAVE8;
  2872. }
  2873.  
  2874. /* Initialize the pointer to beginning of buffer. */
  2875. cur_case->txt.next= cur_case->txt.start;
  2876.  
  2877. ;
  2878. cur_case->case_txt.next= cur_case->case_txt.start;
  2879. cur_case->is_default= YES;
  2880.  
  2881. cur_case->label= s_default= max_stmt++;
  2882.  
  2883. char_after(':');/* |default| must be followed immediately by colon. */
  2884. rlevel--;
  2885. }
  2886.  
  2887.  
  2888.  
  2889.  
  2890. X_FCN x_program(VOID)
  2891. {
  2892. sixteen_bits a;
  2893. eight_bits b;
  2894.  
  2895. expanding(program_CMD);
  2896.  
  2897.  
  2898.  
  2899. WHILE()
  2900. {
  2901. a= next_byte();
  2902.  
  2903. if(!(a==040||a==tab_mark))
  2904. break;
  2905. }
  2906.  
  2907. if(TOKEN1(a))
  2908. {
  2909. #if(YES)
  2910.  
  2911. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"program");
  2912. #endif
  2913. BACK_UP
  2914. cur_fcn= NO_FCN;
  2915. is_function= NO;
  2916. }
  2917. else
  2918. {
  2919. cur_fcn= IDENTIFIER(a,next_byte());
  2920. is_function= NO;
  2921. }
  2922.  
  2923. id0(id_program);id0(cur_fcn);
  2924.  
  2925. if(cur_fcn==id_procedure)
  2926. {
  2927. COPY_TO(073);NL;
  2928. }
  2929. else
  2930. {
  2931. b= next_byte();BACK_UP
  2932. if(b==050)PARENS;
  2933. NL;
  2934. EAT_AUTO_SEMI;
  2935. skip_newlines(COPY_COMMENTS);
  2936. INDENT;
  2937. copy_out(insert.program.start,insert.program.end,!macro);
  2938. out_char(073);
  2939. COPY_2TO(0173,NOT_AFTER);
  2940. if(psave_buffer>save_buffer)NL;
  2941. brace_level++;
  2942. stmt(TO_OUTPUT,BRACE_ONLY);
  2943. brace_level--;
  2944. OUTDENT;
  2945.  
  2946. id0(id__END);
  2947. if(Fortran88){id0(id_program);id0(cur_fcn);}
  2948. NL;
  2949. }
  2950.  
  2951. cur_fcn= NO_FCN;
  2952.  
  2953. rlevel--;
  2954. }
  2955.  
  2956. X_FCN x_module(VOID)
  2957. {
  2958. sixteen_bits a;
  2959. eight_bits b;
  2960.  
  2961. expanding(module_CMD);
  2962.  
  2963.  
  2964.  
  2965. WHILE()
  2966. {
  2967. a= next_byte();
  2968.  
  2969. if(!(a==040||a==tab_mark))
  2970. break;
  2971. }
  2972.  
  2973. if(TOKEN1(a))
  2974. {
  2975. #if(YES)
  2976.  
  2977. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"module");
  2978. #endif
  2979. BACK_UP
  2980. cur_fcn= NO_FCN;
  2981. is_function= NO;
  2982. }
  2983. else
  2984. {
  2985. cur_fcn= IDENTIFIER(a,next_byte());
  2986. is_function= NO;
  2987. }
  2988.  
  2989. id0(id_module);id0(cur_fcn);
  2990.  
  2991. if(cur_fcn==id_procedure)
  2992. {
  2993. COPY_TO(073);NL;
  2994. }
  2995. else
  2996. {
  2997. b= next_byte();BACK_UP
  2998. if(b==050)PARENS;
  2999. NL;
  3000. EAT_AUTO_SEMI;
  3001. skip_newlines(COPY_COMMENTS);
  3002. INDENT;
  3003. copy_out(insert.module.start,insert.module.end,!macro);
  3004. out_char(073);
  3005. COPY_2TO(0173,NOT_AFTER);
  3006. if(psave_buffer>save_buffer)NL;
  3007. brace_level++;
  3008. stmt(TO_OUTPUT,BRACE_ONLY);
  3009. brace_level--;
  3010. OUTDENT;
  3011.  
  3012. id0(id__END);
  3013. if(Fortran88){id0(id_module);id0(cur_fcn);}
  3014. NL;
  3015. }
  3016.  
  3017. cur_fcn= NO_FCN;
  3018.  
  3019. rlevel--;
  3020. }
  3021.  
  3022. X_FCN x_subroutine(VOID)
  3023. {
  3024. sixteen_bits a;
  3025. eight_bits b;
  3026.  
  3027. expanding(subroutine_CMD);
  3028.  
  3029.  
  3030.  
  3031. WHILE()
  3032. {
  3033. a= next_byte();
  3034.  
  3035. if(!(a==040||a==tab_mark))
  3036. break;
  3037. }
  3038.  
  3039. if(TOKEN1(a))
  3040. {
  3041. #if(YES)
  3042.  
  3043. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"subroutine");
  3044. #endif
  3045. BACK_UP
  3046. cur_fcn= NO_FCN;
  3047. is_function= NO;
  3048. }
  3049. else
  3050. {
  3051. cur_fcn= IDENTIFIER(a,next_byte());
  3052. is_function= NO;
  3053. }
  3054.  
  3055. id0(id_subroutine);id0(cur_fcn);
  3056.  
  3057. if(cur_fcn==id_procedure)
  3058. {
  3059. COPY_TO(073);NL;
  3060. }
  3061. else
  3062. {
  3063. b= next_byte();BACK_UP
  3064. if(b==050)PARENS;
  3065. NL;
  3066. EAT_AUTO_SEMI;
  3067. skip_newlines(COPY_COMMENTS);
  3068. INDENT;
  3069. copy_out(insert.subroutine.start,insert.subroutine.end,!macro);
  3070. out_char(073);
  3071. COPY_2TO(0173,NOT_AFTER);
  3072. if(psave_buffer>save_buffer)NL;
  3073. brace_level++;
  3074. stmt(TO_OUTPUT,BRACE_ONLY);
  3075. brace_level--;
  3076. OUTDENT;
  3077.  
  3078. id0(id__END);
  3079. if(Fortran88){id0(id_subroutine);id0(cur_fcn);}
  3080. NL;
  3081. }
  3082.  
  3083. cur_fcn= NO_FCN;
  3084.  
  3085. rlevel--;
  3086. }
  3087.  
  3088. X_FCN x_function(VOID)
  3089. {
  3090. sixteen_bits a;
  3091. eight_bits b;
  3092.  
  3093. expanding(function_CMD);
  3094.  
  3095.  
  3096.  
  3097. WHILE()
  3098. {
  3099. a= next_byte();
  3100.  
  3101. if(!(a==040||a==tab_mark))
  3102. break;
  3103. }
  3104.  
  3105. if(TOKEN1(a))
  3106. {
  3107. #if(YES)
  3108.  
  3109. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"function");
  3110. #endif
  3111. BACK_UP
  3112. cur_fcn= NO_FCN;
  3113. is_function= NO;
  3114. }
  3115. else
  3116. {
  3117. cur_fcn= IDENTIFIER(a,next_byte());
  3118. is_function= YES;
  3119. }
  3120.  
  3121. id0(id_function);id0(cur_fcn);
  3122.  
  3123. if(cur_fcn==id_procedure)
  3124. {
  3125. COPY_TO(073);NL;
  3126. }
  3127. else
  3128. {
  3129. b= next_byte();BACK_UP
  3130. if(b==050)PARENS;
  3131. NL;
  3132. EAT_AUTO_SEMI;
  3133. skip_newlines(COPY_COMMENTS);
  3134. INDENT;
  3135. copy_out(insert.function.start,insert.function.end,!macro);
  3136. out_char(073);
  3137. COPY_2TO(0173,NOT_AFTER);
  3138. if(psave_buffer>save_buffer)NL;
  3139. brace_level++;
  3140. stmt(TO_OUTPUT,BRACE_ONLY);
  3141. brace_level--;
  3142. OUTDENT;
  3143.  
  3144. id0(id__END);
  3145. if(Fortran88){id0(id_function);id0(cur_fcn);}
  3146. NL;
  3147. }
  3148.  
  3149. cur_fcn= NO_FCN;
  3150.  
  3151. rlevel--;
  3152. }
  3153.  
  3154. X_FCN x_blockdata(VOID)
  3155. {
  3156. sixteen_bits a;
  3157. eight_bits b;
  3158.  
  3159. expanding(blockdata_CMD);
  3160.  
  3161.  
  3162.  
  3163. WHILE()
  3164. {
  3165. a= next_byte();
  3166.  
  3167. if(!(a==040||a==tab_mark))
  3168. break;
  3169. }
  3170.  
  3171. if(TOKEN1(a))
  3172. {
  3173. #if(NO)
  3174.  
  3175. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"blockdata");
  3176. #endif
  3177. BACK_UP
  3178. cur_fcn= NO_FCN;
  3179. is_function= NO;
  3180. }
  3181. else
  3182. {
  3183. cur_fcn= IDENTIFIER(a,next_byte());
  3184. is_function= NO;
  3185. }
  3186.  
  3187. id0(id_blockdata);id0(cur_fcn);
  3188.  
  3189. if(cur_fcn==id_procedure)
  3190. {
  3191. COPY_TO(073);NL;
  3192. }
  3193. else
  3194. {
  3195. b= next_byte();BACK_UP
  3196. if(b==050)PARENS;
  3197. NL;
  3198. EAT_AUTO_SEMI;
  3199. skip_newlines(COPY_COMMENTS);
  3200. INDENT;
  3201. copy_out(insert.blockdata.start,insert.blockdata.end,!macro);
  3202. out_char(073);
  3203. COPY_2TO(0173,NOT_AFTER);
  3204. if(psave_buffer>save_buffer)NL;
  3205. brace_level++;
  3206. stmt(TO_OUTPUT,BRACE_ONLY);
  3207. brace_level--;
  3208. OUTDENT;
  3209.  
  3210. id0(id__END);
  3211. if(Fortran88){id0(id_blockdata);id0(cur_fcn);}
  3212. NL;
  3213. }
  3214.  
  3215. cur_fcn= NO_FCN;
  3216.  
  3217. rlevel--;
  3218. }
  3219.  
  3220. X_FCN x_interface(VOID)
  3221. {
  3222. sixteen_bits a;
  3223. eight_bits b;
  3224.  
  3225. expanding(interface_CMD);
  3226.  
  3227.  
  3228.  
  3229. WHILE()
  3230. {
  3231. a= next_byte();
  3232.  
  3233. if(!(a==040||a==tab_mark))
  3234. break;
  3235. }
  3236.  
  3237. if(TOKEN1(a))
  3238. {
  3239. #if(NO)
  3240.  
  3241. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"interface");
  3242. #endif
  3243. BACK_UP
  3244. cur_fcn= NO_FCN;
  3245. is_function= NO;
  3246. }
  3247. else
  3248. {
  3249. cur_fcn= IDENTIFIER(a,next_byte());
  3250. is_function= NO;
  3251. }
  3252.  
  3253. id0(id_interface);id0(cur_fcn);
  3254.  
  3255. if(cur_fcn==id_procedure)
  3256. {
  3257. COPY_TO(073);NL;
  3258. }
  3259. else
  3260. {
  3261. b= next_byte();BACK_UP
  3262. if(b==050)PARENS;
  3263. NL;
  3264. EAT_AUTO_SEMI;
  3265. skip_newlines(COPY_COMMENTS);
  3266. INDENT;
  3267. copy_out(insert.interface.start,insert.interface.end,!macro);
  3268. out_char(073);
  3269. COPY_2TO(0173,NOT_AFTER);
  3270. if(psave_buffer>save_buffer)NL;
  3271. brace_level++;
  3272. stmt(TO_OUTPUT,BRACE_ONLY);
  3273. brace_level--;
  3274. OUTDENT;
  3275.  
  3276. id0(id__END);
  3277. if(Fortran88){id0(id_interface);id0(cur_fcn);}
  3278. NL;
  3279. }
  3280.  
  3281. cur_fcn= NO_FCN;
  3282.  
  3283. rlevel--;
  3284. }
  3285.  
  3286.  
  3287.  
  3288. X_FCN
  3289. x_block(VOID)
  3290. {
  3291. sixteen_bits a;
  3292.  
  3293. if(TOKEN1(a= next_byte()))
  3294. {
  3295. BACK_UP
  3296. id0(id_block);
  3297. }
  3298. else
  3299. {
  3300. a= IDENTIFIER(a,next_byte());
  3301.  
  3302. if(a==id_data)x_blockdata();
  3303. else
  3304. {
  3305. BACK_UP
  3306. id0(a);
  3307. }
  3308. }
  3309. }
  3310.  
  3311.  
  3312.  
  3313. X_FCN
  3314. x_contains(VOID)
  3315. {
  3316. OUTDENT;
  3317. id0(id__CONTAINS);
  3318. char_after(':');
  3319. NL;
  3320. INDENT;
  3321. }
  3322.  
  3323.  
  3324.  
  3325.  
  3326. X_FCN x_type(VOID)
  3327. {
  3328. sixteen_bits a;
  3329. eight_bits b;
  3330.  
  3331. b= next_byte();BACK_UP
  3332. if(b==054){}
  3333. else if(b==050)
  3334. {
  3335. id0(id_type);
  3336. return;
  3337. }
  3338.  
  3339. expanding(type_CMD);
  3340.  
  3341. if(TOKEN1(a= next_byte()))
  3342. {
  3343.  
  3344. RAT_error(ERROR,OC("Expected identifier after \"%s\""),1,"type");
  3345. BACK_UP
  3346. cur_struct= NO_FCN;
  3347. }
  3348. else
  3349. {
  3350. cur_struct= IDENTIFIER(a,next_byte());
  3351. }
  3352.  
  3353. id0(id_type);id0(cur_struct);
  3354. NL;
  3355. INDENT;
  3356. brace_level++;
  3357. stmt(TO_OUTPUT,BRACE_ONLY);
  3358. brace_level--;
  3359. OUTDENT;
  3360.  
  3361. id0(id__END);id0(id_type);id0(cur_struct);
  3362. char_after(';');OUT_CHAR(';');
  3363.  
  3364. wlevel--;
  3365. rlevel--;
  3366. }
  3367.  
  3368.  
  3369.  
  3370. X_FCN
  3371. x_return(VOID)
  3372. {
  3373. eight_bits HUGE*return_expr= NULL,HUGE*pr;
  3374.  
  3375. expanding(return_CMD);
  3376.  
  3377. /* Save the return expression, if it's there. */
  3378. if((pr= SAVE_AFTER(&return_expr,SAVE8,073))>return_expr)
  3379. {
  3380. if(!is_function)
  3381.  
  3382. RAT_error(ERROR,OC("Can't return value from program or subroutine"),0);
  3383. else
  3384. {
  3385.  
  3386. out_cmd(YES,'r',OC(""),OC(" %s"),2,return_expr,pr);
  3387. id0(cur_fcn);EQUALS;
  3388. copy_out(return_expr,pr,!macro);NL;
  3389. }
  3390. }
  3391.  
  3392. RETURN;
  3393. rlevel--;
  3394. FREE_MEM(return_expr,"return_expr",SAVE8,eight_bits);
  3395. }
  3396.  
  3397.  
  3398.  
  3399. X_FCN
  3400. x_unroll(VOID)
  3401. {
  3402. eight_bits HUGE*I= NULL,HUGE*pI;
  3403. eight_bits HUGE*Imin= NULL,HUGE*pImin;
  3404. eight_bits HUGE*Imax= NULL,HUGE*pImax;
  3405. eight_bits HUGE*Di= NULL,HUGE*pDi;
  3406. eight_bits HUGE*txt= NULL,HUGE*ptxt;
  3407. int i,imin,imax,di;
  3408. name_pointer n;
  3409. text_pointer t;
  3410. eight_bits temp[20];
  3411. extern int last_bytes;
  3412. extern boolean saved_token;
  3413. eight_bits c;
  3414.  
  3415. expanding(_DO_CMD);
  3416.  
  3417.  
  3418. {
  3419. eight_bits c;
  3420.  
  3421. if((c= next_byte())!='(')
  3422. {
  3423. didnt_expand('(',c,"$DO");
  3424. return;
  3425. }
  3426. };
  3427.  
  3428. pI= SAVE_AFTER(&I,SAVE8,054);
  3429.  
  3430. if(TOKEN1(*I))
  3431. {
  3432.  
  3433. RAT_error(ERROR,OC("Expected identifier for first argument of $DO; \
  3434. expansion aborted"),0);
  3435. return;
  3436. }
  3437.  
  3438. pImin= SAVE_AFTER(&Imin,SAVE8,054);
  3439. imin= neval(Imin,pImin);
  3440.  
  3441. pImax= SAVE_AFTER(&Imax,SAVE8,054);
  3442. imax= neval(Imax,pImax);
  3443.  
  3444. pDi= SAVE_AFTER(&Di,SAVE8,051);
  3445. di= neval(Di,pDi);
  3446.  
  3447. EAT_AUTO_SEMI;
  3448. skip_newlines(NO);
  3449.  
  3450. c= next_byte();
  3451.  
  3452. if(!(c==0173||c==050))
  3453. {
  3454.  
  3455. RAT_error(ERROR,OC("Was expecting '{' or '(', not '%c', after $DO(); \
  3456. expansion aborted"),1,XCHR(c));
  3457. return;
  3458. }
  3459.  
  3460. /* Absorb the body of the |$DO|.  Tell |next_byte| to not expand macros, so \
  3461. the loop counter can be used as an argument to a macro such as |$IFCASE|. */
  3462. mac_protected= YES;
  3463. ptxt= SAVE_AFTER(&txt,BIG_SAVE8,c==0173?0175:051);
  3464. mac_protected= NO;
  3465.  
  3466. n= name_dir+IDENTIFIER(*I,*(I+1));
  3467. n->info.Macro_type= IMMEDIATE_MACRO;
  3468. t= GET_MEM("equiv",2,text);
  3469. n->equiv_or_xref= (EQUIV)t;
  3470. t->tok_start= temp;
  3471. t->moffset= 2;
  3472.  
  3473. if(!((di>=0&&imax<imin)||(di<0&&imax>imin)))
  3474. for(i= imin;di>=0?i<=imax:i>=imax;i+= di)
  3475. {
  3476. STRNCPY(temp,I,2);
  3477. sprintf((char*)(temp+2),"%c%d%c",XCHR(constant),i,XCHR(constant));
  3478. to_ASCII(temp+2);
  3479. (t+1)->tok_start= temp+STRLEN(temp);
  3480. copy_out(txt,ptxt,!macro);
  3481. if(i==imax)break;
  3482. }
  3483.  
  3484. rlevel--;
  3485.  
  3486. FREE_MEM(t,"t",2,text);
  3487. n->equiv_or_xref= NULL;
  3488. n->info.Macro_type= NOT_DEFINED;
  3489.  
  3490. FREE_MEM(I,"unroll:I",SAVE8,eight_bits);
  3491. FREE_MEM(Imin,"unroll:Imin",SAVE8,eight_bits);
  3492. FREE_MEM(Imax,"unroll:Imax",SAVE8,eight_bits);
  3493. FREE_MEM(txt,"unroll:txt",SAVE8,eight_bits);
  3494. }
  3495.  
  3496.  
  3497.  
  3498. SRTN
  3499. ini_Ratfor(VOID)
  3500. {
  3501. insert.program.start= insert.program.end= 
  3502. GET_MEM("program",2,eight_bits);
  3503. insert.module.start= insert.module.end= 
  3504. GET_MEM("module",2,eight_bits);
  3505. insert.subroutine.start= insert.subroutine.end= 
  3506. GET_MEM("subroutine",2,eight_bits);
  3507. insert.function.start= insert.function.end= 
  3508. GET_MEM("function",2,eight_bits);
  3509. insert.blockdata.start= insert.blockdata.end= 
  3510. GET_MEM("blockdata",2,eight_bits);
  3511. insert.interface.start= insert.interface.end= 
  3512. GET_MEM("interface",2,eight_bits);
  3513. }
  3514.  
  3515.  
  3516. #endif /* Part 2 */
  3517.  
  3518.  
  3519.  
  3520.  
  3521.  
  3522.