#include "block.h"
#include <ctype.h>
#include <algorithm>
+#include "type-stack.h"
#define parse_type(ps) builtin_type (ps->gdbarch ())
#define parse_f_type(ps) builtin_f_type (ps->gdbarch ())
static struct parser_state *pstate = NULL;
+/* Depth of parentheses. */
+static int paren_depth;
+
+/* The current type stack. */
+static struct type_stack *type_stack;
+
int yyparse (void);
static int yylex (void);
%token <voidval> DOLLAR_VARIABLE
%token <opcode> ASSIGN_MODIFY
-%token <opcode> UNOP_INTRINSIC
+%token <opcode> UNOP_INTRINSIC BINOP_INTRINSIC
%left ','
%left ABOVE_COMMA
;
exp : KIND '(' exp ')' %prec UNARY
- { write_exp_elt_opcode (pstate, UNOP_KIND); }
+ { write_exp_elt_opcode (pstate, UNOP_FORTRAN_KIND); }
;
/* No more explicit array operators, we treat everything in F77 as
later in eval.c. */
exp : exp '('
- { start_arglist (); }
+ { pstate->start_arglist (); }
arglist ')'
{ write_exp_elt_opcode (pstate,
OP_F77_UNDETERMINED_ARGLIST);
write_exp_elt_longcst (pstate,
- (LONGEST) end_arglist ());
+ pstate->end_arglist ());
write_exp_elt_opcode (pstate,
OP_F77_UNDETERMINED_ARGLIST); }
;
{ write_exp_elt_opcode (pstate, $1); }
;
+exp : BINOP_INTRINSIC '(' exp ',' exp ')'
+ { write_exp_elt_opcode (pstate, $1); }
+ ;
+
arglist :
;
arglist : exp
- { arglist_len = 1; }
+ { pstate->arglist_len = 1; }
;
arglist : subrange
- { arglist_len = 1; }
+ { pstate->arglist_len = 1; }
;
arglist : arglist ',' exp %prec ABOVE_COMMA
- { arglist_len++; }
+ { pstate->arglist_len++; }
;
/* There are four sorts of subrange types in F90. */
if (sym.symbol)
{
if (symbol_read_needs_frame (sym.symbol))
- innermost_block.update (sym);
+ pstate->block_tracker->update (sym);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
write_exp_elt_block (pstate, sym.block);
write_exp_elt_sym (pstate, sym.symbol);
else
{
struct bound_minimal_symbol msymbol;
- char *arg = copy_name ($1.stoken);
+ std::string arg = copy_name ($1.stoken);
msymbol =
- lookup_bound_minimal_symbol (arg);
+ lookup_bound_minimal_symbol (arg.c_str ());
if (msymbol.minsym != NULL)
write_exp_msymbol (pstate, msymbol);
else if (!have_full_symbols () && !have_partial_symbols ())
error (_("No symbol table is loaded. Use the \"file\" command."));
else
error (_("No symbol \"%s\" in current context."),
- copy_name ($1.stoken));
+ arg.c_str ());
}
}
;
struct type *range_type;
while (!done)
- switch (pop_type ())
+ switch (type_stack->pop ())
{
case tp_end:
done = 1;
follow_type = lookup_lvalue_reference_type (follow_type);
break;
case tp_array:
- array_size = pop_type_int ();
+ array_size = type_stack->pop_int ();
if (array_size != -1)
{
range_type =
break;
case tp_kind:
{
- int kind_val = pop_type_int ();
+ int kind_val = type_stack->pop_int ();
follow_type
= convert_to_kind_type (follow_type, kind_val);
}
;
abs_decl: '*'
- { push_type (tp_pointer); $$ = 0; }
+ { type_stack->push (tp_pointer); $$ = 0; }
| '*' abs_decl
- { push_type (tp_pointer); $$ = $2; }
+ { type_stack->push (tp_pointer); $$ = $2; }
| '&'
- { push_type (tp_reference); $$ = 0; }
+ { type_stack->push (tp_reference); $$ = 0; }
| '&' abs_decl
- { push_type (tp_reference); $$ = $2; }
+ { type_stack->push (tp_reference); $$ = $2; }
| direct_abs_decl
;
| '*' INT
{ push_kind_type ($2.val, $2.type); }
| direct_abs_decl func_mod
- { push_type (tp_function); }
+ { type_stack->push (tp_function); }
| func_mod
- { push_type (tp_function); }
+ { type_stack->push (tp_function); }
;
func_mod: '(' ')'
ival = static_cast <int> (val);
}
- push_type_int (ival);
- push_type (tp_kind);
+ type_stack->push (ival);
+ type_stack->push (tp_kind);
}
/* Called when a type has a '(kind=N)' modifier after it, for example
/* The following correspond to actual functions in Fortran and are case
insensitive. */
{ "kind", KIND, BINOP_END, false },
- { "abs", UNOP_INTRINSIC, UNOP_ABS, false }
+ { "abs", UNOP_INTRINSIC, UNOP_ABS, false },
+ { "mod", BINOP_INTRINSIC, BINOP_MOD, false },
+ { "floor", UNOP_INTRINSIC, UNOP_FORTRAN_FLOOR, false },
+ { "ceiling", UNOP_INTRINSIC, UNOP_FORTRAN_CEILING, false },
+ { "modulo", BINOP_INTRINSIC, BINOP_FORTRAN_MODULO, false },
+ { "cmplx", BINOP_INTRINSIC, BINOP_FORTRAN_CMPLX, false },
};
/* Implementation of a dynamically expandable buffer for processing input
static int
match_string_literal (void)
{
- const char *tokptr = lexptr;
+ const char *tokptr = pstate->lexptr;
for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
{
CHECKBUF (1);
- if (*tokptr == *lexptr)
+ if (*tokptr == *pstate->lexptr)
{
- if (*(tokptr + 1) == *lexptr)
+ if (*(tokptr + 1) == *pstate->lexptr)
tokptr++;
else
break;
tempbuf[tempbufindex] = '\0';
yylval.sval.ptr = tempbuf;
yylval.sval.length = tempbufindex;
- lexptr = ++tokptr;
+ pstate->lexptr = ++tokptr;
return STRING_LITERAL;
}
}
retry:
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
- tokstart = lexptr;
+ tokstart = pstate->lexptr;
/* First of all, let us make sure we are not dealing with the
special tokens .true. and .false. which evaluate to 1 and 0. */
- if (*lexptr == '.')
+ if (*pstate->lexptr == '.')
{
for (int i = 0; i < ARRAY_SIZE (boolean_values); i++)
{
if (strncasecmp (tokstart, boolean_values[i].name,
strlen (boolean_values[i].name)) == 0)
{
- lexptr += strlen (boolean_values[i].name);
+ pstate->lexptr += strlen (boolean_values[i].name);
yylval.lval = boolean_values[i].value;
return BOOLEAN_LITERAL;
}
strlen (dot_ops[i].oper)) == 0)
{
gdb_assert (!dot_ops[i].case_sensitive);
- lexptr += strlen (dot_ops[i].oper);
+ pstate->lexptr += strlen (dot_ops[i].oper);
yylval.opcode = dot_ops[i].opcode;
return dot_ops[i].token;
}
if (strncmp (tokstart, "**", 2) == 0)
{
- lexptr += 2;
+ pstate->lexptr += 2;
yylval.opcode = BINOP_EXP;
return STARSTAR;
}
case ' ':
case '\t':
case '\n':
- lexptr++;
+ pstate->lexptr++;
goto retry;
case '\'':
case '(':
paren_depth++;
- lexptr++;
+ pstate->lexptr++;
return c;
case ')':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ pstate->lexptr++;
return c;
case ',':
- if (comma_terminates && paren_depth == 0)
+ if (pstate->comma_terminates && paren_depth == 0)
return 0;
- lexptr++;
+ pstate->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9')
goto symbol; /* Nope, must be a symbol. */
/* FALL THRU. */
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
case '{':
case '}':
symbol:
- lexptr++;
+ pstate->lexptr++;
return c;
}
if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
return 0;
- lexptr += namelen;
+ pstate->lexptr += namelen;
/* Catch specific keywords. */
currently as names of types; NAME for other symbols.
The caller is not constrained to care about the distinction. */
{
- char *tmp = copy_name (yylval.sval);
+ std::string tmp = copy_name (yylval.sval);
struct block_symbol result;
struct field_of_this_result is_a_field_of_this;
enum domain_enum_tag lookup_domains[] =
way we can refer to it unconditionally below. */
memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this));
- result = lookup_symbol (tmp, pstate->expression_context_block,
+ result = lookup_symbol (tmp.c_str (), pstate->expression_context_block,
lookup_domains[i],
pstate->language ()->la_language
== language_cplus
yylval.tsym.type
= language_lookup_primitive_type (pstate->language (),
- pstate->gdbarch (), tmp);
+ pstate->gdbarch (), tmp.c_str ());
if (yylval.tsym.type != NULL)
return TYPENAME;
parser_debug);
gdb_assert (par_state != NULL);
pstate = par_state;
+ paren_depth = 0;
+
+ struct type_stack stack;
+ scoped_restore restore_type_stack = make_scoped_restore (&type_stack,
+ &stack);
return yyparse ();
}
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}