* parse.c (write_dollar_variable): New function.
authorPer Bothner <per@bothner.com>
Thu, 5 Oct 1995 22:15:49 +0000 (22:15 +0000)
committerPer Bothner <per@bothner.com>
Thu, 5 Oct 1995 22:15:49 +0000 (22:15 +0000)
* c-exp.y (yylex):  Replace code for recognizing '$' pseudo-variables
with a call to write_dollar_variable.
Simplify grammar correspondingly.
* f-exp.y:  Likewise.
* m2-exp.y:  Likewise.
* ch-exp.y:  Likewise.  (Remove function match_dollar_tokens.)
* scm-exp.c (scm_lreadr):  Call write_dollar_variable to handle '$'.

gdb/ChangeLog
gdb/c-exp.y
gdb/ch-exp.y
gdb/f-exp.y
gdb/m2-exp.y
gdb/parse.c
gdb/scm-exp.c

index 76ed885..8e203d7 100644 (file)
@@ -1,3 +1,14 @@
+Thu Oct  5 15:14:36 1995  Per Bothner  <bothner@kalessin.cygnus.com>
+
+       * parse.c (write_dollar_variable):  New function.
+       * c-exp.y (yylex):  Replace code for recognizing '$' pseudo-variables
+       with a call to write_dollar_variable.
+       Simplify grammar correspondingly.
+       * f-exp.y:  Likewise.
+       * m2-exp.y:  Likewise.
+       * ch-exp.y:  Likewise.  (Remove function match_dollar_tokens.)
+       * scm-exp.c (scm_lreadr):  Call write_dollar_variable to handle '$'.
+
 Thu Oct  5 13:27:30 1995  steve chamberlain  <sac@slash.cygnus.com>
 
        * win32.c: New file; support for debugging on windows NT.
index 30ab99e..eae0794 100644 (file)
@@ -184,9 +184,8 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
 /* Special type cases, put in to allow the parser to distinguish different
    legal basetypes.  */
 %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD
-%token <lval> LAST REGNAME
 
-%token <ivar> VARIABLE
+%token <voidval> VARIABLE
 
 %token <opcode> ASSIGN_MODIFY
 
@@ -482,22 +481,8 @@ exp        :       FLOAT
 exp    :       variable
        ;
 
-exp    :       LAST
-                       { write_exp_elt_opcode (OP_LAST);
-                         write_exp_elt_longcst ((LONGEST) $1);
-                         write_exp_elt_opcode (OP_LAST); }
-       ;
-
-exp    :       REGNAME
-                       { write_exp_elt_opcode (OP_REGISTER);
-                         write_exp_elt_longcst ((LONGEST) $1);
-                         write_exp_elt_opcode (OP_REGISTER); }
-       ;
-
 exp    :       VARIABLE
-                       { write_exp_elt_opcode (OP_INTERNALVAR);
-                         write_exp_elt_intern ($1);
-                         write_exp_elt_opcode (OP_INTERNALVAR); }
+                       /* Already written by write_dollar_variable. */
        ;
 
 exp    :       SIZEOF '(' type ')'     %prec UNARY
@@ -1393,60 +1378,8 @@ yylex ()
 
   lexptr += namelen;
 
-  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
-     and $$digits (equivalent to $<-digits> if you could type that).
-     Make token type LAST, and put the number (the digits) in yylval.  */
-
   tryname:
-  if (*tokstart == '$')
-    {
-      register int negate = 0;
-      c = 1;
-      /* Double dollar means negate the number and add -1 as well.
-        Thus $$ alone means -1.  */
-      if (namelen >= 2 && tokstart[1] == '$')
-       {
-         negate = 1;
-         c = 2;
-       }
-      if (c == namelen)
-       {
-         /* Just dollars (one or two) */
-         yylval.lval = - negate;
-         return LAST;
-       }
-      /* Is the rest of the token digits?  */
-      for (; c < namelen; c++)
-       if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))
-         break;
-      if (c == namelen)
-       {
-         yylval.lval = atoi (tokstart + 1 + negate);
-         if (negate)
-           yylval.lval = - yylval.lval;
-         return LAST;
-       }
-    }
-
-  /* Handle tokens that refer to machine registers:
-     $ followed by a register name.  */
 
