[BACK]Return to bc.y CVS log [TXT][DIR] Up to [local] / src / usr.bin / bc

Diff for /src/usr.bin/bc/bc.y between version 1.19 and 1.20

version 1.19, 2003/11/17 11:20:13 version 1.20, 2003/12/02 09:00:07
Line 37 
Line 37 
 #include <ctype.h>  #include <ctype.h>
 #include <err.h>  #include <err.h>
 #include <limits.h>  #include <limits.h>
   #include <search.h>
 #include <signal.h>  #include <signal.h>
 #include <stdarg.h>  #include <stdarg.h>
 #include <stdbool.h>  #include <stdbool.h>
Line 69 
Line 70 
 static void             emit_macro(int, ssize_t);  static void             emit_macro(int, ssize_t);
 static void             free_tree(void);  static void             free_tree(void);
 static ssize_t          numnode(int);  static ssize_t          numnode(int);
   static ssize_t          lookup(char *, size_t, char);
   static ssize_t          letter_node(char *);
   static ssize_t          array_node(char *);
   static ssize_t          function_node(char *);
   
 static void             add_par(ssize_t);  static void             add_par(ssize_t);
 static void             add_local(ssize_t);  static void             add_local(ssize_t);
 static void             warning(const char *);  static void             warning(const char *);
Line 92 
Line 98 
 static char             **sargv;  static char             **sargv;
 static char             *filename;  static char             *filename;
 static bool             do_fork = true;  static bool             do_fork = true;
   static u_short          var_count;
   
 extern char *__progname;  extern char *__progname;
   
 #define BREAKSTACK_SZ   (sizeof(breakstack)/sizeof(breakstack[0]))  #define BREAKSTACK_SZ   (sizeof(breakstack)/sizeof(breakstack[0]))
   
 /* These values are 4.4BSD dc compatible */  /* These values are 4.4BSD bc compatible */
 #define FUNC_CHAR       0x01  #define FUNC_CHAR       0x01
 #define ARRAY_CHAR      0xa1  #define ARRAY_CHAR      0xa1
   
 #define LETTER_NODE(str)        (cs(str_table[(int)str[0]]))  /* Skip '\0', [, \ and ] */
 #define ARRAY_NODE(str)         (cs(str_table[(int)str[0] - 'a' + ARRAY_CHAR]))  #define ENCODE(c)       ((c) < '[' ? (c) : (c) + 3);
 #define FUNCTION_NODE(str)      (cs(str_table[(int)str[0] - 'a' + FUNC_CHAR]))  #define VAR_BASE        (256-4)
   #define MAX_VARIABLES   (VAR_BASE * VAR_BASE)
   
 %}  %}
   
Line 113 
Line 121 
         ssize_t         node;          ssize_t         node;
         struct lvalue   lvalue;          struct lvalue   lvalue;
         const char      *str;          const char      *str;
           char            *astr;
 }  }
   
 %token COMMA SEMICOLON LPAR RPAR LBRACE RBRACE LBRACKET RBRACKET DOT  %token COMMA SEMICOLON LPAR RPAR LBRACE RBRACE LBRACKET RBRACKET DOT
 %token NEWLINE  %token NEWLINE
 %token <str> LETTER NUMBER STRING  %token <astr> LETTER
   %token <str> NUMBER STRING
 %token DEFINE BREAK QUIT LENGTH  %token DEFINE BREAK QUIT LENGTH
 %token RETURN FOR IF WHILE SQRT  %token RETURN FOR IF WHILE SQRT
 %token SCALE IBASE OBASE AUTO  %token SCALE IBASE OBASE AUTO
Line 156 
Line 166 
 %%  %%
   
 program         : /* empty */  program         : /* empty */
                         {                  | program input_item
                                 putchar('q');  
                                 fflush(stdout);  
                                 exit(0);  
                         }  
                 | input_item program  
                 ;                  ;
   
 input_item      : semicolon_list NEWLINE  input_item      : semicolon_list NEWLINE
