Mercurial > octave
changeset 23600:db947ba52118
explicitly limit anonymous functions to a single expression
* ov-fcn-handle.cc (octave_fcn_handle::print_raw): Handle anonymous
function body as a single expression.
* parse.h, oct-parse.in.yy: Now expect 8 shift/reduce conflicts.
(expr_no_assign): New non-terminal.
(expression): Split into expr_no_assign and assign_expr.
(anon_fcn_handle): Define body as expr_no_assign instead of statement.
(base_parser::make_anon_fcn_handle): Handle body as a single
expression instead of statement.
* pt-eval.cc (tree_evaluator::visit_anon_fcn_handle): Handle body as a
single expression instead of statement.
* pt-fcn-handle.h, pt-fcn-handle.cc (class tree_anon_fcn_handle):
Handle body as a single expression. Eliminate return list.
* pt-pr-code.h, pt-pr-code.cc (tree_print_code::print_fcn_handle_body):
Handle anonymous function handle body as single expression.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sun, 11 Jun 2017 16:37:26 -0400 |
parents | 5cb3a2bb5e1e |
children | a3898679d459 |
files | libinterp/octave-value/ov-fcn-handle.cc libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-fcn-handle.cc libinterp/parse-tree/pt-fcn-handle.h libinterp/parse-tree/pt-pr-code.cc libinterp/parse-tree/pt-pr-code.h |
diffstat | 8 files changed, 78 insertions(+), 84 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-fcn-handle.cc Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/octave-value/ov-fcn-handle.cc Sun Jun 11 16:37:26 2017 -0400 @@ -1444,7 +1444,21 @@ os << ") "; - tpc.print_fcn_handle_body (f->body ()); + octave::tree_statement_list *b = f->body (); + + assert (b->length () == 1); + + octave::tree_statement *s = b->front (); + + if (s) + { + assert (s->is_expression ()); + + octave::tree_expression *e = s->expression (); + + if (e) + tpc.print_fcn_handle_body (e); + } printed = true; }
--- a/libinterp/parse-tree/oct-parse.in.yy Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Sun Jun 11 16:37:26 2017 -0400 @@ -111,10 +111,10 @@ // Bison declarations. -// The grammar currently has 14 shift/reduce conflicts. Ensure that +// The grammar currently has 8 shift/reduce conflicts. Ensure that // we notice if that number changes. -%expect 14 +%expect 8 %API_PREFIX_DECL% @@ -244,7 +244,7 @@ %type <tree_matrix_type> matrix_rows %type <tree_cell_type> cell_rows %type <tree_expression_type> matrix cell -%type <tree_expression_type> primary_expr oper_expr power_expr +%type <tree_expression_type> primary_expr oper_expr power_expr expr_no_assign %type <tree_expression_type> simple_expr colon_expr assign_expr expression %type <tree_identifier_type> identifier fcn_name magic_tilde %type <tree_funcall_type> superclass_identifier meta_identifier @@ -605,7 +605,7 @@ } ; -anon_fcn_handle : '@' param_list stmt_begin statement +anon_fcn_handle : '@' param_list stmt_begin expr_no_assign { $$ = parser.make_anon_fcn_handle ($2, $4); lexer.nesting_level.remove (); @@ -909,7 +909,7 @@ { $$ = parser.make_assign_op (OR_EQ, $1, $2, $3); } ; -expression : simple_expr +expr_no_assign : simple_expr { if ($1 && ($1->is_matrix () || $1->iscell ())) { @@ -924,6 +924,12 @@ else $$ = $1; } + | anon_fcn_handle + { $$ = $1; } + ; + +expression : expr_no_assign + { $$ = $1; } | assign_expr { if (! $1) @@ -931,9 +937,6 @@ $$ = $1; } - | anon_fcn_handle - { $$ = $1; } - ; // ================================================ // Commands, declarations, and function definitions @@ -2480,29 +2483,24 @@ tree_anon_fcn_handle * base_parser::make_anon_fcn_handle (tree_parameter_list *param_list, - tree_statement *stmt) + tree_expression *expr) { // FIXME: need to get these from the location of the @ symbol. int l = lexer.input_line_number; int c = lexer.current_input_column; - tree_parameter_list *ret_list = 0; - symbol_table::scope_id fcn_scope = lexer.symtab_context.curr_scope (); symbol_table::scope_id parent_scope = lexer.symtab_context.parent_scope (); lexer.symtab_context.pop (); - stmt->set_print_flag (false); - - tree_statement_list *body = new tree_statement_list (stmt); - - body->mark_as_anon_function_body (); + expr->set_print_flag (false); tree_anon_fcn_handle *retval - = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, + = new tree_anon_fcn_handle (param_list, expr, fcn_scope, parent_scope, l, c); - // FIXME: Stash the filename. This does not work and produces + +// FIXME: Stash the filename. This does not work and produces // errors when executed. //retval->stash_file_name (lexer.fcn_file_name);
--- a/libinterp/parse-tree/parse.h Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/parse.h Sun Jun 11 16:37:26 2017 -0400 @@ -179,7 +179,8 @@ // Build an anonymous function handle. tree_anon_fcn_handle * - make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt); + make_anon_fcn_handle (tree_parameter_list *param_list, + tree_expression * expr); // Build a binary expression. tree_expression *
--- a/libinterp/parse-tree/pt-eval.cc Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Sun Jun 11 16:37:26 2017 -0400 @@ -88,32 +88,43 @@ } void - tree_evaluator::visit_anon_fcn_handle (tree_anon_fcn_handle& expr) + tree_evaluator::visit_anon_fcn_handle (tree_anon_fcn_handle& anon_fh) { // FIXME: should CMD_LIST be limited to a single expression? // I think that is what Matlab does. - tree_parameter_list *param_list = expr.parameter_list (); - tree_parameter_list *ret_list = expr.return_list (); - tree_statement_list *stmt_list = expr.body (); - - symbol_table::scope_id af_sid = expr.scope (); + tree_parameter_list *param_list = anon_fh.parameter_list (); + tree_expression *expr = anon_fh.expression (); + + symbol_table::scope_id af_sid = anon_fh.scope (); symbol_table& symtab = m_interpreter.get_symbol_table (); symbol_table::scope_id af_parent_sid - = expr.has_parent_scope () ? symtab.current_scope () : -1; + = anon_fh.has_parent_scope () ? symtab.current_scope () : -1; symbol_table::scope_id new_scope = symtab.dup_scope (af_sid); if (new_scope > 0 && af_parent_sid > 0) symtab.inherit (new_scope, af_parent_sid); + tree_parameter_list *param_list_dup + = param_list ? param_list->dup (new_scope, 0) : 0; + + tree_parameter_list *ret_list = 0; + + tree_statement_list *stmt_list = 0; + + if (expr) + { + tree_expression *expr_dup = expr->dup (new_scope, 0); + tree_statement *stmt = new tree_statement (expr_dup, 0); + stmt_list = new tree_statement_list (stmt); + } + octave_user_function *af - = new octave_user_function (new_scope, - param_list ? param_list->dup (new_scope, 0) : 0, - ret_list ? ret_list->dup (new_scope, 0) : 0, - stmt_list ? stmt_list->dup (new_scope, 0) : 0); + = new octave_user_function (new_scope, param_list_dup, ret_list, + stmt_list); if (af_parent_sid > 0) symtab.set_parent (new_scope, af_parent_sid); @@ -133,8 +144,10 @@ } af->mark_as_anonymous_function (); - af->stash_fcn_file_name (expr.file_name ()); - af->stash_fcn_location (expr.line (), expr.column ()); + + // FIXME: these should probably come from ANON_FH. + // af->stash_fcn_file_name (expr.file_name ()); + // af->stash_fcn_location (expr.line (), expr.column ()); octave_value ov_fcn (af);
--- a/libinterp/parse-tree/pt-fcn-handle.cc Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/pt-fcn-handle.cc Sun Jun 11 16:37:26 2017 -0400 @@ -67,8 +67,7 @@ tree_anon_fcn_handle::~tree_anon_fcn_handle (void) { delete m_parameter_list; - delete m_return_list; - delete m_statement_list; + delete m_expression; } tree_expression * @@ -76,8 +75,7 @@ symbol_table::context_id) const { tree_parameter_list *param_list = parameter_list (); - tree_parameter_list *ret_list = return_list (); - tree_statement_list *stmt_list = body (); + tree_expression *expr = expression (); symbol_table::scope_id af_sid = scope (); symbol_table::scope_id af_parent_sid = parent_scope (); @@ -92,8 +90,7 @@ tree_anon_fcn_handle *new_afh = new tree_anon_fcn_handle (param_list ? param_list->dup (new_scope, 0) : 0, - ret_list ? ret_list->dup (new_scope, 0) : 0, - stmt_list ? stmt_list->dup (new_scope, 0) : 0, + expr ? expr->dup (new_scope, 0) : 0, new_scope, af_parent_sid, line (), column ()); new_afh->copy_base (*this);
--- a/libinterp/parse-tree/pt-fcn-handle.h Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/pt-fcn-handle.h Sun Jun 11 16:37:26 2017 -0400 @@ -92,17 +92,16 @@ public: tree_anon_fcn_handle (int l = -1, int c = -1) - : tree_expression (l, c), m_parameter_list (0), m_return_list (0), - m_statement_list (0), m_sid (-1), m_parent_sid (-1), m_file_name () + : tree_expression (l, c), m_parameter_list (0), m_expression (0), + m_sid (-1), m_parent_sid (-1), m_file_name () { } - tree_anon_fcn_handle (tree_parameter_list *pl, tree_parameter_list *rl, - tree_statement_list *cl, symbol_table::scope_id sid, + tree_anon_fcn_handle (tree_parameter_list *pl, tree_expression *ex, + symbol_table::scope_id sid, symbol_table::scope_id parent_sid, int l = -1, int c = -1) - : tree_expression (l, c), m_parameter_list (pl), m_return_list (rl), - m_statement_list (cl), m_sid (sid), m_parent_sid (parent_sid), - m_file_name () + : tree_expression (l, c), m_parameter_list (pl), m_expression (ex), + m_sid (sid), m_parent_sid (parent_sid), m_file_name () { } // No copying! @@ -122,9 +121,7 @@ return m_parameter_list; } - tree_parameter_list * return_list (void) const { return m_return_list; } - - tree_statement_list * body (void) const { return m_statement_list; } + tree_expression * expression (void) const { return m_expression; } symbol_table::scope_id scope (void) const { return m_sid; } @@ -146,11 +143,8 @@ // Inputs parameters. tree_parameter_list *m_parameter_list; - // Output parameters. - tree_parameter_list *m_return_list; - - // Function body. - tree_statement_list *m_statement_list; + // Function body, limited to a single expression. + tree_expression *m_expression; // Function scope. symbol_table::scope_id m_sid;
--- a/libinterp/parse-tree/pt-pr-code.cc Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/pt-pr-code.cc Sun Jun 11 16:37:26 2017 -0400 @@ -52,7 +52,7 @@ os << ") "; - print_fcn_handle_body (afh.body ()); + print_fcn_handle_body (afh.expression ()); print_parens (afh, ")"); } @@ -1152,36 +1152,13 @@ } void - tree_print_code::print_fcn_handle_body (tree_statement_list *b) + tree_print_code::print_fcn_handle_body (tree_expression *e) { - if (b) + if (e) { - assert (b->length () == 1); - - tree_statement *s = b->front (); - - if (s) - { - if (s->is_expression ()) - { - tree_expression *e = s->expression (); - - if (e) - { - suppress_newlines++; - e->accept (*this); - suppress_newlines--; - } - } - else - { - tree_command *c = s->command (); - - suppress_newlines++; - c->accept (*this); - suppress_newlines--; - } - } + suppress_newlines++; + e->accept (*this); + suppress_newlines--; } }
--- a/libinterp/parse-tree/pt-pr-code.h Fri Jun 09 02:21:28 2017 -0400 +++ b/libinterp/parse-tree/pt-pr-code.h Sun Jun 11 16:37:26 2017 -0400 @@ -148,7 +148,7 @@ void visit_do_until_command (tree_do_until_command&); - void print_fcn_handle_body (tree_statement_list *); + void print_fcn_handle_body (tree_expression *); private: