* c-exp.y, m2-exp.y (yyreds, yytoks): Remap like other yy* names.
authorFred Fish <fnf@specifix.com>
Thu, 31 Dec 1992 04:05:05 +0000 (04:05 +0000)
committerFred Fish <fnf@specifix.com>
Thu, 31 Dec 1992 04:05:05 +0000 (04:05 +0000)
* c-exp.y, m2-exp.y (YYDEBUG):  Define if MAINTENANCE_CMDS is defined
and YYDEBUG is not already defined.
* c-exp.y (strncmp):  Replace throughout with STREQN, missed
them during the previous replacements.
* printcmd.c (_initialize_printcmd):  Update internal documentation
for "set" command to note that the assignment syntax is language
dependent.
**** start-sanitize-chill ****
* ch-exp.y (yyreds, yytoks):  Remap like other yy* names.
* ch-exp.y (YYDEBUG):  Define if MAINTENANCE_CMDS is defined
and YYDEBUG is not already defined.
* ch-exp.y (GDB_REGNAME, GDB_LAST, GDB_VARIABLE, GDB_ASSIGNMENT,
single_assignment_action): New terminals and nonterminal for gdb
extensions to chill expression grammer.
* ch-exp.y (match_dollar_tokens):  Lexer routine to match all
tokens that start with '$' (register names, convenience vars, etc).
* ch-exp.y (tokentab2):  Add GDB_ASSIGNMENT.
* ch-exp.y (yylex):  Call match_dollar_tokens.
**** end-sanitize-chill ****

gdb/ChangeLog
gdb/c-exp.y
gdb/ch-exp.y
gdb/m2-exp.y
gdb/printcmd.c

index 5d535a6..72c8e19 100644 (file)
@@ -1,3 +1,26 @@
+Wed Dec 30 19:47:13 1992  Fred Fish  (fnf@cygnus.com)
+
+       * c-exp.y, m2-exp.y (yyreds, yytoks):  Remap like other yy* names.
+       * c-exp.y, m2-exp.y (YYDEBUG):  Define if MAINTENANCE_CMDS is defined
+       and YYDEBUG is not already defined.
+       * c-exp.y (strncmp):  Replace throughout with STREQN, missed
+       them during the previous replacements.
+       * printcmd.c (_initialize_printcmd):  Update internal documentation
+       for "set" command to note that the assignment syntax is language
+       dependent.
+       **** start-sanitize-chill ****
+       * ch-exp.y (yyreds, yytoks):  Remap like other yy* names.
+       * ch-exp.y (YYDEBUG):  Define if MAINTENANCE_CMDS is defined
+       and YYDEBUG is not already defined.
+       * ch-exp.y (GDB_REGNAME, GDB_LAST, GDB_VARIABLE, GDB_ASSIGNMENT,
+       single_assignment_action): New terminals and nonterminal for gdb
+       extensions to chill expression grammer.
+       * ch-exp.y (match_dollar_tokens):  Lexer routine to match all
+       tokens that start with '$' (register names, convenience vars, etc).
+       * ch-exp.y (tokentab2):  Add GDB_ASSIGNMENT.
+       * ch-exp.y (yylex):  Call match_dollar_tokens.
+       **** end-sanitize-chill ****
+
 Mon Dec 28 15:00:01 1992  Stu Grossman  (grossman at cygnus.com)
 
        * hppah-tdep.c (skip_trampoline_code):  Use new macros for
index 1129cf6..b77200e 100644 (file)
@@ -73,6 +73,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yy_yyv  c_yyv
 #define        yyval   c_val
 #define        yylloc  c_lloc
+#define yyreds c_reds          /* With YYDEBUG defined */
+#define yytoks c_toks          /* With YYDEBUG defined */
 #define yyss   c_yyss          /* byacc */
 #define        yyssp   c_yysp          /* byacc */
 #define        yyvs    c_yyvs          /* byacc */
@@ -87,7 +89,9 @@ yylex PARAMS ((void));
 void
 yyerror PARAMS ((char *));
 
-/* #define     YYDEBUG 1 */
+#if MAINTENANCE_CMDS
+#define        YYDEBUG 1
+#endif
 
 %}
 
@@ -1094,7 +1098,7 @@ yylex ()
   tokstart = lexptr;
   /* See if it is a special token of length 3.  */
   for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (!strncmp (tokstart, tokentab3[i].operator, 3))