Line 342 
Line 347 
                                         macro_char = '{';                                          macro_char = '{';
                                 else if (macro_char == ARRAY_CHAR)                                  else if (macro_char == ARRAY_CHAR)
                                         macro_char += 26;                                          macro_char += 26;
                                 else if (macro_char == 256)                                  else if (macro_char == 255)
                                         fatal("program too big");                                          fatal("program too big");
                                 if (breaksp == BREAKSTACK_SZ)                                  if (breaksp == BREAKSTACK_SZ)
                                         fatal("nesting too deep");                                          fatal("nesting too deep");
Line 372 
Line 377 
   
 function_header : DEFINE LETTER LPAR  function_header : DEFINE LETTER LPAR
                         {                          {
                                 $$ = FUNCTION_NODE($2);                                  $$ = function_node($2);
                                   free($2);
                                 prologue = cs("");                                  prologue = cs("");
                                 epilogue = cs("");                                  epilogue = cs("");
                                 nesting = 1;                                  nesting = 1;
Line 393 
Line 399 
   
 parameter_list  : LETTER  parameter_list  : LETTER
                         {                          {
                                 add_par(LETTER_NODE($1));                                  add_par(letter_node($1));
                                   free($1);
                         }                          }
                 | LETTER LBRACKET RBRACKET                  | LETTER LBRACKET RBRACKET
                         {                          {
                                 add_par(ARRAY_NODE($1));                                  add_par(array_node($1));
                                   free($1);
                         }                          }
                 | parameter_list COMMA LETTER                  | parameter_list COMMA LETTER
                         {                          {
                                 add_par(LETTER_NODE($3));                                  add_par(letter_node($3));
                                   free($3);
                         }                          }
                 | parameter_list COMMA LETTER LBRACKET RBRACKET                  | parameter_list COMMA LETTER LBRACKET RBRACKET
                         {                          {
                                 add_par(ARRAY_NODE($3));                                  add_par(array_node($3));
                                   free($3);
                         }                          }
                 ;                  ;
   
Line 420 
Line 430 
   
 define_list     : LETTER  define_list     : LETTER
                         {                          {
                                 add_local(LETTER_NODE($1));                                  add_local(letter_node($1));
                                   free($1);
                         }                          }
                 | LETTER LBRACKET RBRACKET                  | LETTER LBRACKET RBRACKET
                         {                          {
                                 add_local(ARRAY_NODE($1));                                  add_local(array_node($1));
                                   free($1);
                         }                          }
                 | define_list COMMA LETTER                  | define_list COMMA LETTER
                         {                          {
                                 add_local(LETTER_NODE($3));                                  add_local(letter_node($3));
                                   free($3);
                         }                          }
                 | define_list COMMA LETTER LBRACKET RBRACKET                  | define_list COMMA LETTER LBRACKET RBRACKET
                         {                          {
                                 add_local(ARRAY_NODE($3));                                  add_local(array_node($3));
                                   free($3);
                         }                          }
                 ;                  ;
   
Line 453 
Line 467 
                         }                          }
                 | argument_list COMMA LETTER LBRACKET RBRACKET                  | argument_list COMMA LETTER LBRACKET RBRACKET
                         {                          {
                                 $$ = node($1, cs("l"), ARRAY_NODE($3),                                  $$ = node($1, cs("l"), array_node($3),
                                     END_NODE);                                      END_NODE);
                                   free($3);
                         }                          }
                 ;                  ;
   
