Mercurial > octave
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 |