-  if (*tokstart == '$') {
-    for (c = 0; c < NUM_REGS; c++)
-      if (namelen - 1 == strlen (reg_names[c])
-         && STREQN (tokstart + 1, reg_names[c], namelen - 1))
-       {
-         yylval.lval = c;
-         return REGNAME;
-       }
-    for (c = 0; c < num_std_regs; c++)
-     if (namelen - 1 == strlen (std_regs[c].name)
-        && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
-       {
-        yylval.lval = std_regs[c].regnum;
-        return REGNAME;
-       }
-  }
   /* Catch specific keywords.  Should be done with a data structure.  */
   switch (namelen)
     {
@@ -1506,11 +1439,9 @@ yylex ()
   yylval.sval.ptr = tokstart;
   yylval.sval.length = namelen;
 
-  /* Any other names starting in $ are debugger internal variables.  */
-
   if (*tokstart == '$')
     {
-      yylval.ivar =  lookup_internalvar (copy_name (yylval.sval) + 1);
+      write_dollar_variable (yylval.sval);
       return VARIABLE;
     }
 
index f8e9717..87137c8 100644 (file)
@@ -225,9 +225,7 @@ yyerror PARAMS ((char *));
    specific things that we recognize in the same context as Chill tokens
    (register names for example). */
 
-%token <lval>          GDB_REGNAME     /* Machine register name */
-%token <lval>          GDB_LAST        /* Value history */
-%token <ivar>          GDB_VARIABLE    /* Convenience variable */
+%token <voidval>       GDB_VARIABLE    /* Convenience variable */
 %token <voidval>       GDB_ASSIGNMENT  /* Assign value to somewhere */
 
 %type <voidval>                access_name
@@ -291,24 +289,7 @@ access_name        :       LOCATION_NAME
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
-               |       GDB_LAST                /* gdb specific */
-                       {
-                         write_exp_elt_opcode (OP_LAST);
-                         write_exp_elt_longcst ($1);
-                         write_exp_elt_opcode (OP_LAST); 
-                       }
-               |       GDB_REGNAME             /* gdb specific */
-                       {
-                         write_exp_elt_opcode (OP_REGISTER);
-                         write_exp_elt_longcst ($1);
-                         write_exp_elt_opcode (OP_REGISTER); 
-                       }
                |       GDB_VARIABLE    /* gdb specific */
-                       {
-                         write_exp_elt_opcode (OP_INTERNALVAR);
-                         write_exp_elt_intern ($1);
-                         write_exp_elt_opcode (OP_INTERNALVAR); 
-                       }
                ;
 
 /* Z.200, 4.2.8 */
@@ -1382,131 +1363,6 @@ match_bitstring_literal ()
     }
 }
 
-/* Recognize tokens that start with '$'.  These include:
-
-       $regname        A native register name or a "standard
-                       register name".
-                       Return token GDB_REGNAME.
-
-       $variable       A convenience variable with a name chosen
-                       by the user.
-                       Return token GDB_VARIABLE.
-
-       $digits         Value history with index <digits>, starting
-                       from the first value which has index 1.
-                       Return GDB_LAST.
-
-       $$digits        Value history with index <digits> relative
-                       to the last value.  I.E. $$0 is the last
-                       value, $$1 is the one previous to that, $$2
-                       is the one previous to $$1, etc.
-                       Return token GDB_LAST.
-
-       $ | $0 | $$0    The last value in the value history.
-                       Return token GDB_LAST.
-
-       $$              An abbreviation for the second to the last
-                       value in the value history, I.E. $$1
-                       Return token GDB_LAST.
-
-    Note that we currently assume that register names and convenience
-    variables follow the convention of starting with a letter or '_'.
-
-   */
-
-static int
-match_dollar_tokens ()
-{
-  char *tokptr;
-  int regno;
-  int namelength;
-  int negate;
-  int ival;
-
-  /* We will always have a successful match, even if it is just for
-     a single '$', the abbreviation for $$0.  So advance lexptr. */
-
-  tokptr = ++lexptr;
-
-  if (*tokptr == '_' || isalpha (*tokptr))
-    {
-      /* Look for a match with a native register name, usually something
-        like "r0" for example. */
-
-      for (regno = 0; regno < NUM_REGS; regno++)
-       {
-         namelength = strlen (reg_names[regno]);
-         if (STREQN (tokptr, reg_names[regno], namelength)
-             && !isalnum (tokptr[namelength]))
-           {
-             yylval.lval = regno;
-             lexptr += namelength;
-             return (GDB_REGNAME);
-           }
-       }
-
-      /* Look for a match with a standard register name, usually something
-        like "pc", which gdb always recognizes as the program counter
-        regardless of what the native register name is. */
-
-      for (regno = 0; regno < num_std_regs; regno++)
-       {
-         namelength = strlen (std_regs[regno].name);
-         if (STREQN (tokptr, std_regs[regno].name, namelength)
-             && !isalnum (tokptr[namelength]))
-           {
-             yylval.lval = std_regs[regno].regnum;
-             lexptr += namelength;
-             return (GDB_REGNAME);
-           }
-       }
-
-      /* Attempt to match against a convenience variable.  Note that
-        this will always succeed, because if no variable of that name
-        already exists, the lookup_internalvar will create one for us.
-        Also note that both lexptr and tokptr currently point to the
-        start of the input string we are trying to match, and that we
-        have already tested the first character for non-numeric, so we
-        don't have to treat it specially. */
-
-      while (*tokptr == '_' || isalnum (*tokptr))
-       {
-         tokptr++;
-       }
-      yylval.sval.ptr = lexptr;
-      yylval.sval.length = tokptr - lexptr;
-      yylval.ivar = lookup_internalvar (copy_name (yylval.sval));
-      lexptr = tokptr;
-      return (GDB_VARIABLE);
-    }
-
-  /* Since we didn't match against a register name or convenience
-     variable, our only choice left is a history value. */
-
-  if (*tokptr == '$')
-    {
-      negate = 1;
-      ival = 1;
-      tokptr++;
-    }
-  else
-    {
-      negate = 0;
-      ival = 0;
-    }
-
-  /* Attempt to decode more characters as an integer value giving
-     the index in the history list.  If successful, the value will
-     overwrite ival (currently 0 or 1), and if not, ival will be
-     left alone, which is good since it is currently correct for
-     the '$' or '$$' case. */
-
-  decode_integer_literal (&ival, &tokptr);
-  yylval.lval = negate ? -ival : ival;
-  lexptr = tokptr;
-  return (GDB_LAST);
-}
-
 struct token
 {
   char *operator;
@@ -1620,11 +1476,13 @@ yylex ()
            }
          break;
        case '$':