Line 542 
Line 557 
                 | LETTER LPAR opt_argument_list RPAR                  | LETTER LPAR opt_argument_list RPAR
                         {                          {
                                 $$ = node($3, cs("l"),                                  $$ = node($3, cs("l"),
                                     FUNCTION_NODE($1), cs("x"),                                      function_node($1), cs("x"),
                                     END_NODE);                                      END_NODE);
                                   free($1);
                         }                          }
                 | MINUS expression %prec UMINUS                  | MINUS expression %prec UMINUS
                         {                          {
Line 660 
Line 676 
 named_expression  named_expression
                 : LETTER                  : LETTER
                         {                          {
                                 $$.load = node(cs("l"), LETTER_NODE($1),                                  $$.load = node(cs("l"), letter_node($1),
                                     END_NODE);                                      END_NODE);
                                 $$.store = node(cs("s"), LETTER_NODE($1),                                  $$.store = node(cs("s"), letter_node($1),
                                     END_NODE);                                      END_NODE);
                                   free($1);
                         }                          }
                 | LETTER LBRACKET expression RBRACKET                  | LETTER LBRACKET expression RBRACKET
                         {                          {
                                 $$.load = node($3, cs(";"),                                  $$.load = node($3, cs(";"),
                                     ARRAY_NODE($1), END_NODE);                                      array_node($1), END_NODE);
                                 $$.store = node($3, cs(":"),                                  $$.store = node($3, cs(":"),
                                     ARRAY_NODE($1), END_NODE);                                      array_node($1), END_NODE);
                                   free($1);
                         }                          }
                 | SCALE                  | SCALE
                         {                          {
Line 810 
Line 828 
         else if (num < 16)          else if (num < 16)
                 p = str_table['A' - 10 + num];                  p = str_table['A' - 10 + num];
         else          else
                 err(1, "internal error: break num > 15");                  errx(1, "internal error: break num > 15");
         return node(cs(" "), cs(p), END_NODE);          return node(cs(" "), cs(p), END_NODE);
 }  }
   
   
   static ssize_t
   lookup(char * str, size_t len, char type)
   {
           ENTRY   entry, *found;
           u_short num;
           u_char  *p;
   
           /* The scanner allocated an extra byte already */
           if (str[len-1] != type) {
                   str[len] = type;
                   str[len+1] = '\0';
           }
           entry.key = str;
           found = hsearch(entry, FIND);
           if (found == NULL) {
                   if (var_count == MAX_VARIABLES)
                           errx(1, "too many variables");
                   p = malloc(4);
                   if (p == NULL)
                           err(1, NULL);
                   num = var_count++;
                   p[0] = 255;
                   p[1] = ENCODE(num / VAR_BASE + 1);
                   p[2] = ENCODE(num % VAR_BASE + 1);
                   p[3] = '\0';
   
                   entry.data = p;
                   entry.key = strdup(str);
                   if (entry.key == NULL)
                           err(1, NULL);
                   found = hsearch(entry, ENTER);
                   if (found == NULL)
                           err(1, NULL);
           }
           return cs(found->data);
   }
   
   static ssize_t
   letter_node(char *str)
   {
           size_t len;
   
           len = strlen(str);
           if (len == 1 && str[0] != '_')
                   return cs(str_table[(int)str[0]]);
           else
                   return lookup(str, len, 'L');
   }
   
   static ssize_t
   array_node(char *str)
   {
           size_t len;
   
           len = strlen(str);
           if (len == 1 && str[0] != '_')
                   return cs(str_table[(int)str[0] - 'a' + ARRAY_CHAR]);
           else
                   return lookup(str, len, 'A');
   }
   
   static ssize_t
   function_node(char *str)
   {
           size_t len;
   
           len = strlen(str);
           if (len == 1 && str[0] != '_')
                   return cs(str_table[(int)str[0] - 'a' + FUNC_CHAR]);
           else
                   return lookup(str, len, 'F');
   }
   
 static void  static void
 add_par(ssize_t n)  add_par(ssize_t n)
 {  {
Line 893 
Line 985 
                 str_table[i][0] = i;                  str_table[i][0] = i;
                 str_table[i][1] = '\0';                  str_table[i][1] = '\0';
         }          }
           if (hcreate(1 << 16) == 0)
                   err(1, NULL);
 }  }
   
   
Line 1003 
Line 1097 
                         dup(p[0]);                          dup(p[0]);
                         close(p[0]);                          close(p[0]);
                         close(p[1]);                          close(p[1]);
                         execl(_PATH_DC, "dc", "-", (char *)NULL);                          execl(_PATH_DC, "dc", "-x", (char *)NULL);
                         err(1, "cannot find dc");                          err(1, "cannot find dc");
                 }                  }
         }          }

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.20