comparison libinterp/parse-tree/oct-parse.yy @ 26060:edcb09d4b1f5

store nesting depth and primary parent info in nested function scopes * symscope.h, symscope.cc (symbol_scope_rep::m_nesting_depth, symbol_scope_rep::m_primary_parent): New data members. (symbol_scope_rep::m_is_nested, symbol_scope_rep::mark_nested, (symbol_scope::mark_nested): Delete. (symbol_scope_rep::set_primary_parent, symbol_scope_rep::primary_parent_scope_rep, symbol_scope_rep::is_relative, symbol_scope_rep::nesting_depth, symbol_scope_rep::set_nesting_depth): New functions. (symbol_scope::set_primary_parent, symbol_scope::primary_parent_scope_rep, symbol_scope::is_relative, symbol_scope::nesting_depth, symbol_scope::set_nesting_depth): New functions. (symbol_scope::set_primary_parent, symbol_scope_rep::primary_parent_scope_rep, symbol_scope_rep::is_relative, symbol_scope_rep::nesting_depth, symbol_scope_rep::set_nesting_depth): New functions. (symbol_scope_rep::is_nested): Use nesting depth to determine whether a function is nested. (symbol_scope_rep::dump): Also include nesting_depth and is_static. * oct-parse.yy (base_parser::m_curr_fcn_depth, base_parser::m_max_fcn_depth): Initialize to -1. Primary scope now has nesting level of 0. Adjust all uses.
author John W. Eaton <jwe@octave.org>
date Fri, 09 Nov 2018 02:15:42 -0500
parents da2bbcf1fbcd
children 2eb71b83d3e2
comparison
equal deleted inserted replaced
26059:da2bbcf1fbcd 26060:edcb09d4b1f5
1288 // Will get a real name later. 1288 // Will get a real name later.
1289 lexer.m_symtab_context.push (octave::symbol_scope ("parser:push_fcn_symtab")); 1289 lexer.m_symtab_context.push (octave::symbol_scope ("parser:push_fcn_symtab"));
1290 parser.m_function_scopes.push (lexer.m_symtab_context.curr_scope ()); 1290 parser.m_function_scopes.push (lexer.m_symtab_context.curr_scope ());
1291 1291
1292 if (! lexer.m_reading_script_file 1292 if (! lexer.m_reading_script_file
1293 && parser.m_curr_fcn_depth == 1 1293 && parser.m_curr_fcn_depth == 0
1294 && ! parser.m_parsing_subfunctions) 1294 && ! parser.m_parsing_subfunctions)
1295 parser.m_primary_fcn_scope 1295 parser.m_primary_fcn_scope
1296 = lexer.m_symtab_context.curr_scope (); 1296 = lexer.m_symtab_context.curr_scope ();
1297 1297
1298 if (lexer.m_reading_script_file 1298 if (lexer.m_reading_script_file
1299 && parser.m_curr_fcn_depth > 1) 1299 && parser.m_curr_fcn_depth > 0)
1300 { 1300 {
1301 parser.bison_error ("nested functions not implemented in this context"); 1301 parser.bison_error ("nested functions not implemented in this context");
1302 YYABORT; 1302 YYABORT;
1303 } 1303 }
1304 } 1304 }
1525 1525
1526 // Make classdef local functions unique from 1526 // Make classdef local functions unique from
1527 // classdef methods. 1527 // classdef methods.
1528 1528
1529 if (parser.m_parsing_local_functions 1529 if (parser.m_parsing_local_functions
1530 && parser.m_curr_fcn_depth == 1) 1530 && parser.m_curr_fcn_depth == 0)
1531 id = lexer.m_fcn_file_name + ">" + id; 1531 id = lexer.m_fcn_file_name + ">" + id;
1532 1532
1533 if (! parser.m_function_scopes.name_current_scope (id)) 1533 if (! parser.m_function_scopes.name_current_scope (id))
1534 { 1534 {
1535 parser.bison_error ("duplicate subfunction or nested function name", 1535 parser.bison_error ("duplicate subfunction or nested function name",
2175 2175
2176 base_parser::base_parser (base_lexer& lxr) 2176 base_parser::base_parser (base_lexer& lxr)
2177 : m_endfunction_found (false), m_autoloading (false), 2177 : m_endfunction_found (false), m_autoloading (false),
2178 m_fcn_file_from_relative_lookup (false), 2178 m_fcn_file_from_relative_lookup (false),
2179 m_parsing_subfunctions (false), m_parsing_local_functions (false), 2179 m_parsing_subfunctions (false), m_parsing_local_functions (false),
2180 m_max_fcn_depth (0), m_curr_fcn_depth (0), m_primary_fcn_scope (), 2180 m_max_fcn_depth (-1), m_curr_fcn_depth (-1), m_primary_fcn_scope (),
2181 m_curr_class_name (), m_curr_package_name (), m_function_scopes (), 2181 m_curr_class_name (), m_curr_package_name (), m_function_scopes (),
2182 m_primary_fcn_ptr (nullptr), m_subfunction_names (), 2182 m_primary_fcn_ptr (nullptr), m_subfunction_names (),
2183 m_classdef_object (nullptr), m_stmt_list (nullptr), m_lexer (lxr), 2183 m_classdef_object (nullptr), m_stmt_list (nullptr), m_lexer (lxr),
2184 m_parser_state (yypstate_new ()) 2184 m_parser_state (yypstate_new ())
2185 { } 2185 { }
2207 m_endfunction_found = false; 2207 m_endfunction_found = false;
2208 m_autoloading = false; 2208 m_autoloading = false;
2209 m_fcn_file_from_relative_lookup = false; 2209 m_fcn_file_from_relative_lookup = false;
2210 m_parsing_subfunctions = false; 2210 m_parsing_subfunctions = false;
2211 m_parsing_local_functions = false; 2211 m_parsing_local_functions = false;
2212 m_max_fcn_depth = 0; 2212 m_max_fcn_depth = -1;
2213 m_curr_fcn_depth = 0; 2213 m_curr_fcn_depth = -1;
2214 m_primary_fcn_scope = symbol_scope (); 2214 m_primary_fcn_scope = symbol_scope ();
2215 m_curr_class_name = ""; 2215 m_curr_class_name = "";
2216 m_curr_package_name = ""; 2216 m_curr_package_name = "";
2217 m_function_scopes.clear (); 2217 m_function_scopes.clear ();
2218 m_primary_fcn_ptr = nullptr; 2218 m_primary_fcn_ptr = nullptr;
3357 // If input is coming from a file, issue a warning if the name of 3357 // If input is coming from a file, issue a warning if the name of
3358 // the file does not match the name of the function stated in the 3358 // the file does not match the name of the function stated in the
3359 // file. Matlab doesn't provide a diagnostic (it ignores the stated 3359 // file. Matlab doesn't provide a diagnostic (it ignores the stated
3360 // name). 3360 // name).
3361 if (! m_autoloading && m_lexer.m_reading_fcn_file 3361 if (! m_autoloading && m_lexer.m_reading_fcn_file
3362 && m_curr_fcn_depth == 1 && ! m_parsing_subfunctions) 3362 && m_curr_fcn_depth == 0 && ! m_parsing_subfunctions)
3363 { 3363 {
3364 // FIXME: should m_lexer.m_fcn_file_name already be 3364 // FIXME: should m_lexer.m_fcn_file_name already be
3365 // preprocessed when we get here? It seems to only be a 3365 // preprocessed when we get here? It seems to only be a
3366 // problem with relative filenames. 3366 // problem with relative filenames.
3367 3367
3428 // Record help text for functions other than nested functions. 3428 // Record help text for functions other than nested functions.
3429 // We cannot currently record help for nested functions (bug #46008) 3429 // We cannot currently record help for nested functions (bug #46008)
3430 // because the doc_string of the outermost function is read first, 3430 // because the doc_string of the outermost function is read first,
3431 // whereas this function is called for the innermost function first. 3431 // whereas this function is called for the innermost function first.
3432 // We could have a stack of help_text in lexer. 3432 // We could have a stack of help_text in lexer.
3433 if (! m_lexer.m_help_text.empty () && m_curr_fcn_depth == 1) 3433 if (! m_lexer.m_help_text.empty () && m_curr_fcn_depth == 0)
3434 { 3434 {
3435 fcn->document (m_lexer.m_help_text); 3435 fcn->document (m_lexer.m_help_text);
3436 3436
3437 m_lexer.m_help_text = ""; 3437 m_lexer.m_help_text = "";
3438 } 3438 }
3439 3439
3440 if (m_lexer.m_reading_fcn_file && m_curr_fcn_depth == 1 3440 if (m_lexer.m_reading_fcn_file && m_curr_fcn_depth == 0
3441 && ! m_parsing_subfunctions) 3441 && ! m_parsing_subfunctions)
3442 m_primary_fcn_ptr = fcn; 3442 m_primary_fcn_ptr = fcn;
3443 3443
3444 return fcn; 3444 return fcn;
3445 } 3445 }
3477 if (lc) 3477 if (lc)
3478 fcn->stash_leading_comment (lc); 3478 fcn->stash_leading_comment (lc);
3479 3479
3480 fcn->define_ret_list (ret_list); 3480 fcn->define_ret_list (ret_list);
3481 3481
3482 if (m_curr_fcn_depth > 1 || m_parsing_subfunctions) 3482 if (m_curr_fcn_depth > 0 || m_parsing_subfunctions)
3483 { 3483 {
3484 fcn->stash_fcn_location (l, c); 3484 fcn->stash_fcn_location (l, c);
3485 fcn->stash_parent_fcn_name (m_lexer.m_fcn_file_name); 3485 fcn->stash_parent_fcn_name (m_lexer.m_fcn_file_name);
3486 3486
3487 octave_value ov_fcn (fcn); 3487 octave_value ov_fcn (fcn);
3488 3488
3489 if (m_endfunction_found && m_function_scopes.size () > 1) 3489 if (m_endfunction_found && m_function_scopes.size () > 1)
3490 { 3490 {
3491 fcn->mark_as_nested_function (); 3491 fcn->mark_as_nested_function ();
3492 fcn_scope.mark_nested (); 3492 fcn_scope.set_nesting_depth (m_curr_fcn_depth);
3493 3493
3494 symbol_scope pscope = m_function_scopes.parent_scope (); 3494 symbol_scope pscope = m_function_scopes.parent_scope ();
3495 fcn_scope.set_parent (pscope); 3495 fcn_scope.set_parent (pscope);
3496 fcn_scope.set_primary_parent (m_primary_fcn_scope);
3496 pscope.install_nestfunction (nm, ov_fcn, fcn_scope); 3497 pscope.install_nestfunction (nm, ov_fcn, fcn_scope);
3497 } 3498 }
3498 else 3499 else
3499 { 3500 {
3500 fcn->mark_as_subfunction (); 3501 fcn->mark_as_subfunction ();
3502 fcn_scope.set_parent (m_primary_fcn_scope); 3503 fcn_scope.set_parent (m_primary_fcn_scope);
3503 m_primary_fcn_scope.install_subfunction (nm, ov_fcn); 3504 m_primary_fcn_scope.install_subfunction (nm, ov_fcn);
3504 } 3505 }
3505 } 3506 }
3506 3507
3507 if (m_curr_fcn_depth == 1) 3508 if (m_curr_fcn_depth == 0)
3508 fcn_scope.update_nest (); 3509 fcn_scope.update_nest ();
3509 3510
3510 if (! m_lexer.m_reading_fcn_file && m_curr_fcn_depth == 1) 3511 if (! m_lexer.m_reading_fcn_file && m_curr_fcn_depth == 0)
3511 { 3512 {
3512 // We are either reading a script file or defining a function 3513 // We are either reading a script file or defining a function
3513 // at the command line, so this definition creates a 3514 // at the command line, so this definition creates a
3514 // tree_function object that is placed in the parse tree. 3515 // tree_function object that is placed in the parse tree.
3515 // Otherwise, it is just inserted in the symbol table, 3516 // Otherwise, it is just inserted in the symbol table,
3536 void 3537 void
3537 base_parser::recover_from_parsing_function (void) 3538 base_parser::recover_from_parsing_function (void)
3538 { 3539 {
3539 m_lexer.m_symtab_context.pop (); 3540 m_lexer.m_symtab_context.pop ();
3540 3541
3541 if (m_lexer.m_reading_fcn_file && m_curr_fcn_depth == 1 3542 if (m_lexer.m_reading_fcn_file && m_curr_fcn_depth == 0
3542 && ! m_parsing_subfunctions) 3543 && ! m_parsing_subfunctions)
3543 m_parsing_subfunctions = true; 3544 m_parsing_subfunctions = true;
3544 3545
3545 m_curr_fcn_depth--; 3546 m_curr_fcn_depth--;
3546 m_function_scopes.pop (); 3547 m_function_scopes.pop ();
3998 retval->mark_global (); 3999 retval->mark_global ();
3999 } 4000 }
4000 break; 4001 break;
4001 4002
4002 case PERSISTENT: 4003 case PERSISTENT:
4003 if (m_curr_fcn_depth > 0) 4004 if (m_curr_fcn_depth >= 0)
4004 { 4005 {
4005 retval = new tree_decl_command ("persistent", lst, l, c); 4006 retval = new tree_decl_command ("persistent", lst, l, c);
4006 retval->mark_persistent (); 4007 retval->mark_persistent ();
4007 } 4008 }
4008 else 4009 else
4238 } 4239 }
4239 4240
4240 void 4241 void
4241 base_parser::maybe_warn_missing_semi (tree_statement_list *t) 4242 base_parser::maybe_warn_missing_semi (tree_statement_list *t)
4242 { 4243 {
4243 if (m_curr_fcn_depth > 0) 4244 if (m_curr_fcn_depth >= 0)
4244 { 4245 {
4245 tree_statement *tmp = t->back (); 4246 tree_statement *tmp = t->back ();
4246 4247
4247 if (tmp->is_expression ()) 4248 if (tmp->is_expression ())
4248 warning_with_id 4249 warning_with_id