-         token = match_dollar_tokens ();
-         if (token != 0)
-           {
-             return (token);
-           }
+         yylval.sval.ptr = lexptr;
+         do {
+           lexptr++;
+         } while (isalnum (*lexptr) || (lexptr == '_'));
+         yylval.sval.length = lexptr - yylval.sval.ptr;
+         write_dollar_variable (yylval.sval);
+         return GDB_VARIABLE;
          break;
       }
     /* See if it is a special token of length 2.  */
index 4dd238c..ee97015 100644 (file)
@@ -186,9 +186,9 @@ static int parse_number PARAMS ((char *, int, int, YYSTYPE *));
 %token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD 
 %token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD 
 %token BOOL_AND BOOL_OR BOOL_NOT   
-%token <lval> LAST REGNAME CHARACTER 
+%token <lval> CHARACTER 
 
-%token <ivar> VARIABLE
+%token <voidval> VARIABLE
 
 %token <opcode> ASSIGN_MODIFY
 
@@ -412,22 +412,7 @@ exp        :       FLOAT
 exp    :       variable
        ;
 
-exp    :       LAST
-                       { write_exp_elt_opcode (OP_LAST);
-                         write_exp_elt_longcst ((LONGEST) $1);
-                         write_exp_elt_opcode (OP_LAST); }
-       ;
-
-exp    :       REGNAME
-                       { write_exp_elt_opcode (OP_REGISTER);
-                         write_exp_elt_longcst ((LONGEST) $1);
-                         write_exp_elt_opcode (OP_REGISTER); }
-       ;
-
 exp    :       VARIABLE
-                       { write_exp_elt_opcode (OP_INTERNALVAR);
-                         write_exp_elt_intern ($1);
-                         write_exp_elt_opcode (OP_INTERNALVAR); }
        ;
 
 exp    :       SIZEOF '(' type ')'     %prec UNARY
@@ -1110,60 +1095,6 @@ yylex ()
   
   lexptr += namelen;
   
