# HG changeset patch # User jwe # Date 1035911574 0 # Node ID 597fbc55ea404a63bd092932618374f1f3566aea # Parent 7d9bda865012b640f28be1e0096753aca9061020 [project @ 2002-10-29 17:12:53 by jwe] diff -r 7d9bda865012 -r 597fbc55ea40 src/ChangeLog --- a/src/ChangeLog Mon Oct 28 21:05:31 2002 +0000 +++ b/src/ChangeLog Tue Oct 29 17:12:54 2002 +0000 @@ -1,3 +1,25 @@ +2002-10-29 John W. Eaton + + * pt-idx.h (tree_index_expression::dyn_field): New data member. + * pt-idx.cc (tree_index_expression::tree_index_expression + (tree_expression*, tree_expression*, int, int)): New constructor. + (tree_index_expression::append (tree_expression*)): New function. + (tree_index_expression::get_struct_index): New function. + (tree_index_expression::make_arg_struct): Handle dynamic fields. + (tree_index_expression::rvalue): Likewise. + (tree_index_expression::lvalue): Likewise. + + * parse.y (make_indirect_ref (tree_expression*, tree_expression*)): + New function. + (indirect_ref_op): New non-terminal. + (postfix_expr): Use it. + Recognize dynamic struct field references. + (parsing_indir): Delete unused non-terminal. + + * lex.l ("("): Set lexer_flags.looking_at_indirect_ref to false here. + + * pt-idx.cc (tree_index_expression::name): Simplify. + 2002-10-28 John W. Eaton * oct-conf.h.in (OCTAVE_CONF_HAVE_DLOPEN_API, diff -r 7d9bda865012 -r 597fbc55ea40 src/lex.l --- a/src/lex.l Mon Oct 28 21:05:31 2002 +0000 +++ b/src/lex.l Tue Oct 29 17:12:54 2002 +0000 @@ -691,6 +691,7 @@ } "(" { + lexer_flags.looking_at_indirect_ref = false; if (lexer_flags.plotting && ! lexer_flags.in_plot_range) lexer_flags.past_plot_range = true; nesting_level.paren (); diff -r 7d9bda865012 -r 597fbc55ea40 src/parse.y --- a/src/parse.y Mon Oct 28 21:05:31 2002 +0000 +++ b/src/parse.y Tue Oct 29 17:12:54 2002 +0000 @@ -291,6 +291,10 @@ static tree_index_expression * make_indirect_ref (tree_expression *expr, const std::string&); +// Make an indirect reference expression with dynamic field name. +static tree_index_expression * +make_indirect_ref (tree_expression *expr, tree_expression *field); + // Make a declaration command. static tree_decl_command * make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst); @@ -696,7 +700,7 @@ } ; -parsing_indir : // empty +indirect_ref_op : '.' { lexer_flags.looking_at_indirect_ref = true; } ; @@ -718,8 +722,10 @@ { $$ = make_postfix_op (QUOTE, $1, $2); } | postfix_expr TRANSPOSE { $$ = make_postfix_op (TRANSPOSE, $1, $2); } - | postfix_expr '.' parsing_indir STRUCT_ELT - { $$ = make_indirect_ref ($1, $4->text ()); } + | postfix_expr indirect_ref_op STRUCT_ELT + { $$ = make_indirect_ref ($1, $3->text ()); } + | postfix_expr indirect_ref_op '(' expression ')' + { $$ = make_indirect_ref ($1, $4); } ; prefix_expr : postfix_expr @@ -2656,6 +2662,32 @@ return retval; } +// Make an indirect reference expression with dynamic field name. + +static tree_index_expression * +make_indirect_ref (tree_expression *expr, tree_expression *elt) +{ + tree_index_expression *retval = 0; + + int l = expr->line (); + int c = expr->column (); + + if (expr->is_index_expression ()) + { + tree_index_expression *tmp = static_cast (expr); + + tmp->append (elt); + + retval = tmp; + } + else + retval = new tree_index_expression (expr, elt, l, c); + + lexer_flags.looking_at_indirect_ref = false; + + return retval; +} + // Make a declaration command. static tree_decl_command * diff -r 7d9bda865012 -r 597fbc55ea40 src/pt-idx.cc --- a/src/pt-idx.cc Mon Oct 28 21:05:31 2002 +0000 +++ b/src/pt-idx.cc Tue Oct 29 17:12:54 2002 +0000 @@ -52,7 +52,8 @@ tree_index_expression::tree_index_expression (tree_expression *e, tree_argument_list *lst, int l, int c, char t) - : tree_expression (l, c), expr (e), args (), type (), arg_nm () + : tree_expression (l, c), expr (e), args (), type (), + arg_nm (), dyn_field () { append (lst, t); } @@ -60,17 +61,28 @@ tree_index_expression::tree_index_expression (tree_expression *e, const std::string& n, int l, int c) - : tree_expression (l, c), expr (e), args (), type (), arg_nm () + : tree_expression (l, c), expr (e), args (), type (), + arg_nm (), dyn_field () { append (n); } +tree_index_expression::tree_index_expression (tree_expression *e, + tree_expression *df, + int l, int c) + : tree_expression (l, c), expr (e), args (), type (), + arg_nm (), dyn_field () +{ + append (df); +} + void tree_index_expression::append (tree_argument_list *lst, char t) { args.append (lst); type.append (1, t); arg_nm.append (lst ? lst->get_arg_names () : string_vector ()); + dyn_field.append (static_cast (0)); } void @@ -79,6 +91,16 @@ args.append (static_cast (0)); type.append ("."); arg_nm.append (n); + dyn_field.append (static_cast (0)); +} + +void +tree_index_expression::append (tree_expression *df) +{ + args.append (static_cast (0)); + type.append ("."); + arg_nm.append (""); + dyn_field.append (df); } tree_index_expression::~tree_index_expression (void) @@ -98,11 +120,7 @@ std::string tree_index_expression::name (void) const { - // ??? FIXME ??? - std::string xname = expr->name (); - - return (type[0] != '.' || xname == "") - ? xname : xname + "." + arg_nm.front ()(0); + return expr->name (); } static Cell @@ -152,6 +170,29 @@ return retval; } +std::string +tree_index_expression::get_struct_index (Pix p_arg_nm, Pix p_dyn_field) const +{ + std::string fn = arg_nm(p_arg_nm)(0); + + if (fn.empty ()) + { + tree_expression *df = dyn_field (p_dyn_field); + + if (df) + { + octave_value t = df->rvalue (); + + if (! error_state) + fn = t.string_value (); + } + else + panic_impossible (); + } + + return fn; +} + Octave_map tree_index_expression::make_arg_struct (void) const { @@ -162,6 +203,7 @@ Pix p_args = args.first (); Pix p_arg_nm = arg_nm.first (); + Pix p_dyn_field = dyn_field.first (); Octave_map m; @@ -178,7 +220,7 @@ break; case '.': - subs_list(i) = arg_nm(p_arg_nm)(0); + subs_list(i) = get_struct_index (p_arg_nm, p_dyn_field); break; default: @@ -190,6 +232,7 @@ args.next (p_args); arg_nm.next (p_arg_nm); + dyn_field.next (p_dyn_field); } m ["subs"] = subs_list; @@ -216,6 +259,7 @@ Pix p_args = args.first (); Pix p_arg_nm = arg_nm.first (); + Pix p_dyn_field = dyn_field.first (); for (int i = 0; i < n; i++) { @@ -230,7 +274,7 @@ break; case '.': - idx.append (arg_nm(p_arg_nm)(0)); + idx.append (get_struct_index (p_arg_nm, p_dyn_field)); break; default: @@ -242,6 +286,7 @@ args.next (p_args); arg_nm.next (p_arg_nm); + dyn_field.next (p_dyn_field); } if (! error_state) @@ -275,6 +320,7 @@ Pix p_args = args.first (); Pix p_arg_nm = arg_nm.first (); + Pix p_dyn_field = dyn_field.first (); for (int i = 0; i < n; i++) { @@ -289,7 +335,7 @@ break; case '.': - idx.append (arg_nm(p_arg_nm)(0)); + idx.append (get_struct_index (p_arg_nm, p_dyn_field)); break; default: @@ -301,6 +347,7 @@ args.next (p_args); arg_nm.next (p_arg_nm); + dyn_field.next (p_dyn_field); } if (! error_state) diff -r 7d9bda865012 -r 597fbc55ea40 src/pt-idx.h --- a/src/pt-idx.h Mon Oct 28 21:05:31 2002 +0000 +++ b/src/pt-idx.h Tue Oct 29 17:12:54 2002 +0000 @@ -54,12 +54,17 @@ tree_index_expression (tree_expression *e, const std::string& n, int l = -1, int c = -1); + tree_index_expression (tree_expression *e, tree_expression* df, + int l = -1, int c = -1); + ~tree_index_expression (void); void append (tree_argument_list *lst = 0, char t = '('); void append (const std::string& n); + void append (tree_expression *df); + bool is_index_expression (void) const { return true; } std::string name (void) const; @@ -97,10 +102,16 @@ // The type of this index expression. std::string type; - // The names of the arguments. + // The names of the arguments. Used for constant struct element + // references. SLList arg_nm; - Octave_map tree_index_expression::make_arg_struct (void) const; + // The list of dynamic field names, if any. + SLList dyn_field; + + Octave_map make_arg_struct (void) const; + + std::string get_struct_index (Pix p_arg_nm, Pix p_dyn_field) const; // No copying!