home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / fweb153.zip / fweb-1.53 / web / common.hweb < prev    next >
Text File  |  1995-09-23  |  12KB  |  435 lines

  1. @z --- common.hweb ---
  2.  
  3. FWEB version 1.53 (September 23, 1995)
  4.  
  5. Based on version 0.5 of S. Levy's CWEB [copyright (C) 1987 Princeton University]
  6.  
  7. @x-----------------------------------------------------------------------------
  8.  
  9. @i typedefs.hwb
  10.  
  11. @* DEFINITIONS for TANGLE and WEAVE. Here's stuff required for
  12. \.{tangle.web} and \.{weave.web}. 
  13.  
  14. @ As much as possible, we adhere to ANSI conventions. However, to support
  15. pre-ANSI compilers such as \.{gcc}, we must make some modifications. It is
  16. assumed that the compilers predefine macros such as |vax|, |sun|, or |mac|,
  17. in \It{lower case}; if they do not, then these macros must be defined from
  18. the command line. In addition, the \WEB\ files must be tangled with
  19. \It{upper case} macros such as |VAX|, |SUN|, or |MAC| defined from the
  20. command line, as in \.{ftangle tangle -m"SUN"}. It is conventional to put
  21. the machine macro command into the ini file \.{.fweb}, as in ``\.{+mSUN}''.
  22.  
  23. @i os.hweb // System-dependent definitions.
  24.  
  25. @ The following flag is used for \Cpp. (??)
  26. @<Common...@>=
  27.  
  28. EXTERN boolean long_comment;
  29.  
  30. @ Code related to the character set. \It{Mess around here only at your own
  31. risk.} 
  32.  
  33. @D and_and OCTAL(4) // `|&&|'.
  34. @D star_star OCTAL(5) // `|@r x**y|' .
  35. @D colon_colon OCTAL(11) // \Cpp\ and \Fortran--90: `$\CF$'.
  36.  
  37. /* The next two only occur in different languages, so they can have the same
  38. value. */  
  39. @D neqv OCTAL(10) // `|@r .neqv.|'.
  40. @D ellipsis neqv // `|...|'.
  41.  
  42. @D stmt_label OCTAL(30)
  43.  
  44. @D slash_slash OCTAL(26)  // Concatenation `|@r \/|' .
  45.  
  46. @D bell OCTAL(7) // |ASCII| code for ringing the bell.
  47. @D tab_mark @'\t' // |ASCII| code used as tab-skip.
  48. @D line_feed OCTAL(12) /* |ASCII| code thrown away at end of line; $\equiv$
  49.             \.{'\\n'}. */
  50. @D form_feed OCTAL(14) // |ASCII| code used at end of page.
  51. @D carriage_return OCTAL(15) // |ASCII| code used at end of line.
  52.  
  53. @D gt_gt OCTAL(20) // `|>>|'; this doesn't exist in MIT.
  54. @D lt_lt OCTAL(22) // `|<<|'; this doesn't exist in MIT.
  55.  
  56. @D plus_plus OCTAL(13) // `|++|'; this corresponds to MIT's up-arrow.
  57. @D minus_minus OCTAL(1) // `|--|'; this corresponds to MIT's down-arrow.
  58.  
  59. @D minus_gt OCTAL(31) // `|->|'.
  60. @D eqv minus_gt // `|@r .eqv.|'.
  61.  
  62. @D not_eq OCTAL(32) // `|!=|'.
  63.  
  64. @D paste OCTAL(33) // `|##|'.
  65.  
  66. @D lt_eq OCTAL(34) // `|<=|'.
  67. @D gt_eq OCTAL(35) // `|>=|'.
  68.  
  69. @D eq_eq OCTAL(36) // `|==|'.
  70.  
  71. @D or_or OCTAL(37) // `||| |'.
  72.  
  73. @D begin_language OCTAL(16) // Mark a language switch.
  74.  
  75. @D left_array OCTAL(21)  // `$\LS$'.
  76. @D right_array OCTAL(25) // `$\SR$'.
  77.  
  78. @D interior_semi OCTAL(24) // `\.;'.
  79.  
  80. @<Common code...@>=
  81.  
  82. IN_COMMON ASCII xord[]; // specifies conversion of input characters.
  83. @#ifdef scramble_ASCII
  84.     IN_COMMON ASCII xxord[];
  85. @#endif
  86. IN_COMMON outer_char xchr[]; // specifies conversion of output characters.
  87.  
  88. @ Code related to input routines:
  89.  
  90. @<Common code...@>=
  91.  
  92. IN_COMMON BUF_SIZE buf_size; // Used for \FWEAVE; see \.{common.web}.
  93. IN_COMMON ASCII HUGE *loc; /* points to the next character to be read from the
  94.                 buffer*/ 
  95.  
  96. @ Code related to identifier and module name storage:
  97.  
  98. @d ID_FLAG 10240 // \bf DON'T MONKEY WITH THIS NUMBER!.
  99.  
  100. @d length(c) (c+1)->byte_start-(c)->byte_start // the length of a name.
  101.  
  102. @d llink link // left link in binary search tree for module names.
  103. @d root name_dir->rlink /* the root of the binary search tree
  104.   for module names */
  105.  
  106. @d is_intrinsic(n) (n->intrinsic_word & (boolean)language)
  107. @d is_keyword(n) (n->keyword & (boolean)language)
  108.  
  109. @<Common code...@>=
  110.  
  111. IN_COMMON name_pointer name_ptr; // first unused position in |byte_start|.
  112. IN_COMMON ASCII HUGE *byte_ptr; // first unused position in |byte_mem|.
  113.  
  114. typedef name_pointer HUGE *hash_pointer;
  115. IN_COMMON hash_pointer hash, /* heads of hash lists */
  116.     hash_end, /* end of |hash| */
  117.     h; /* index into hash-head array */
  118.  
  119.  
  120. @ To distinguish between the constructions \.{@@<\dots@@>} and
  121. \.{\#<\dots@@>}, both of which return |module_name|, we introduce the flag
  122. |mac_mod_name|. 
  123.  
  124. @<Common code...@>=
  125.  
  126. EXTERN boolean mac_mod_name;
  127.  
  128. @ Code related to module numbers:
  129. @<Common code...@>=
  130.  
  131. IN_COMMON sixteen_bits module_count; // The current module number.
  132. IN_COMMON boolean HUGE *chngd_module; // Dynamic array: Is the module changed?
  133. IN_COMMON boolean prn_where; // Tells \.{TANGLE} to print line and file    info.
  134.  
  135. @ Code relating to output:
  136.  
  137. @d UPDATE_TERMINAL fflush(stdout) // Empty the terminal output buffer.
  138. @d new_line putchar('\n') @d putxchar putchar
  139. @d ASCII_write(p0,n) fflush(stdout),
  140.         ASCII_file_write(stdout,p0,(int)(n))@;
  141.     /* Write on the standard output, converting from |ASCII|. */ 
  142.  
  143. @ For FORTRAN, \&{format} commands are annoying, because the use of slashes
  144. doesn't fit with the rest of the \Fortran\ syntax. Thus, we'll deal with the
  145. |format| statement something like a preprocessor statement, in that we'll
  146. raise a special flag when we're inside it, and issue special tokens to
  147. indicate the start and the end of the statement.
  148.  
  149. @D begin_format_stmt OCTAL(171)
  150. @D end_format_stmt OCTAL(172)
  151.  
  152. @ For~C, getting an identifier is simple. For FORTRAN, we treat \&{format}
  153. statements much like C's preprocessor statement. However, there's no
  154. special character to start a \&{format} line; we have to actually check the
  155. identifier. Furthermore, it looks nicer if constructions such as \\{f6.2}
  156. are treated as one identifier, so when we're inside a \&{format} statement
  157. we allow the period to be an acceptable (internal) character for an identifier.
  158.  
  159. @d is_identifier(c) (isAlpha(c) || c==@'_' || c==@'$' ||
  160.     (c==@'%' && language!=C && !Fortran88) ) /* This defines the starting
  161.                     character of an identifier. */ 
  162.  
  163. @d is_kind(c) (isDigit(c) || isAlpha(c) || c==@'_' || c==@'$') 
  164.     /* \Fortran-90 kind parameter. */
  165.  
  166. @<Get an identifier@>= 
  167. @{
  168. IN_COMMON ASCII HUGE *pformat, HUGE *pdata;
  169. @% IN_COMMON ASCII HUGE *pdefault, HUGE *pcontains;
  170.  
  171. get_identifier:
  172.   id_first = --loc;
  173.  
  174. /* Scan over subsequent elements of an identifier. */
  175.   for(++loc; isAlpha(*loc) || isDigit(*loc) || 
  176.     *loc==@'_' || *loc==@'$' || (in_format && *loc==@'.'); loc++)
  177.         ;
  178.  
  179. id_loc=loc;  /* End plus one of the identifier. */
  180.  
  181. if(FORTRAN_LIKE(language))
  182.     {
  183.     if(web_strcmp(pformat,pformat+6,id_first,id_loc) == EQUAL)
  184.         { /* Raise special flag to say we're inside a |@r format|
  185. statement. */ 
  186.         in_format = YES;
  187.         return begin_format_stmt; 
  188.         }
  189.     else if(program==weave)
  190.         {
  191.         if(web_strcmp(pdata,pdata+4,id_first,id_loc) == EQUAL)
  192.             { // Inside a |@r data| statement.
  193.             in_data = YES;
  194.             return identifier;
  195.             }
  196.         else if(at_beginning && *loc==@':' &&
  197.                 !is_in(non_labels,id_first,id_loc))
  198.             return stmt_label;  
  199.         }
  200.     }
  201.  
  202. if(is_include_like()) sharp_include_line = YES;
  203. return identifier;
  204. }
  205.  
  206. @ Here we obtain the file name after an \.{@@o}~command.
  207. @<Scan the output file name@>=
  208. {
  209. while(*loc == @' ' || *loc == tab_mark)
  210.     {
  211.     loc++;
  212.     if(loc > limit) return ignore;
  213.     }
  214.  
  215. id_first = loc;
  216. while(*loc != @' ' && *loc != tab_mark) loc++; // Absorb file name.
  217. id_loc = loc;
  218. if(*id_first == @'"') id_first++;
  219. if(*(id_loc-1) == @'"') id_loc--;
  220. if(id_loc - id_first >= MAX_FILE_NAME_LENGTH)
  221.     {
  222.     err_print(T,"Output file name too long; allowed only %d characters",
  223.         MAX_FILE_NAME_LENGTH - 1);
  224.     id_loc = id_first + MAX_FILE_NAME_LENGTH - 1;
  225.     }
  226. }
  227.  
  228. @ These tables are initialized during |common_init|.
  229.  
  230. @<Common...@>=
  231.  
  232. #undef expr
  233. #define expr 1
  234.  
  235. #undef unop
  236. #define unop 2
  237.  
  238. #undef binop
  239. #define binop 3
  240.  
  241. extern DOTS HUGE *dots; /* The dynamic table; see \.{common.web}. */
  242.  
  243. #ifdef _FWEB_h
  244.  
  245.     EXTERN DOTS dots0[]
  246.    #if(part == 0 || part == 1)
  247.         = {
  248.         {(ASCII *)"@@@@@@",3,dot_const,expr,0}, /* Dummy */
  249.         {(ASCII *)"AND",3,dot_const,binop,and_and}, /* |and_and| */
  250.         {(ASCII *)"EQ",2,dot_const,binop,eq_eq}, /* |eq_eq| */
  251.         {(ASCII *)"EQV",3,dot_const,binop,eqv}, /* |eqv| */
  252.         {(ASCII *)"FALSE",5,dot_const,expr,0},
  253.         {(ASCII *)"GE",2,dot_const,binop,gt_eq}, /* |gt_eq| */
  254.         {(ASCII *)"GT",2,dot_const,binop,@'>'}, /* |@'>'| */
  255.         {(ASCII *)"LE",2,dot_const,binop,lt_eq}, /* |lt_eq| */
  256.         {(ASCII *)"LT",2,dot_const,binop,@'<'}, /* |@'<'| */
  257.         {(ASCII *)"NE",2,dot_const,binop,not_eq}, /* |not_eq| */
  258.         {(ASCII *)"NEQV",4,dot_const,binop,neqv}, /* |neqv| */
  259.         {(ASCII *)"NOT",3,dot_const,unop,@'!'}, /* |@'!'| */
  260.         {(ASCII *)"OR",2,dot_const,binop,or_or}, /* |or_or| */
  261.         {(ASCII *)"TRUE",4,dot_const,expr,1},
  262.         {(ASCII *)"XOR",3,dot_const,binop,neqv}, /* |neqv| */
  263.         {(ASCII *)"",0,0,0,0}
  264.         }
  265.     #endif /* |part == 1| */
  266.         ;
  267. #endif /* |_FWEB_h| */
  268.  
  269. @ The preprocessor commands have a similar format.
  270. @<Common...@>=
  271.  
  272. #ifdef _FWEB_h
  273.  
  274.     EXTERN DOTS mcmds[] 
  275.    #if(part ==0 || part == 1)
  276.      = {
  277.         {(ASCII *)"define",6,WEB_definition},
  278.         {(ASCII *)"elif",4,m_elif},
  279.         {(ASCII *)"elseif",6,m_elif},
  280.         {(ASCII *)"else",4,m_else},
  281.         {(ASCII *)"endfor",6,m_endfor},
  282.         {(ASCII *)"endif",5,m_endif},
  283.         {(ASCII *)"for",3,m_for},
  284.         {(ASCII *)"if",2,m_if},
  285.         {(ASCII *)"ifdef",5,m_ifdef},
  286.         {(ASCII *)"ifndef",6,m_ifndef},
  287.         {(ASCII *)"pragma",6,m_pragma},
  288.         {(ASCII *)"undef",5,m_undef},
  289.         {(ASCII *)"",0,0}
  290.         }
  291.     #endif /* |part == 1| */
  292.         ;
  293. #endif /* |_FWEB_h| */
  294.  
  295. @ The preprocessor commands are piggy-backed on the \.{@@\#} command. If
  296. there's text after that command, then we hunt through the above table.
  297. Otherwise, it's a |big_line_break|.
  298.  
  299. @<Process possible preprocessor command@>=
  300. @{
  301. boolean mcode;
  302.  
  303. @b
  304. *limit = @' '; /* Terminator for identifier search. */
  305. id_first = loc;
  306.  
  307. while(isAlpha(*loc)) loc++; /* Find end of identifier. */
  308.  
  309. if((mcode=is_mcmd(mcmds,id_first,loc)) != 0) return mcode;
  310.  
  311. loc = id_first; /* Failed to recognize preprocessor command. */
  312. }
  313.  
  314. @i mem.hweb /* Macros for memory allocation. */
  315.  
  316. @ Miscellaneous definitions.
  317.  
  318. @#ifndef _FWEAVE_
  319.  
  320.     @D MCHECK0(n,reason) mcheck0((unsigned long)(n),(outer_char *)reason)
  321.  
  322.     @d EVALUATE(val,p0,p1) 
  323.       {unsigned long nbytes;
  324.       val_ptr = val_heap = 
  325.       GET_MEM("val_heap",nbytes=2*((p1)-(p0)),VAL); 
  326.         evaluate(&val,p0,p1); 
  327.       if(val_heap) FREE_MEM(val_heap,"val_heap",nbytes,VAL);
  328.       }
  329.  
  330.     @d DONE_LEVEL (cur_byte >= cur_end) /* Do we need to pop? */
  331.  
  332. @#endif /* |_FWEAVE_| */
  333.  
  334. @<Glob...@>=
  335.  
  336. /* The shorter length here is primarily to keep the stack under control.
  337. Now that |N_MSGBUF| is used  dynamically, maybe this statement isn't
  338. necessary. */ 
  339. #ifdef SMALL_MEMORY
  340.     #define N_MSGBUF 2000
  341. #else
  342.     #define N_MSGBUF 10000
  343. #endif 
  344.  
  345.  
  346. @ The following helps insert spaces in the output.
  347. @<Typedef...@>=
  348.  
  349. @#ifndef _FWEAVE_
  350.  
  351.     typedef enum
  352.         {
  353.         MISCELLANEOUS, /* ``normal'' state */
  354.         NUM_OR_ID, /* state associated with numbers and identifiers */
  355.         UNBREAKABLE, /* state associated with \.{@@\&} */
  356.         VERBATIM /* state in the middle of a string */
  357.         } OUTPUT_STATE;
  358.  
  359. @#endif /* |_FWEAVE_| */
  360.  
  361. @ For debugging and error messages, we need a routine that gives the name
  362. of a control code.
  363. @m CN(code) case code: return (outer_char *)#code
  364. @A
  365. @#if defined _FWEAVE_ || defined _FTANGLE_
  366. #if(part == 0 || part == 1)
  367.  
  368. @[outer_char *ccode_name FCN((code))
  369.     eight_bits code C1("")@;
  370. {
  371. switch(code)
  372.     {
  373.     CN(begin_FORTRAN);
  374.     CN(begin_RATFOR);
  375.     CN(begin_C);
  376.     CN(ascii_constant);
  377.     CN(big_line_break);
  378.     CN(begin_meta);
  379.     CN(end_meta);
  380.     CN(TeX_string);
  381.     CN(xref_roman);
  382.     CN(xref_typewriter);
  383.     CN(xref_wildcard);
  384.     CN(formatt);
  385.     CN(definition);
  386.     CN(WEB_definition);
  387.     CN(begin_code);
  388.     CN(module_name);
  389.     CN(new_module);
  390.     CN(m_ifdef);
  391.     CN(m_ifndef);
  392.     CN(m_if);
  393.     CN(m_else);
  394.     CN(m_elif);
  395.     CN(m_endif);
  396.     CN(m_undef);
  397.  
  398. @#ifdef _FTANGLE_
  399.     CN(begin_vcmnt);
  400.     CN(begin_bp);
  401.     CN(insert_bp);
  402.     CN(control_text);
  403. @#endif /* |_FTANGLE_| */
  404.  
  405. @#ifdef _FWEAVE_
  406.     CN(dont_expand);
  407.     CN(auto_label);
  408.     CN(macro_module_name);
  409.     CN(switch_math_flag);
  410.     CN(underline);
  411.     CN(thin_space);
  412.     CN(math_break);
  413.     CN(line_break);
  414.     CN(no_line_break);
  415.     CN(pseudo_semi);
  416.     CN(macro_space);
  417.     CN(copy_mode);
  418.     CN(toggle_output);
  419.     CN(pseudo_expr);
  420.     CN(pseudo_colon);
  421.     CN(trace);
  422. @#endif /* |_FWEAVE_| */
  423.     default: return OC("UNKNOWN");
  424.     }    
  425. }
  426. #endif /* |part == 1| */
  427. @#endif /* |defined _FWEAVE_ || defined _FTANGLE_| */
  428.  
  429. @ This dummy module avoids warning messages from \FWEAVE\ if the indicated
  430. modules aren't actually used.
  431. @<Unused@>=
  432. @<Get an id...@>@;
  433. @<Process possible ...@>@;
  434.  
  435.