-  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
-     and $$digits (equivalent to $<-digits> if you could type that).
-     Make token type LAST, and put the number (the digits) in yylval.  */
-  
-  if (*tokstart == '$')
-    {
-      register int negate = 0;
-
-      c = 1;
-      /* Double dollar means negate the number and add -1 as well.
-        Thus $$ alone means -1.  */
-      if (namelen >= 2 && tokstart[1] == '$')
-       {
-         negate = 1;
-         c = 2;
-       }
-      if (c == namelen)
-       {
-         /* Just dollars (one or two) */
-         yylval.lval = - negate;
-         return LAST;
-       }
-      /* Is the rest of the token digits?  */
-      for (; c < namelen; c++)
-       if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))
-         break;
-      if (c == namelen)
-       {
-         yylval.lval = atoi (tokstart + 1 + negate);
-         if (negate)
-           yylval.lval = - yylval.lval;
-         return LAST;
-       }
-    }
-  
-  /* Handle tokens that refer to machine registers:
-     $ followed by a register name.  */
-  
-  if (*tokstart == '$') {
-    for (c = 0; c < NUM_REGS; c++)
-      if (namelen - 1 == strlen (reg_names[c])
-         && STREQN (tokstart + 1, reg_names[c], namelen - 1))
-       {
-         yylval.lval = c;
-         return REGNAME;
-       }
-    for (c = 0; c < num_std_regs; c++)
-      if (namelen - 1 == strlen (std_regs[c].name)
-         && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
-       {
-         yylval.lval = std_regs[c].regnum;
-         return REGNAME;
-       }
-  }
   /* Catch specific keywords.  */
   
   for (i = 0; f77_keywords[i].operator != NULL; i++)
@@ -1178,11 +1109,9 @@ yylex ()
   yylval.sval.ptr = tokstart;
   yylval.sval.length = namelen;
   
-  /* Any other names starting in $ are debugger internal variables.  */
-  
   if (*tokstart == '$')
     {
-      yylval.ivar =  lookup_internalvar (copy_name (yylval.sval) + 1);
+      write_dollar_variable (yylval.sval);
       return VARIABLE;
     }
   
index efcaab8..9ec896f 100644 (file)
@@ -178,9 +178,7 @@ static struct block *modblock=0;
 /* The GDB scope operator */
 %token COLONCOLON
 
-%token <lval> LAST REGNAME
-
-%token <ivar> INTERNAL_VAR
+%token <voidval> INTERNAL_VAR
 
 /* M2 tokens */
 %left ','
@@ -519,19 +517,6 @@ exp        :       FLOAT
 exp    :       variable
        ;
 
-/* The GDB internal variable $$, et al. */
-exp    :       LAST
-                       { write_exp_elt_opcode (OP_LAST);
-                         write_exp_elt_longcst ((LONGEST) $1);
-                         write_exp_elt_opcode (OP_LAST); }
-       ;
-
-exp    :       REGNAME
-                       { write_exp_elt_opcode (OP_REGISTER);
-                         write_exp_elt_longcst ((LONGEST) $1);
-                         write_exp_elt_opcode (OP_REGISTER); }
-       ;
-
 exp    :       SIZE '(' type ')'       %prec UNARY
                        { write_exp_elt_opcode (OP_LONG);
                          write_exp_elt_type (builtin_type_int);
@@ -580,9 +565,6 @@ variable:   fblock
 
 /* GDB internal ($foo) variable */
 variable:      INTERNAL_VAR
-                       { write_exp_elt_opcode (OP_INTERNALVAR);
-                         write_exp_elt_intern ($1);
-                         write_exp_elt_opcode (OP_INTERNALVAR); }
        ;
 
 /* GDB scope operator */
@@ -1003,61 +985,6 @@ yylex ()
 
   lexptr += namelen;
 
-  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
-     and $$digits (equivalent to $<-digits> if you could type that).
-     Make token type LAST, and put the number (the digits) in yylval.  */
-
-  if (*tokstart == '$')
-    {
-      register int negate = 0;
-      c = 1;
-      /* Double dollar means negate the number and add -1 as well.
-        Thus $$ alone means -1.  */
-      if (namelen >= 2 && tokstart[1] == '$')
-       {
-         negate = 1;
-         c = 2;
-       }
-      if (c == namelen)
-       {
-         /* Just dollars (one or two) */
-         yylval.lval = - negate;
-         return LAST;
-       }
-      /* Is the rest of the token digits?  */
-      for (; c < namelen; c++)
-       if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))
-         break;
-      if (c == namelen)
-       {
-         yylval.lval = atoi (tokstart + 1 + negate);
-         if (negate)
-           yylval.lval = - yylval.lval;
-         return LAST;
-       }
-    }
-
-  /* Handle tokens that refer to machine registers:
-     $ followed by a register name.  */
-
-  if (*tokstart == '$') {
-    for (c = 0; c < NUM_REGS; c++)
-      if (namelen - 1 == strlen (reg_names[c])
-         && STREQN (tokstart + 1, reg_names[c], namelen - 1))
-       {
-         yylval.lval = c;
-         return REGNAME;
-       }
-    for (c = 0; c < num_std_regs; c++)
-     if (namelen - 1 == strlen (std_regs[c].name)
-        && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
-       {
-        yylval.lval = std_regs[c].regnum;
-        return REGNAME;
-       }
-  }
-
-
   /*  Lookup special keywords */
   for(i = 0 ; i < sizeof(keytab) / sizeof(keytab[0]) ; i++)
      if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen))