+    if (STREQN (tokstart, tokentab3[i].operator, 3))
       {
        lexptr += 3;
        yylval.opcode = tokentab3[i].opcode;
@@ -1103,7 +1107,7 @@ yylex ()
 
   /* See if it is a special token of length 2.  */
   for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (!strncmp (tokstart, tokentab2[i].operator, 2))
+    if (STREQN (tokstart, tokentab2[i].operator, 2))
       {
        lexptr += 2;
        yylval.opcode = tokentab2[i].opcode;
@@ -1369,14 +1373,14 @@ yylex ()
   if (*tokstart == '$') {
     for (c = 0; c < NUM_REGS; c++)
       if (namelen - 1 == strlen (reg_names[c])
-         && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
+         && 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)
-        && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
+        && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
        {
         yylval.lval = std_regs[c].regnum;
         return REGNAME;
@@ -1386,40 +1390,40 @@ yylex ()
   switch (namelen)
     {
     case 8:
-      if (!strncmp (tokstart, "unsigned", 8))
+      if (STREQN (tokstart, "unsigned", 8))
        return UNSIGNED;
       if (current_language->la_language == language_cplus
-         && !strncmp (tokstart, "template", 8))
+         && STREQN (tokstart, "template", 8))
        return TEMPLATE;
-      if (!strncmp (tokstart, "volatile", 8))
+      if (STREQN (tokstart, "volatile", 8))
        return VOLATILE_KEYWORD;
       break;
     case 6:
-      if (!strncmp (tokstart, "struct", 6))
+      if (STREQN (tokstart, "struct", 6))
        return STRUCT;
-      if (!strncmp (tokstart, "signed", 6))
+      if (STREQN (tokstart, "signed", 6))
        return SIGNED_KEYWORD;
-      if (!strncmp (tokstart, "sizeof", 6))      
+      if (STREQN (tokstart, "sizeof", 6))      
        return SIZEOF;
       break;
     case 5:
       if (current_language->la_language == language_cplus
-         && !strncmp (tokstart, "class", 5))
+         && STREQN (tokstart, "class", 5))
        return CLASS;
-      if (!strncmp (tokstart, "union", 5))
+      if (STREQN (tokstart, "union", 5))
        return UNION;
-      if (!strncmp (tokstart, "short", 5))
+      if (STREQN (tokstart, "short", 5))
        return SHORT;
-      if (!strncmp (tokstart, "const", 5))
+      if (STREQN (tokstart, "const", 5))
        return CONST_KEYWORD;
       break;
     case 4:
-      if (!strncmp (tokstart, "enum", 4))
+      if (STREQN (tokstart, "enum", 4))
        return ENUM;
-      if (!strncmp (tokstart, "long", 4))
+      if (STREQN (tokstart, "long", 4))
        return LONG;
       if (current_language->la_language == language_cplus
-         && !strncmp (tokstart, "this", 4))
+         && STREQN (tokstart, "this", 4))
        {
          static const char this_name[] =
                                 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
@@ -1430,7 +1434,7 @@ yylex ()
        }
       break;
     case 3:
-      if (!strncmp (tokstart, "int", 3))
+      if (STREQN (tokstart, "int", 3))
        return INT_KEYWORD;
       break;
     default:
index 141463d..2f6376a 100644 (file)
@@ -90,6 +90,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yy_yyv  chill_yyv
 #define        yyval   chill_val
 #define        yylloc  chill_lloc
+#define yyreds chill_reds              /* With YYDEBUG defined */
+#define yytoks chill_toks              /* With YYDEBUG defined */
 #define yyss   chill_yyss              /* byacc */
 #define        yyssp   chill_yysp              /* byacc */
 #define        yyvs    chill_yyvs              /* byacc */
@@ -104,7 +106,9 @@ yyerror PARAMS ((char *));
 int
 yyparse PARAMS ((void));
 
-/* #define     YYDEBUG 1 */
+#if MAINTENANCE_CMDS
+#define        YYDEBUG 1
+#endif
 
 %}
 
@@ -190,6 +194,15 @@ yyparse PARAMS ((void));
 %token <voidval>       ELSIF
 %token <voidval>       ILLEGAL_TOKEN
 
+/* Tokens which are not Chill tokens used in expressions, but rather GDB
+   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_ASSIGNMENT  /* Assign value to somewhere */
+
 %type <voidval>                location
 %type <voidval>                access_name
 %type <voidval>                primitive_value
@@ -247,6 +260,8 @@ yyparse PARAMS ((void));
 %type <voidval>                case_label_specification
 %type <voidval>                buffer_location
 
+%type <voidval>                single_assignment_action
+
 %%
 
 /* Z.200, 5.3.1 */
@@ -287,6 +302,24 @@ 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); 
+                       }
                |       FIXME
                        {
                          $$ = 0;       /* FIXME */
@@ -604,6 +637,10 @@ operand_0  :       operand_1
                        {
                          write_exp_elt_opcode (BINOP_BITWISE_XOR);
                        }
+               |       single_assignment_action
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
                ;
 
 /* Z.200, 5.3.4 */
@@ -740,6 +777,13 @@ operand_6  :       POINTER location
                ;
 
 
+/* Z.200, 6.2 */
+
+single_assignment_action :     location GDB_ASSIGNMENT value
+                       {
+                         write_exp_elt_opcode (BINOP_ASSIGN);
+                       }
+
 /* Z.200, 12.4.3 */
 /* FIXME:  For now we just accept only a single integer literal. */
 
@@ -1036,6 +1080,131 @@ match_integer_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 + 1;
+             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);
+}
+
 #if 0
 static void convert_float ()
 {
@@ -1103,6 +1272,7 @@ static const struct token tokentab3[] =
 
 static const struct token tokentab2[] =
 {
+    { ":=", GDB_ASSIGNMENT },
     { "//", SLASH_SLASH },
     { "/=", NOTEQUAL },
     { "<=", LEQ },
@@ -1136,7 +1306,6 @@ yylex ()
                return (0);
            case '.':
            case '=':
-           case ':':
            case ';':
            case '!':
            case '+':
@@ -1150,7 +1319,8 @@ yylex ()
                return (*lexptr++);
        }
     /* Look for characters which start a particular kind of multicharacter
-       token, such as a character literal. */
+       token, such as a character literal, register name, convenience
+       variable name, etc. */
     switch (*lexptr)
       {
         case 'C':
@@ -1162,11 +1332,18 @@ yylex ()
              return (token);
            }
          break;
+       case '$':
+         token = match_dollar_tokens ();
+         if (token != 0)
+           {
+             return (token);
+           }
+         break;
       }
     /* See if it is a special token of length 5.  */
     for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++)
        {
-           if (strncmp (lexptr, tokentab5[i].operator, 5) == 0)
+           if (STREQN (lexptr, tokentab5[i].operator, 5))
                {
                    lexptr += 5;
                    return (tokentab5[i].token);
@@ -1175,7 +1352,7 @@ yylex ()
     /* See if it is a special token of length 4.  */
     for (i = 0; i < sizeof (tokentab4) / sizeof (tokentab4[0]); i++)
        {
-           if (strncmp (lexptr, tokentab4[i].operator, 4) == 0)
+           if (STREQN (lexptr, tokentab4[i].operator, 4))
                {
                    lexptr += 4;
                    return (tokentab4[i].token);
@@ -1184,7 +1361,7 @@ yylex ()
     /* See if it is a special token of length 3.  */
     for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
        {
-           if (strncmp (lexptr, tokentab3[i].operator, 3) == 0)
+           if (STREQN (lexptr, tokentab3[i].operator, 3))
                {
                    lexptr += 3;
                    return (tokentab3[i].token);
@@ -1193,7 +1370,7 @@ yylex ()
     /* See if it is a special token of length 2.  */
     for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
        {
-           if (strncmp (lexptr, tokentab2[i].operator, 2) == 0)
+           if (STREQN (lexptr, tokentab2[i].operator, 2))
                {
                    lexptr += 2;
                    return (tokentab2[i].token);
@@ -1204,19 +1381,20 @@ yylex ()
        would already have found it. */
     switch (*lexptr)
        {
+           case ':':
            case '/':
            case '<':
            case '>':
                return (*lexptr++);
        }
     /* Look for other special tokens. */
-    if (strncmp (lexptr, "TRUE", 4) == 0) /* FIXME:  What about lowercase? */
+    if (STREQN (lexptr, "TRUE", 4)) /* FIXME:  What about lowercase? */
        {
            yylval.ulval = 1;
            lexptr += 4;
            return (BOOLEAN_LITERAL);
        }
-    if (strncmp (lexptr, "FALSE", 5) == 0) /* FIXME:  What about lowercase? */
+    if (STREQN (lexptr, "FALSE", 5)) /* FIXME:  What about lowercase? */
        {
            yylval.ulval = 0;
            lexptr += 5;
index 037a074..2bee738 100644 (file)
@@ -75,6 +75,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yy_yyv  m2_yyv
 #define        yyval   m2_val
 #define        yylloc  m2_lloc
+#define yyreds m2_reds         /* With YYDEBUG defined */
+#define yytoks m2_toks         /* With YYDEBUG defined */
 #define yyss   m2_yyss         /* byacc */
 #define        yyssp   m2_yysp         /* byacc */
 #define        yyvs    m2_yyvs         /* byacc */
@@ -106,7 +108,10 @@ static int number_sign = 1;
 static struct block *modblock=0;
 #endif
 
-/* #define     YYDEBUG 1 */
+#if MAINTENANCE_CMDS
+#define        YYDEBUG 1
+#endif
+
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -848,7 +853,7 @@ yylex ()
 
   /* See if it is a special token of length 2 */
   for( i = 0 ; i < sizeof tokentab2 / sizeof tokentab2[0] ; i++)
-     if(!strncmp(tokentab2[i].name, tokstart, 2))
+     if(STREQN(tokentab2[i].name, tokstart, 2))
      {
        lexptr += 2;
        return tokentab2[i].token;
@@ -1043,14 +1048,14 @@ yylex ()
   if (*tokstart == '$') {
     for (c = 0; c < NUM_REGS; c++)
       if (namelen - 1 == strlen (reg_names[c])
-         && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
+         && 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)
-        && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
+        && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
        {
         yylval.lval = std_regs[c].regnum;
         return REGNAME;
@@ -1060,7 +1065,7 @@ yylex ()
 
   /*  Lookup special keywords */
   for(i = 0 ; i < sizeof(keytab) / sizeof(keytab[0]) ; i++)
-     if(namelen == strlen(keytab[i].keyw) && !strncmp(tokstart,keytab[i].keyw,namelen))
+     if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen))
           return keytab[i].token;
 
   yylval.sval.ptr = tokstart;
@@ -1126,12 +1131,12 @@ yylex ()
     else
     {
        /* Built-in BOOLEAN type.  This is sort of a hack. */
-       if(!strncmp(tokstart,"TRUE",4))
+       if(STREQN(tokstart,"TRUE",4))
        {
          yylval.ulval = 1;
          return M2_TRUE;
        }
-       else if(!strncmp(tokstart,"FALSE",5))
+       else if(STREQN(tokstart,"FALSE",5))
        {
          yylval.ulval = 0;
          return M2_FALSE;
index aecd57c..d8bc20f 100644 (file)
@@ -1960,10 +1960,11 @@ This is useful for formatted output in user-defined commands.");
 This is useful in user-defined commands.");
 
   add_prefix_cmd ("set", class_vars, set_command,
-"Perform an assignment VAR = EXP.\n\
-You must type the \"=\".  VAR may be a debugger \"convenience\" variable\n\
-(names starting with $), a register (a few standard names starting with $),\n\
-or an actual variable in the program being debugged.  EXP is any expression.\n\
+"Evaluate expression EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example).  VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged.  EXP is any valid expression.\n\
 Use \"set variable\" for variables with names identical to set subcommands.\n\
 \nWith a subcommand, this command modifies parts of the gdb environment.\n\
 You can see these environment settings with the \"show\" command.",
@@ -1977,10 +1978,11 @@ current working language.  The result is printed and saved in the value\n\
 history, if it is not void.");
 
   add_cmd ("variable", class_vars, set_command,
-           "Perform an assignment VAR = EXP.\n\
-You must type the \"=\".  VAR may be a debugger \"convenience\" variable\n\
-(names starting with $), a register (a few standard names starting with $),\n\
-or an actual variable in the program being debugged.  EXP is any expression.\n\
+"Evaluate expression EXP and assign result to variable VAR, using assignment\n\
+syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\
+example).  VAR may be a debugger \"convenience\" variable (names starting\n\
+with $), a register (a few standard names starting with $), or an actual\n\
+variable in the program being debugged.  EXP is any valid expression.\n\
 This may usually be abbreviated to simply \"set\".",
            &setlist);