@@ -1066,15 +993,12 @@ yylex ()
   yylval.sval.ptr = tokstart;
   yylval.sval.length = namelen;
 
-  /* Any other names starting in $ are debugger internal variables.  */
-
   if (*tokstart == '$')
     {
-      yylval.ivar = (struct internalvar *) lookup_internalvar (copy_name (yylval.sval) + 1);
+      write_dollar_variable (yylval.sval);
       return INTERNAL_VAR;
     }
 
-
   /* Use token-type BLOCKNAME for symbols that happen to be defined as
      functions.  If this is not so, then ...
      Use token-type TYPENAME for symbols that happen to be defined
index fb8793f..7bbe0a8 100644 (file)
@@ -399,6 +399,97 @@ write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
   write_exp_elt_opcode (UNOP_MEMVAL);
 }
 \f
+/* Recognize tokens that start with '$'.  These include:
+
+       $regname        A native register name or a "standard
+                       register name".
+
+       $variable       A convenience variable with a name chosen
+                       by the user.
+
+       $digits         Value history with index <digits>, starting
+                       from the first value which has index 1.
+
+       $$digits        Value history with index <digits> relative
+                       to the last value.  I.E. $$0 is the last
+                       value, $$1 is the one previous to that, $$2
+                       is the one previous to $$1, etc.
+
+       $ | $0 | $$0    The last value in the value history.
+
+       $$              An abbreviation for the second to the last
+                       value in the value history, I.E. $$1
+
+   */
+
+void
+write_dollar_variable (str)
+     struct stoken str;
+{
+  /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+     and $$digits (equivalent to $<-digits> if you could type that). */
+
+  int negate = 0;
+  int i = 1;
+  /* Double dollar means negate the number and add -1 as well.
+     Thus $$ alone means -1.  */
+  if (str.length >= 2 && str.ptr[1] == '$')
+    {
+      negate = 1;
+      i = 2;
+    }
+  if (i == str.length)
+    {
+      /* Just dollars (one or two) */
+      i = - negate;
+      goto handle_last;
+    }
+  /* Is the rest of the token digits?  */
+  for (; i < str.length; i++)
+    if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9'))
+      break;
+  if (i == str.length)
+    {
+      i = atoi (str.ptr + 1 + negate);
+      if (negate)
+       i = - i;
+      goto handle_last;
+    }
+  
+  /* Handle tokens that refer to machine registers:
+     $ followed by a register name.  */
+  for (i = 0; i < NUM_REGS; i++)
+    if (str.length - 1 == strlen (reg_names[i])
+       && STREQN (str.ptr + 1, reg_names[i], str.length - 1))
+      {
+       goto handle_register;
+      }
+  for (i = 0; i < num_std_regs; i++)
+    if (str.length - 1 == strlen (std_regs[i].name)
+       && STREQN (str.ptr + 1, std_regs[i].name, str.length - 1))
+      {
+       i = std_regs[i].regnum;
+       goto handle_register;
+      }
+
+  /* Any other names starting in $ are debugger internal variables.  */
+
+  write_exp_elt_opcode (OP_INTERNALVAR);
+  write_exp_elt_intern (lookup_internalvar (copy_name (str) + 1));
+  write_exp_elt_opcode (OP_INTERNALVAR); 
+  return;
+ handle_last:
+  write_exp_elt_opcode (OP_LAST);
+  write_exp_elt_longcst ((LONGEST) i);
+  write_exp_elt_opcode (OP_LAST);
+  return;
+ handle_register:
+  write_exp_elt_opcode (OP_REGISTER);
+  write_exp_elt_longcst (i);
+  write_exp_elt_opcode (OP_REGISTER); 
+  return;
+}
+\f
 /* Return a null-terminated temporary copy of the name
    of a string token.  */
 
index 4c98d64..8df6803 100644 (file)
@@ -373,6 +373,11 @@ scm_lreadr (skipping)
       if (!skipping)
        {
          str.length = lexptr - str.ptr;
+         if (str.ptr[0] == '$')
+           {
+             write_dollar_variable (str);
+             return;
+           }
          write_exp_elt_opcode (OP_NAME);
          write_exp_string (str);
          write_exp_elt_opcode (OP_NAME);