Mercurial > octave
changeset 33298:e3d55a08aff4 bytecode-interpreter
maint: merge default to bytecode-interpreter
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 02 Apr 2024 16:11:12 -0400 |
parents | 85f39533661d (current diff) 0376082b659f (diff) |
children | 95596df836a1 |
files | libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov-usr-fcn.h libinterp/parse-tree/module.mk libinterp/parse-tree/pt-eval.cc |
diffstat | 42 files changed, 1468 insertions(+), 1793 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/cdef-class.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/octave-value/cdef-class.cc Tue Apr 02 16:11:12 2024 -0400 @@ -969,7 +969,7 @@ // Method blocks - std::list<tree_classdef_methods_block *> mb_list = b->methods_list (); + std::list<tree_classdef_methods_block *> mb_list = b->method_list (); load_path& lp = interp.get_load_path (); @@ -1083,7 +1083,7 @@ // evaluating default value expressions. std::list<tree_classdef_properties_block *> pb_list - = b->properties_list (); + = b->property_list (); for (auto& pb_p : pb_list) {
--- a/libinterp/octave-value/ov-usr-fcn.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc Tue Apr 02 16:11:12 2024 -0400 @@ -45,6 +45,7 @@ #include "ov-usr-fcn.h" #include "ov.h" #include "pager.h" +#include "pt-cmd.h" #include "pt-eval.h" #include "pt-jump.h" #include "pt-misc.h" @@ -263,7 +264,6 @@ octave::tree_parameter_list *rl, octave::tree_statement_list *cl) : octave_user_code ("", "", scope, cl, ""), m_param_list (pl), m_ret_list (rl), - m_lead_comm (), m_trail_comm (), m_location_line (0), m_location_column (0), m_system_fcn_file (false), m_num_named_args (m_param_list ? m_param_list->size () : 0), @@ -279,8 +279,6 @@ { delete m_param_list; delete m_ret_list; - delete m_lead_comm; - delete m_trail_comm; } std::string @@ -314,6 +312,39 @@ return this; } +void +octave_user_function::attach_trailing_comments (const octave::comment_list& lst) +{ + if (m_cmd_list && ! m_cmd_list->empty ()) + { + octave::tree_statement *last_stmt = m_cmd_list->back (); + + octave::tree_command *cmd = last_stmt->command (); + + octave::tree_no_op_command *no_op_cmd = dynamic_cast <octave::tree_no_op_command *> (cmd); + + if (no_op_cmd && (no_op_cmd->is_end_of_fcn_or_script () || no_op_cmd->is_end_of_file ())) + no_op_cmd->attach_trailing_comments (lst); + } +} + +octave::comment_list octave_user_function::trailing_comments () const +{ + if (m_cmd_list && ! m_cmd_list->empty ()) + { + octave::tree_statement *last_stmt = m_cmd_list->back (); + + octave::tree_command *cmd = last_stmt->command (); + + octave::tree_no_op_command *no_op_cmd = dynamic_cast <octave::tree_no_op_command *> (cmd); + + if (no_op_cmd && (no_op_cmd->is_end_of_fcn_or_script () || no_op_cmd->is_end_of_file ())) + return no_op_cmd->trailing_comments (); + } + + return octave::comment_list (); +} + // If there is no explicit end statement at the end of the function, // relocate the no_op that was generated for the end of file condition // to appear on the next line after the last statement in the file, or
--- a/libinterp/octave-value/ov-usr-fcn.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.h Tue Apr 02 16:11:12 2024 -0400 @@ -35,6 +35,7 @@ #include "ov-fcn.h" #include "ov-typeinfo.h" #include "symscope.h" +#include "token.h" #include "unwind-prot.h" #if defined (OCTAVE_ENABLE_BYTECODE_EVALUATOR) # include "pt-bytecode.h" @@ -248,6 +249,11 @@ octave_user_function * define_ret_list (octave::tree_parameter_list *t); + void set_fcn_tok (const octave::token& fcn_tok) { m_fcn_tok = fcn_tok; } + void set_eq_tok (const octave::token& eq_tok) { m_eq_tok = eq_tok; } + + void attach_trailing_comments (const octave::comment_list& lst); + void stash_fcn_location (int line, int col) { m_location_line = line; @@ -270,10 +276,6 @@ void stash_parent_fcn_scope (const octave::symbol_scope& ps); - void stash_leading_comment (octave::comment_list *lc) { m_lead_comm = lc; } - - void stash_trailing_comment (octave::comment_list *tc) { m_trail_comm = tc; } - std::string profiler_name () const; std::string parent_fcn_name () const @@ -410,9 +412,8 @@ octave::tree_parameter_list * return_list () { return m_ret_list; } - octave::comment_list * leading_comment () { return m_lead_comm; } - - octave::comment_list * trailing_comment () { return m_trail_comm; } + octave::comment_list leading_comments () const { return m_fcn_tok.leading_comments (); } + octave::comment_list trailing_comments () const; // If is_special_expr is true, retrieve the sigular expression that forms the // body. May be null (even if is_special_expr is true). @@ -443,11 +444,10 @@ // this function. octave::tree_parameter_list *m_ret_list; - // The comments preceding the FUNCTION token. - octave::comment_list *m_lead_comm; - - // The comments preceding the ENDFUNCTION token. - octave::comment_list *m_trail_comm; + // FIXME: Should we also be caching the final token (END or EOF) as + // m_end_tok? + octave::token m_fcn_tok; + octave::token m_eq_tok; // Location where this function was defined. int m_location_line;
--- a/libinterp/parse-tree/comment-list.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/comment-list.h Tue Apr 02 16:11:12 2024 -0400 @@ -29,6 +29,7 @@ #include "octave-config.h" #include <list> +#include <memory> #include <string> OCTAVE_BEGIN_NAMESPACE(octave) @@ -105,31 +106,53 @@ bool m_uses_hash_char; }; -class comment_list : public std::list<comment_elt> +class comment_list { public: OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (comment_list) + typedef std::list<comment_elt>::reference reference; + typedef std::list<comment_elt>::const_reference const_reference; + + typedef std::list<comment_elt>::iterator iterator; + typedef std::list<comment_elt>::const_iterator const_iterator; + void append (const comment_elt& elt) { - push_back (elt); + m_list.push_back (elt); } void append (const std::string& s, comment_elt::comment_type t = comment_elt::unknown, bool uses_hash_char = false) { - push_back (comment_elt (s, t, uses_hash_char)); + m_list.push_back (comment_elt (s, t, uses_hash_char)); } + void clear () { m_list.clear (); } + + bool empty () const { return m_list.empty (); } + + reference front () { return m_list.front (); } + reference back () { return m_list.back (); } + + const_reference front () const { return m_list.front (); } + const_reference back () const { return m_list.back (); } + + iterator begin () { return m_list.begin (); } + iterator end () { return m_list.end (); } + + const_iterator begin () const { return m_list.begin (); } + const_iterator end () const { return m_list.end (); } + comment_list * dup () const; // Documentation for functions is typically the first block of // comments that doesn't look like a copyright statement. comment_elt find_doc_comment () const { - for (const auto& elt : *this) + for (const auto& elt : m_list) { // FIXME: should we also omit end-of-line comments? if (! elt.is_copyright ()) @@ -143,6 +166,10 @@ { return find_doc_comment().text (); } + +private: + + std::list<comment_elt> m_list; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/lex.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/lex.h Tue Apr 02 16:11:12 2024 -0400 @@ -483,7 +483,7 @@ std::string m_current_input_line; // The text of the current comment, used to gather comment lines - // before storing in m_comment_buf. + // before storing in m_comment_list. std::string m_comment_text; // The text of functions entered on the command line. @@ -559,52 +559,8 @@ bool m_eof; }; - // Collect comment text. - - class comment_buffer - { - public: - - comment_buffer () : m_comment_list (nullptr) { } - - OCTAVE_DISABLE_COPY_MOVE (comment_buffer) - - ~comment_buffer () { delete m_comment_list; } - - void append (const std::string& s, comment_elt::comment_type t, bool uses_hash_char) - { - if (! m_comment_list) - m_comment_list = new comment_list (); - - m_comment_list->append (s, t, uses_hash_char); - } - - // Caller is expected to delete the returned value. - - comment_list * get_comment_list () - { - comment_list *retval = m_comment_list; - - m_comment_list = nullptr; - - return retval; - } - - void reset () - { - delete m_comment_list; - - m_comment_list = nullptr; - } - - private: - - comment_list *m_comment_list; - }; - base_lexer (interpreter& interp) - : lexical_feedback (interp), m_scanner (nullptr), m_input_buf (), - m_comment_buf () + : lexical_feedback (interp), m_scanner (nullptr), m_input_buf () { init (); } @@ -661,7 +617,12 @@ void finish_comment (comment_elt::comment_type typ); - comment_list * get_comment_list () { return m_comment_buf.get_comment_list (); } + comment_list get_comment_list () + { + comment_list retval = m_comment_list; + m_comment_list.clear (); + return retval; + } int handle_close_bracket (int bracket_type); @@ -717,8 +678,8 @@ // Object that reads and buffers input. input_buffer m_input_buf; - // Object that collects comment text. - comment_buffer m_comment_buf; + // List of collected comments. + comment_list m_comment_list; virtual std::string input_source () const { return "unknown"; }
--- a/libinterp/parse-tree/lex.ll Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/lex.ll Tue Apr 02 16:11:12 2024 -0400 @@ -991,7 +991,7 @@ curr_lexer->m_looking_for_object_index = true; curr_lexer->m_at_beginning_of_statement = false; - octave::token *tok = new octave::token (DQ_STRING, curr_lexer->m_string_text, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); + octave::token *tok = new octave::token (DQ_STRING, curr_lexer->m_string_text, curr_lexer->m_tok_beg, curr_lexer->m_tok_end, curr_lexer->get_comment_list ()); curr_lexer->m_string_text = ""; @@ -1141,7 +1141,7 @@ curr_lexer->m_looking_for_object_index = true; curr_lexer->m_at_beginning_of_statement = false; - octave::token *tok = new octave::token (SQ_STRING, curr_lexer->m_string_text, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); + octave::token *tok = new octave::token (SQ_STRING, curr_lexer->m_string_text, curr_lexer->m_tok_beg, curr_lexer->m_tok_end, curr_lexer->get_comment_list ()); curr_lexer->m_string_text = ""; @@ -1407,7 +1407,7 @@ curr_lexer->m_looking_for_object_index = true; - tok = new octave::token (FCN_HANDLE, ident, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); + tok = new octave::token (FCN_HANDLE, ident, curr_lexer->m_tok_beg, curr_lexer->m_tok_end, curr_lexer->get_comment_list ()); return curr_lexer->handle_token (tok); } @@ -2441,7 +2441,7 @@ lexical_feedback::reset (); - m_comment_buf.reset (); + m_comment_list.clear (); } void @@ -2479,7 +2479,7 @@ syntax_error (msg); } - token *tok = new token (END_OF_INPUT, m_tok_beg, m_tok_end); + token *tok = new token (END_OF_INPUT, m_tok_beg, m_tok_end, get_comment_list ()); return handle_token (tok); } @@ -2644,47 +2644,47 @@ return nullptr; } - tok = new token (kw->tok_id, token::simple_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::simple_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case end_try_catch_kw: - tok = new token (kw->tok_id, token::try_catch_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::try_catch_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case end_unwind_protect_kw: - tok = new token (kw->tok_id, token::unwind_protect_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::unwind_protect_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endfor_kw: - tok = new token (kw->tok_id, token::for_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::for_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endfunction_kw: - tok = new token (kw->tok_id, token::function_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::function_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endif_kw: - tok = new token (kw->tok_id, token::if_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::if_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endparfor_kw: - tok = new token (kw->tok_id, token::parfor_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::parfor_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endswitch_kw: - tok = new token (kw->tok_id, token::switch_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::switch_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endwhile_kw: - tok = new token (kw->tok_id, token::while_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::while_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; @@ -2692,33 +2692,33 @@ #if defined (DISABLE_ARGUMENTS_VALIDATION_BLOCK) return nullptr; #else - tok = new token (kw->tok_id, token::arguments_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::arguments_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; #endif case endclassdef_kw: - tok = new token (kw->tok_id, token::classdef_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::classdef_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endenumeration_kw: - tok = new token (kw->tok_id, token::enumeration_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::enumeration_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endevents_kw: - tok = new token (kw->tok_id, token::events_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::events_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endmethods_kw: - tok = new token (kw->tok_id, token::methods_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::methods_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; case endproperties_kw: - tok = new token (kw->tok_id, token::properties_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::properties_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; @@ -2821,7 +2821,7 @@ break; case endspmd_kw: - tok = new token (kw->tok_id, token::spmd_end, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, token::spmd_end, m_tok_beg, m_tok_end, get_comment_list ()); m_at_beginning_of_statement = true; break; @@ -2830,9 +2830,9 @@ if ((m_reading_fcn_file || m_reading_script_file || m_reading_classdef_file) && ! m_fcn_file_full_name.empty ()) - tok = new token (kw->tok_id, m_fcn_file_full_name, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, m_fcn_file_full_name, m_tok_beg, m_tok_end, get_comment_list ()); else - tok = new token (kw->tok_id, "stdin", m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, "stdin", m_tok_beg, m_tok_end, get_comment_list ()); } break; @@ -2840,7 +2840,7 @@ { int l = m_tok_beg.line (); octave_value ov_value (static_cast<double> (l)); - tok = new token (kw->tok_id, ov_value, "", m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, ov_value, "", m_tok_beg, m_tok_end, get_comment_list ()); } break; @@ -2849,7 +2849,7 @@ } if (! tok) - tok = new token (kw->tok_id, true, m_tok_beg, m_tok_end); + tok = new token (kw->tok_id, true, m_tok_beg, m_tok_end, get_comment_list ()); return tok; } @@ -3036,7 +3036,7 @@ update_token_positions (flex_yyleng ()); - token *tok = new token (NUMBER, ov_value, yytxt, m_tok_beg, m_tok_end); + token *tok = new token (NUMBER, ov_value, yytxt, m_tok_beg, m_tok_end, get_comment_list ()); return handle_token (tok); } @@ -3158,7 +3158,7 @@ ? octave_value (Complex (0.0, value)) : octave_value (value)); - token *tok = new token (NUMBER, ov_value, yytxt, m_tok_beg, m_tok_end); + token *tok = new token (NUMBER, ov_value, yytxt, m_tok_beg, m_tok_end, get_comment_list ()); return handle_token (tok); } @@ -3229,7 +3229,7 @@ update_token_positions (flex_yyleng ()); - token *tok = new token (NUMBER, ov_value, yytxt, m_tok_beg, m_tok_end); + token *tok = new token (NUMBER, ov_value, yytxt, m_tok_beg, m_tok_end, get_comment_list ()); return handle_token (tok); } @@ -3307,7 +3307,7 @@ if (looks_like_copyright (m_comment_text)) typ = comment_elt::copyright; - m_comment_buf.append (m_comment_text, typ, m_comment_uses_hash_char); + m_comment_list.append (m_comment_text, typ, m_comment_uses_hash_char); m_comment_text = ""; m_comment_uses_hash_char = false; @@ -3373,7 +3373,7 @@ return syntax_error (msg); } - token *tok = new token (SUPERCLASSREF, meth, cls, m_tok_beg, m_tok_end); + token *tok = new token (SUPERCLASSREF, meth, cls, m_tok_beg, m_tok_end, get_comment_list ()); m_filepos.increment_column (flex_yyleng ()); @@ -3388,7 +3388,7 @@ m_looking_for_object_index = true; - token *tok = new token (METAQUERY, cls, m_tok_beg, m_tok_end); + token *tok = new token (METAQUERY, cls, m_tok_beg, m_tok_end, get_comment_list ()); m_filepos.increment_column (flex_yyleng ()); @@ -3403,7 +3403,7 @@ m_looking_for_object_index = true; - token *tok = new token (FQ_IDENT, ident, m_tok_beg, m_tok_end); + token *tok = new token (FQ_IDENT, ident, m_tok_beg, m_tok_end, get_comment_list ()); m_filepos.increment_column (flex_yyleng ()); @@ -3427,7 +3427,7 @@ if (m_looking_at_indirect_ref) { - token *tok = new token (STRUCT_ELT, ident, m_tok_beg, m_tok_end); + token *tok = new token (STRUCT_ELT, ident, m_tok_beg, m_tok_end, get_comment_list ()); m_looking_for_object_index = true; @@ -3452,7 +3452,7 @@ return handle_token (tok); } - tok = new token (NAME, ident, m_tok_beg, m_tok_end); + tok = new token (NAME, ident, m_tok_beg, m_tok_end, get_comment_list ()); // For compatibility with Matlab, the following symbols are // handled specially so that things like @@ -3889,7 +3889,7 @@ update_token_positions (flex_yyleng ()); - token *tok = new token (tok_id, m_tok_beg, m_tok_end); + token *tok = new token (tok_id, m_tok_beg, m_tok_end, get_comment_list ()); m_looking_for_object_index = false; m_at_beginning_of_statement = bos; @@ -3923,7 +3923,7 @@ int base_lexer::finish_command_arg () { - token *tok = new token (SQ_STRING, m_string_text, m_tok_beg, m_tok_end); + token *tok = new token (SQ_STRING, m_string_text, m_tok_beg, m_tok_end, get_comment_list ()); m_string_text = ""; m_command_arg_paren_count = 0;
--- a/libinterp/parse-tree/module.mk Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/module.mk Tue Apr 02 16:11:12 2024 -0400 @@ -27,6 +27,7 @@ %reldir%/pt-colon.h \ %reldir%/pt-const.h \ %reldir%/pt-decl.h \ + %reldir%/pt-delimiter-list.h \ %reldir%/pt-eval.h \ %reldir%/pt-except.h \ %reldir%/pt-exp.h \
--- a/libinterp/parse-tree/oct-parse.yy Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/oct-parse.yy Tue Apr 02 16:11:12 2024 -0400 @@ -141,9 +141,6 @@ // The type of the basic tokens returned by the lexer. octave::token *tok; - // Comment strings that we need to deal with mid-rule. - octave::comment_list *comment_type; - // Types for the nonterminals we generate. char punct_type; octave::tree *tree_type; @@ -190,10 +187,10 @@ octave::tree_classdef_property* tree_classdef_property_type; octave::tree_classdef_property_list* tree_classdef_property_list_type; octave::tree_classdef_properties_block* tree_classdef_properties_block_type; - octave::tree_classdef_methods_list* tree_classdef_methods_list_type; + octave::tree_classdef_method_list* tree_classdef_method_list_type; octave::tree_classdef_methods_block* tree_classdef_methods_block_type; octave::tree_classdef_event* tree_classdef_event_type; - octave::tree_classdef_events_list* tree_classdef_events_list_type; + octave::tree_classdef_event_list* tree_classdef_event_list_type; octave::tree_classdef_events_block* tree_classdef_events_block_type; octave::tree_classdef_enum* tree_classdef_enum_type; octave::tree_classdef_enum_list* tree_classdef_enum_list_type; @@ -242,12 +239,11 @@ // %token VARARGIN VARARGOUT // Nonterminals we construct. -%type <dummy_type> indirect_ref_op %type <dummy_type> push_fcn_symtab push_script_symtab begin_file -%type <dummy_type> param_list_beg param_list_end stmt_begin anon_fcn_begin +%type <dummy_type> stmt_begin anon_fcn_begin %type <dummy_type> parsing_local_fcns parse_error at_first_executable_stmt -%type <comment_type> stash_comment -%type <tok> function_beg classdef_beg arguments_beg +%type <tok> param_list_beg param_list_end +%type <tok> function_beg classdef_beg arguments_beg indirect_ref_op %type <tok> properties_beg methods_beg events_beg enumeration_beg %type <punct_type> sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep %type <tree_type> input @@ -275,8 +271,8 @@ %type <tree_classdef_type> classdef %type <tree_command_type> file %type <tree_if_command_type> if_command -%type <tree_if_clause_type> elseif_clause else_clause -%type <tree_if_command_list_type> if_cmd_list1 if_cmd_list +%type <tree_if_command_list_type> if_clause_list +%type <tree_if_clause_type> if_clause elseif_clause else_clause %type <tree_switch_command_type> switch_command %type <tree_switch_case_type> switch_case default_case %type <tree_switch_case_list_type> case_list1 case_list @@ -295,10 +291,10 @@ %type <tree_classdef_property_type> class_property %type <tree_classdef_property_list_type> property_list property_list1 %type <tree_classdef_properties_block_type> properties_block -%type <tree_classdef_methods_list_type> methods_list methods_list1 +%type <tree_classdef_method_list_type> method_list method_list1 %type <tree_classdef_methods_block_type> methods_block %type <tree_classdef_event_type> class_event -%type <tree_classdef_events_list_type> events_list events_list1 +%type <tree_classdef_event_list_type> event_list event_list1 %type <tree_classdef_events_block_type> events_block %type <tree_classdef_enum_type> class_enum %type <tree_classdef_enum_list_type> enum_list enum_list1 @@ -311,7 +307,6 @@ %type <tree_arg_size_spec_type> size_spec %type <tree_identifier_type> class_name %type <tree_arg_validation_fcns_type> validation_fcns -%type <tree_expression_type> default_value %type <octave_user_function_type> method_decl1 // Precedence and associativity. @@ -338,7 +333,6 @@ %destructor { } <tok> %destructor { } <punct_type> -%destructor { } <comment_type> %destructor { } <> %destructor { delete $$; } <tree_type> @@ -384,10 +378,10 @@ %destructor { delete $$; } <tree_classdef_property_type> %destructor { delete $$; } <tree_classdef_property_list_type> %destructor { delete $$; } <tree_classdef_properties_block_type> -%destructor { delete $$; } <tree_classdef_methods_list_type> +%destructor { delete $$; } <tree_classdef_method_list_type> %destructor { delete $$; } <tree_classdef_methods_block_type> %destructor { delete $$; } <tree_classdef_event_type> -%destructor { delete $$; } <tree_classdef_events_list_type> +%destructor { delete $$; } <tree_classdef_event_list_type> %destructor { delete $$; } <tree_classdef_events_block_type> %destructor { delete $$; } <tree_classdef_enum_type> %destructor { delete $$; } <tree_classdef_enum_list_type> @@ -523,7 +517,7 @@ word_list_cmd : identifier word_list { - $$ = parser.make_index_expression ($1, $2, '('); + $$ = parser.make_index_expression ($1, nullptr, $2, nullptr, '('); if (! $$) { // make_index_expression deleted $1 and $2. @@ -536,7 +530,7 @@ word_list : string { $$ = parser.make_argument_list ($1); } | word_list string - { $$ = parser.append_argument_list ($1, $2); } + { $$ = parser.append_argument_list ($1, nullptr, $2); } ; // =========== @@ -569,30 +563,26 @@ ; matrix : '[' matrix_rows ']' - { $$ = parser.finish_matrix ($2, $1, $3); } + { $$ = parser.finish_matrix ($1, $2, $3); } ; matrix_rows : cell_or_matrix_row { $$ = parser.make_matrix ($1); } | matrix_rows ';' cell_or_matrix_row { - OCTAVE_YYUSE ($2); - - $$ = parser.append_matrix_row ($1, $3); + $$ = parser.append_matrix_row ($1, $2, $3); } ; cell : '{' cell_rows '}' - { $$ = parser.finish_cell ($2, $1, $3); } + { $$ = parser.finish_cell ($1, $2, $3); } ; cell_rows : cell_or_matrix_row { $$ = parser.make_cell ($1); } | cell_rows ';' cell_or_matrix_row { - OCTAVE_YYUSE ($2); - - $$ = parser.append_cell_row ($1, $3); + $$ = parser.append_cell_row ($1, $2, $3); } ; @@ -685,9 +675,7 @@ { $$ = $1; } | '(' expression ')' { - OCTAVE_YYUSE ($1, $3); - - $$ = $2->mark_in_parens (); + $$ = $2->mark_in_delims (*($1), *($3)); } ; @@ -697,9 +685,7 @@ magic_tilde : '~' { - OCTAVE_YYUSE ($1); - - $$ = parser.make_black_hole (); + $$ = parser.make_black_hole ($1); } ; @@ -711,44 +697,35 @@ { $$ = parser.make_argument_list ($1); } | arg_list ',' magic_colon { - OCTAVE_YYUSE ($2); - - $$ = parser.append_argument_list ($1, $3); + $$ = parser.append_argument_list ($1, $2, $3); } | arg_list ',' magic_tilde { - OCTAVE_YYUSE ($2); - - $$ = parser.append_argument_list ($1, $3); + $$ = parser.append_argument_list ($1, $2, $3); } | arg_list ',' expression { - OCTAVE_YYUSE ($2); - - $$ = parser.append_argument_list ($1, $3); + $$ = parser.append_argument_list ($1, $2, $3); } ; indirect_ref_op : '.' { - OCTAVE_YYUSE ($1); - - $$ = 0; lexer.m_looking_at_indirect_ref = true; + $$ = $1; } ; oper_expr : primary_expr { $$ = $1; } | oper_expr PLUS_PLUS - { $$ = parser.make_postfix_op (PLUS_PLUS, $1, $2); } + { $$ = parser.make_postfix_op ($1, $2); } | oper_expr MINUS_MINUS - { $$ = parser.make_postfix_op (MINUS_MINUS, $1, $2); } + { $$ = parser.make_postfix_op ($1, $2); } | oper_expr '(' ')' { - OCTAVE_YYUSE ($2, $3); - - $$ = parser.make_index_expression ($1, nullptr, '('); + $$ = parser.make_index_expression ($1, $2, nullptr, $3, '('); + if (! $$) { // make_index_expression deleted $1. @@ -757,9 +734,8 @@ } | oper_expr '(' arg_list ')' { - OCTAVE_YYUSE ($2, $4); - - $$ = parser.make_index_expression ($1, $3, '('); + $$ = parser.make_index_expression ($1, $2, $3, $4, '('); + if (! $$) { // make_index_expression deleted $1 and $3. @@ -768,9 +744,8 @@ } | oper_expr '{' '}' { - OCTAVE_YYUSE ($2, $3); - - $$ = parser.make_index_expression ($1, nullptr, '{'); + $$ = parser.make_index_expression ($1, $2, nullptr, $3, '{'); + if (! $$) { // make_index_expression deleted $1. @@ -779,9 +754,8 @@ } | oper_expr '{' arg_list '}' { - OCTAVE_YYUSE ($2, $4); - - $$ = parser.make_index_expression ($1, $3, '{'); + $$ = parser.make_index_expression ($1, $2, $3, $4, '{'); + if (! $$) { // make_index_expression deleted $1 and $3. @@ -789,62 +763,57 @@ } } | oper_expr HERMITIAN - { $$ = parser.make_postfix_op (HERMITIAN, $1, $2); } + { $$ = parser.make_postfix_op ($1, $2); } | oper_expr TRANSPOSE - { $$ = parser.make_postfix_op (TRANSPOSE, $1, $2); } + { $$ = parser.make_postfix_op ($1, $2); } | oper_expr indirect_ref_op STRUCT_ELT - { $$ = parser.make_indirect_ref ($1, $3->text ()); } + { $$ = parser.make_indirect_ref ($1, $2, $3); } | oper_expr indirect_ref_op '(' expression ')' - { - OCTAVE_YYUSE ($3, $5); - - $$ = parser.make_indirect_ref ($1, $4); - } + { $$ = parser.make_indirect_ref ($1, $2, $3, $4, $5); } | PLUS_PLUS oper_expr %prec UNARY - { $$ = parser.make_prefix_op (PLUS_PLUS, $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | MINUS_MINUS oper_expr %prec UNARY - { $$ = parser.make_prefix_op (MINUS_MINUS, $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '~' oper_expr %prec UNARY - { $$ = parser.make_prefix_op ('~', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '!' oper_expr %prec UNARY - { $$ = parser.make_prefix_op ('!', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '+' oper_expr %prec UNARY - { $$ = parser.make_prefix_op ('+', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '-' oper_expr %prec UNARY - { $$ = parser.make_prefix_op ('-', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | oper_expr POW power_expr - { $$ = parser.make_binary_op (POW, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr EPOW power_expr - { $$ = parser.make_binary_op (EPOW, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr '+' oper_expr - { $$ = parser.make_binary_op ('+', $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr '-' oper_expr - { $$ = parser.make_binary_op ('-', $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr '*' oper_expr - { $$ = parser.make_binary_op ('*', $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr '/' oper_expr - { $$ = parser.make_binary_op ('/', $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr EMUL oper_expr - { $$ = parser.make_binary_op (EMUL, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr EDIV oper_expr - { $$ = parser.make_binary_op (EDIV, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr LEFTDIV oper_expr - { $$ = parser.make_binary_op (LEFTDIV, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | oper_expr ELEFTDIV oper_expr - { $$ = parser.make_binary_op (ELEFTDIV, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } ; power_expr : primary_expr { $$ = $1; } | power_expr PLUS_PLUS - { $$ = parser.make_postfix_op (PLUS_PLUS, $1, $2); } + { $$ = parser.make_postfix_op ($1, $2); } | power_expr MINUS_MINUS - { $$ = parser.make_postfix_op (MINUS_MINUS, $1, $2); } + { $$ = parser.make_postfix_op ($1, $2); } | power_expr '(' ')' { - OCTAVE_YYUSE ($2, $3); - - $$ = parser.make_index_expression ($1, nullptr, '('); + $$ = parser.make_index_expression ($1, $2, nullptr, $3, '('); + if (! $$) { // make_index_expression deleted $1. @@ -853,9 +822,8 @@ } | power_expr '(' arg_list ')' { - OCTAVE_YYUSE ($2, $4); - - $$ = parser.make_index_expression ($1, $3, '('); + $$ = parser.make_index_expression ($1, $2, $3, $4, '('); + if (! $$) { // make_index_expression deleted $1 and $3. @@ -864,9 +832,8 @@ } | power_expr '{' '}' { - OCTAVE_YYUSE ($2, $3); - - $$ = parser.make_index_expression ($1, nullptr, '{'); + $$ = parser.make_index_expression ($1, $2, nullptr, $3, '{'); + if (! $$) { // make_index_expression deleted $1. @@ -875,9 +842,8 @@ } | power_expr '{' arg_list '}' { - OCTAVE_YYUSE ($2, $4); - - $$ = parser.make_index_expression ($1, $3, '{'); + $$ = parser.make_index_expression ($1, $2, $3, $4, '{'); + if (! $$) { // make_index_expression deleted $1 and $3. @@ -885,32 +851,26 @@ } } | power_expr indirect_ref_op STRUCT_ELT - { $$ = parser.make_indirect_ref ($1, $3->text ()); } + { $$ = parser.make_indirect_ref ($1, $2, $3); } | power_expr indirect_ref_op '(' expression ')' - { - OCTAVE_YYUSE ($3, $5); - - $$ = parser.make_indirect_ref ($1, $4); - } + { $$ = parser.make_indirect_ref ($1, $2, $3, $4, $5); } | PLUS_PLUS power_expr %prec POW - { $$ = parser.make_prefix_op (PLUS_PLUS, $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | MINUS_MINUS power_expr %prec POW - { $$ = parser.make_prefix_op (MINUS_MINUS, $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '~' power_expr %prec POW - { $$ = parser.make_prefix_op ('~', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '!' power_expr %prec POW - { $$ = parser.make_prefix_op ('!', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '+' power_expr %prec POW - { $$ = parser.make_prefix_op ('+', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } | '-' power_expr %prec POW - { $$ = parser.make_prefix_op ('-', $2, $1); } + { $$ = parser.make_prefix_op ($1, $2); } ; colon_expr : oper_expr ':' oper_expr { - OCTAVE_YYUSE ($2); - - $$ = parser.make_colon_expression ($1, $3); + $$ = parser.make_colon_expression ($1, $2, $3); if (! $$) { @@ -920,9 +880,7 @@ } | oper_expr ':' oper_expr ':' oper_expr { - OCTAVE_YYUSE ($2, $4); - - $$ = parser.make_colon_expression ($1, $5, $3); + $$ = parser.make_colon_expression ($1, $2, $3, $4, $5); if (! $$) { @@ -937,25 +895,25 @@ | colon_expr { $$ = $1; } | simple_expr EXPR_LT simple_expr - { $$ = parser.make_binary_op (EXPR_LT, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_LE simple_expr - { $$ = parser.make_binary_op (EXPR_LE, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_EQ simple_expr - { $$ = parser.make_binary_op (EXPR_EQ, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_GE simple_expr - { $$ = parser.make_binary_op (EXPR_GE, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_GT simple_expr - { $$ = parser.make_binary_op (EXPR_GT, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_NE simple_expr - { $$ = parser.make_binary_op (EXPR_NE, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_AND simple_expr - { $$ = parser.make_binary_op (EXPR_AND, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_OR simple_expr - { $$ = parser.make_binary_op (EXPR_OR, $1, $2, $3); } + { $$ = parser.make_binary_op ($1, $2, $3); } | simple_expr EXPR_AND_AND simple_expr - { $$ = parser.make_boolean_op (EXPR_AND_AND, $1, $2, $3); } + { $$ = parser.make_boolean_op ($1, $2, $3); } | simple_expr EXPR_OR_OR simple_expr - { $$ = parser.make_boolean_op (EXPR_OR_OR, $1, $2, $3); } + { $$ = parser.make_boolean_op ($1, $2, $3); } ; assign_lhs : simple_expr @@ -973,31 +931,31 @@ ; assign_expr : assign_lhs '=' expression - { $$ = parser.make_assign_op ('=', $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs ADD_EQ expression - { $$ = parser.make_assign_op (ADD_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs SUB_EQ expression - { $$ = parser.make_assign_op (SUB_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs MUL_EQ expression - { $$ = parser.make_assign_op (MUL_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs DIV_EQ expression - { $$ = parser.make_assign_op (DIV_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs LEFTDIV_EQ expression - { $$ = parser.make_assign_op (LEFTDIV_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs POW_EQ expression - { $$ = parser.make_assign_op (POW_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs EMUL_EQ expression - { $$ = parser.make_assign_op (EMUL_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs EDIV_EQ expression - { $$ = parser.make_assign_op (EDIV_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs ELEFTDIV_EQ expression - { $$ = parser.make_assign_op (ELEFTDIV_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs EPOW_EQ expression - { $$ = parser.make_assign_op (EPOW_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs AND_EQ expression - { $$ = parser.make_assign_op (AND_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } | assign_lhs OR_EQ expression - { $$ = parser.make_assign_op (OR_EQ, $1, $2, $3); } + { $$ = parser.make_assign_op ($1, $2, $3); } ; expression : simple_expr @@ -1052,12 +1010,12 @@ declaration : GLOBAL decl_init_list { - $$ = parser.make_decl_command (GLOBAL, $1, $2); + $$ = parser.make_decl_command ($1, $2); lexer.m_looking_at_decl_list = false; } | PERSISTENT decl_init_list { - $$ = parser.make_decl_command (PERSISTENT, $1, $2); + $$ = parser.make_decl_command ($1, $2); lexer.m_looking_at_decl_list = false; } ; @@ -1088,49 +1046,45 @@ // If statement // ============ -if_command : IF stash_comment if_cmd_list END +if_command : if_clause_list else_clause END { - if (! ($$ = parser.finish_if_command ($1, $3, $4, $2))) + if (! ($$ = parser.finish_if_command ($1, $2, $3))) { - // finish_if_command deleted $3. + // finish_if_command deleted $1 and $2. YYABORT; } } ; -if_cmd_list : if_cmd_list1 - { $$ = $1; } - | if_cmd_list1 else_clause - { $$ = parser.append_if_clause ($1, $2); } - ; - -if_cmd_list1 : expression stmt_begin opt_sep opt_list - { - OCTAVE_YYUSE ($3); - - parser.maybe_convert_to_braindead_shortcircuit ($1); - - $$ = parser.start_if_command ($1, $4); - } - | if_cmd_list1 elseif_clause +if_clause_list : if_clause + { $$ = parser.start_if_command ($1); } + | if_clause_list elseif_clause { $$ = parser.append_if_clause ($1, $2); } ; -elseif_clause : ELSEIF stash_comment opt_sep expression stmt_begin opt_sep opt_list +if_clause : IF opt_sep expression stmt_begin opt_sep opt_list { - OCTAVE_YYUSE ($3, $6); - - parser.maybe_convert_to_braindead_shortcircuit ($4); - - $$ = parser.make_elseif_clause ($1, $4, $7, $2); + OCTAVE_YYUSE ($2, $5); + + $$ = parser.make_if_clause ($1, $3, $6); } ; -else_clause : ELSE stash_comment opt_sep opt_list +elseif_clause : ELSEIF opt_sep expression stmt_begin opt_sep opt_list { - OCTAVE_YYUSE ($3); - - $$ = parser.make_else_clause ($1, $2, $4); + OCTAVE_YYUSE ($2, $5); + + $$ = parser.make_if_clause ($1, $3, $6); + } + ; + +else_clause : // empty + { $$ = nullptr; } + | ELSE opt_sep opt_list + { + OCTAVE_YYUSE ($2); + + $$ = parser.make_if_clause ($1, nullptr, $3); } ; @@ -1138,13 +1092,13 @@ // Switch statement // ================ -switch_command : SWITCH stash_comment expression opt_sep case_list END +switch_command : SWITCH expression opt_sep case_list END { - OCTAVE_YYUSE ($4); - - if (! ($$ = parser.finish_switch_command ($1, $3, $5, $6, $2))) + OCTAVE_YYUSE ($3); + + if (! ($$ = parser.finish_switch_command ($1, $2, $4, $5))) { - // finish_switch_command deleted $3 adn $5. + // finish_switch_command deleted $2 and $4. YYABORT; } } @@ -1166,19 +1120,19 @@ { $$ = parser.append_switch_case ($1, $2); } ; -switch_case : CASE stash_comment opt_sep expression stmt_begin opt_sep opt_list +switch_case : CASE opt_sep expression stmt_begin opt_sep opt_list { - OCTAVE_YYUSE ($3, $6); - - $$ = parser.make_switch_case ($1, $4, $7, $2); + OCTAVE_YYUSE ($2, $5); + + $$ = parser.make_switch_case ($1, $3, $6); } ; -default_case : OTHERWISE stash_comment opt_sep opt_list +default_case : OTHERWISE opt_sep opt_list { - OCTAVE_YYUSE ($3); - - $$ = parser.make_default_switch_case ($1, $2, $4); + OCTAVE_YYUSE ($2); + + $$ = parser.make_default_switch_case ($1, $3); } ; @@ -1186,65 +1140,61 @@ // Looping // ======= -loop_command : WHILE stash_comment expression stmt_begin opt_sep opt_list END +loop_command : WHILE expression stmt_begin opt_sep opt_list END { - OCTAVE_YYUSE ($5); - - parser.maybe_convert_to_braindead_shortcircuit ($3); - - if (! ($$ = parser.make_while_command ($1, $3, $6, $7, $2))) + OCTAVE_YYUSE ($4); + + parser.maybe_convert_to_braindead_shortcircuit ($2); + + if (! ($$ = parser.make_while_command ($1, $2, $5, $6))) { - // make_while_command deleted $3 and $6. + // make_while_command deleted $2 and $5. YYABORT; } } - | DO stash_comment opt_sep opt_list UNTIL expression + | DO opt_sep opt_list UNTIL expression { - OCTAVE_YYUSE ($1, $3); - - $$ = parser.make_do_until_command ($5, $4, $6, $2); + OCTAVE_YYUSE ($2); + + $$ = parser.make_do_until_command ($1, $3, $4, $5); } - | FOR stash_comment assign_lhs '=' expression stmt_begin opt_sep opt_list END + | FOR assign_lhs '=' expression stmt_begin opt_sep opt_list END { - OCTAVE_YYUSE ($4, $7); - - if (! ($$ = parser.make_for_command (FOR, $1, $3, $5, - nullptr, $8, $9, $2))) + OCTAVE_YYUSE ($6); + + if (! ($$ = parser.make_for_command ($1, nullptr, $2, $3, $4, nullptr, nullptr, nullptr, $7, $8))) + { + // make_for_command deleted $2, $4, and $7. + YYABORT; + } + } + | FOR '(' assign_lhs '=' expression ')' opt_sep opt_list END + { + OCTAVE_YYUSE ($2, $4, $6, $7); + + if (! ($$ = parser.make_for_command ($1, $2, $3, $4, $5, nullptr, nullptr, $6, $8, $9))) { // make_for_command deleted $3, $5, and $8. YYABORT; } } - | FOR stash_comment '(' assign_lhs '=' expression ')' opt_sep opt_list END + | PARFOR assign_lhs '=' expression stmt_begin opt_sep opt_list END { - OCTAVE_YYUSE ($3, $5, $7, $8); - - if (! ($$ = parser.make_for_command (FOR, $1, $4, $6, - nullptr, $9, $10, $2))) + OCTAVE_YYUSE ($3, $6); + + if (! ($$ = parser.make_for_command ($1, nullptr, $2, $3, $4, nullptr, nullptr, nullptr, $7, $8))) { - // make_for_command deleted $4, $6, and $9. + // make_for_command deleted $2, $4, and $7. YYABORT; } } - | PARFOR stash_comment assign_lhs '=' expression stmt_begin opt_sep opt_list END + | PARFOR '(' assign_lhs '=' expression ',' expression ')' opt_sep opt_list END { - OCTAVE_YYUSE ($4, $7); - - if (! ($$ = parser.make_for_command (PARFOR, $1, $3, $5, - nullptr, $8, $9, $2))) + OCTAVE_YYUSE ($2, $4, $6, $8, $9); + + if (! ($$ = parser.make_for_command ($1, $2, $3, $4, $5, $6, $7, $8, $10, $11))) { - // make_for_command deleted $3, $5, and $8. - YYABORT; - } - } - | PARFOR stash_comment '(' assign_lhs '=' expression ',' expression ')' opt_sep opt_list END - { - OCTAVE_YYUSE ($3, $5, $7, $9, $10); - - if (! ($$ = parser.make_for_command (PARFOR, $1, $4, $6, - $8, $11, $12, $2))) - { - // make_for_command deleted $4, $6, $8, and $11. + // make_for_command deleted $3, $5, $7, and $10. YYABORT; } } @@ -1272,16 +1222,13 @@ // Parallel execution pool // ======================= -spmd_command : SPMD stash_comment opt_sep opt_list END +spmd_command : SPMD opt_sep opt_list END { - OCTAVE_YYUSE ($3); - - octave::comment_list *lc = $2; - octave::comment_list *tc = lexer.get_comment_list (); - - if (! ($$ = parser.make_spmd_command ($1, $4, $5, lc, tc))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_spmd_command ($1, $3, $4))) { - // make_spmd_command deleted $4, LC, and TC. + // make_spmd_command deleted $3. YYABORT; } } @@ -1291,36 +1238,33 @@ // Exceptions // ========== -except_command : UNWIND stash_comment opt_sep opt_list CLEANUP - stash_comment opt_sep opt_list END +except_command : UNWIND opt_sep opt_list CLEANUP opt_sep opt_list END { - OCTAVE_YYUSE ($3, $5, $7); - - if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6))) + OCTAVE_YYUSE ($2, $5); + + if (! ($$ = parser.make_unwind_command ($1, $3, $4, $6, $7))) { - // make_unwind_command deleted $4 and $8. + // make_unwind_command deleted $3 and $6. YYABORT; } } - | TRY stash_comment opt_sep opt_list CATCH stash_comment - opt_sep opt_list END + | TRY opt_sep opt_list CATCH opt_sep opt_list END { - OCTAVE_YYUSE ($3, $5, $7); - - if (! ($$ = parser.make_try_command ($1, $4, $7, $8, $9, $2, $6))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_try_command ($1, $3, $4, $5, $6, $7))) { - // make_try_command deleted $4 and $8. + // make_try_command deleted $3 and $6. YYABORT; } } - | TRY stash_comment opt_sep opt_list END + | TRY opt_sep opt_list END { - OCTAVE_YYUSE ($3); - - if (! ($$ = parser.make_try_command ($1, $4, 0, nullptr, - $5, $2, nullptr))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_try_command ($1, $3, nullptr, 0, nullptr, $4))) { - // make_try_command deleted $4. + // make_try_command deleted $3. YYABORT; } } @@ -1345,9 +1289,6 @@ param_list_beg : '(' { - OCTAVE_YYUSE ($1); - - $$ = 0; lexer.m_looking_at_parameter_list = true; lexer.m_arguments_is_keyword = false; @@ -1358,17 +1299,18 @@ lexer.m_looking_at_function_handle--; lexer.m_looking_at_anon_fcn_args = true; } + + $$ = $1; } ; param_list_end : ')' { - OCTAVE_YYUSE ($1); - - $$ = 0; lexer.m_looking_at_parameter_list = false; lexer.m_arguments_is_keyword = true; lexer.m_looking_for_object_index = false; + + $$ = $1; } ; @@ -1383,11 +1325,14 @@ if ($2) lexer.mark_as_variables ($2->variable_names ()); - $$ = $2; + $$ = $2->mark_in_delims (*($1), *($3)); } | param_list_beg error { + OCTAVE_YYUSE ($1); + $$ = nullptr; + parser.bison_error ("invalid parameter list"); YYABORT; } @@ -1416,9 +1361,7 @@ { $$ = parser.make_parameter_list (octave::tree_parameter_list::in, $1); } | param_list2 ',' param_list_elt { - OCTAVE_YYUSE ($2); - - $$ = parser.append_parameter_list ($1, $3); + $$ = parser.append_parameter_list ($1, $2, $3); } ; @@ -1434,18 +1377,17 @@ return_list : '[' ']' { - OCTAVE_YYUSE ($1, $2); - lexer.m_looking_at_return_list = false; - $$ = parser.make_parameter_list (octave::tree_parameter_list::out); + octave::tree_parameter_list *tmp = parser.make_parameter_list (octave::tree_parameter_list::out); + + $$ = tmp->mark_in_delims (*($1), *($2)); } | identifier { lexer.m_looking_at_return_list = false; - octave::tree_parameter_list *tmp - = parser.make_parameter_list (octave::tree_parameter_list::out, $1); + octave::tree_parameter_list *tmp = parser.make_parameter_list (octave::tree_parameter_list::out, $1); // Even though this parameter list can contain only // a single identifier, we still need to validate it @@ -1461,15 +1403,13 @@ } | '[' return_list1 ']' { - OCTAVE_YYUSE ($1, $3); - lexer.m_looking_at_return_list = false; // Check for duplicate parameter names, varargin, // or varargout. if (parser.validate_param_list ($2, octave::tree_parameter_list::out)) - $$ = $2; + $$ = $2->mark_in_delims (*($1), *($3)); else { delete $2; @@ -1484,9 +1424,7 @@ } | return_list1 ',' identifier { - OCTAVE_YYUSE ($2); - - $$ = parser.append_parameter_list ($1, $3); + $$ = parser.append_parameter_list ($1, $2, $3); } ; @@ -1533,8 +1471,7 @@ else { octave::tree_statement *end_of_script - = parser.make_end ("endscript", true, - $4->beg_pos (), $4->end_pos ()); + = parser.make_end ("endscript", true, $4, $4->beg_pos (), $4->end_pos ()); parser.make_script ($3, end_of_script); } @@ -1546,12 +1483,12 @@ } | begin_file opt_nl classdef parsing_local_fcns opt_sep opt_fcn_list END_OF_INPUT { - OCTAVE_YYUSE ($2, $5, $7); + OCTAVE_YYUSE ($2, $5); // Unused symbol table context. lexer.m_symtab_context.pop (); - if (! parser.finish_classdef_file ($3, $6)) + if (! parser.finish_classdef_file ($3, $6, $7)) YYABORT; $$ = nullptr; @@ -1583,9 +1520,7 @@ } | GET '.' identifier { - OCTAVE_YYUSE ($1, $2); - - $$ = $3; + $$ = $3->mark_get_set (*($1), *($2)); lexer.m_parsed_function_name.top () = true; lexer.m_maybe_classdef_get_set_method = false; @@ -1594,9 +1529,7 @@ } | SET '.' identifier { - OCTAVE_YYUSE ($1, $2); - - $$ = $3; + $$ = $3->mark_get_set (*($1), *($2)); lexer.m_parsed_function_name.top () = true; lexer.m_maybe_classdef_get_set_method = false; @@ -1610,8 +1543,7 @@ parser.endfunction_found (true); if (parser.end_token_ok ($1, octave::token::function_end)) - $$ = parser.make_end ("endfunction", false, - $1->beg_pos (), $1->end_pos ()); + $$ = parser.make_end ("endfunction", false, $1, $1->beg_pos (), $1->end_pos ()); else { parser.end_token_error ($1, octave::token::function_end); @@ -1648,29 +1580,26 @@ YYABORT; } - $$ = parser.make_end ("endfunction", true, - $1->beg_pos (), $1->end_pos ()); + $$ = parser.make_end ("endfunction", true, $1, $1->beg_pos (), $1->end_pos ()); } ; -function : function_beg stash_comment fcn_name opt_param_list opt_sep stash_comment function_body function_end +function : function_beg fcn_name opt_param_list opt_sep function_body function_end { - OCTAVE_YYUSE ($5); - - $$ = parser.make_function ($1, nullptr, $3, $4, $7, $8, $2, $6); + OCTAVE_YYUSE ($4); + + $$ = parser.make_function ($1, nullptr, nullptr, $2, $3, $5, $6); } - | function_beg stash_comment return_list '=' fcn_name opt_param_list opt_sep stash_comment function_body function_end + | function_beg return_list '=' fcn_name opt_param_list opt_sep function_body function_end { - OCTAVE_YYUSE ($4, $7); - - $$ = parser.make_function ($1, $3, $5, $6, $9, $10, $2, $8); + OCTAVE_YYUSE ($6); + + $$ = parser.make_function ($1, $2, $3, $4, $5, $7, $8); } ; function_body : at_first_executable_stmt opt_list { - OCTAVE_YYUSE ($1); - $$ = $2; } | function_body1 opt_sep at_first_executable_stmt opt_list @@ -1684,7 +1613,6 @@ at_first_executable_stmt : // empty { - $$ = 0; lexer.m_arguments_is_keyword = false; } ; @@ -1703,17 +1631,13 @@ } ; -arguments_block : arguments_beg stash_comment opt_sep args_attr_list - args_validation_list opt_sep END +arguments_block : arguments_beg opt_sep args_attr_list args_validation_list opt_sep END { - OCTAVE_YYUSE ($3, $6); - - octave::comment_list *lc = $2; - octave::comment_list *tc = lexer.get_comment_list (); - - if (! ($$ = parser.make_arguments_block ($1, $4, $5, $7, lc, tc))) + OCTAVE_YYUSE ($2, $5); + + if (! ($$ = parser.make_arguments_block ($1, $3, $4, $6))) { - // make_arguments_block deleted $4, $5, LC, and TC. + // make_arguments_block deleted $3, and $4. YYABORT; } @@ -1732,7 +1656,7 @@ { $$ = nullptr; } | '(' identifier ')' { - OCTAVE_YYUSE ($1, $3); + $2->mark_in_delims (*($1), *($3)); // Error if $$ is nullptr. if (! ($$ = parser.make_args_attribute_list ($2))) @@ -1766,21 +1690,29 @@ { $$ = $1; } ; -arg_validation : size_spec class_name validation_fcns default_value - { - if (! ($$ = parser.make_arg_validation ($1, $2, $3, $4))) - { - // make_arg_validation deleted ... - YYABORT; - } - } +arg_validation : size_spec class_name validation_fcns + { + if (! ($$ = parser.make_arg_validation ($1, $2, $3))) + { + // make_arg_validation deleted ... + YYABORT; + } + } + | size_spec class_name validation_fcns '=' expression + { + if (! ($$ = parser.make_arg_validation ($1, $2, $3, $4, $5))) + { + // make_arg_validation deleted ... + YYABORT; + } + } ; size_spec : // empty { $$ = nullptr; } | '(' arg_list ')' { - OCTAVE_YYUSE ($1, $3); + $2->mark_in_delims (*($1), *($3)); if (! ($$ = parser.make_arg_size_spec ($2))) { @@ -1801,7 +1733,7 @@ { $$ = nullptr; } | '{' arg_list '}' { - OCTAVE_YYUSE ($1, $3); + $2->mark_in_delims (*($1), *($3)); if (! ($$ = parser.make_arg_validation_fcns ($2))) { @@ -1811,16 +1743,6 @@ } ; -default_value : // empty - { $$ = nullptr; } - | '=' expression - { - OCTAVE_YYUSE ($1); - - $$ = $2; - } - ; - // ======== // Classdef // ======== @@ -1843,15 +1765,15 @@ } ; -classdef : classdef_beg stash_comment attr_list identifier opt_sep superclass_list stash_comment class_body stash_comment END +classdef : classdef_beg attr_list identifier opt_sep superclass_list class_body END { - OCTAVE_YYUSE ($5); + OCTAVE_YYUSE ($4); lexer.m_parsing_classdef = false; - if (! ($$ = parser.make_classdef ($1, $3, $4, $6, $8, $10, $2, $7, $9))) + if (! ($$ = parser.make_classdef ($1, $2, $3, $5, $6, $7))) { - // make_classdef deleted $2, $3, $4, $6, $7, $8, $9 + // make_classdef deleted $2, $3, $5, $6 YYABORT; } } @@ -1861,9 +1783,9 @@ { $$ = nullptr; } | '(' attr_list1 ')' opt_sep { - OCTAVE_YYUSE ($1, $3, $4); - - $$ = $2; + OCTAVE_YYUSE ($4); + + $$ = $2->mark_in_delims (*($1), *($3)); } ; @@ -1871,9 +1793,7 @@ { $$ = parser.make_classdef_attribute_list ($1); } | attr_list1 ',' attr { - OCTAVE_YYUSE ($2); - - $$ = parser.append_classdef_attribute ($1, $3); + $$ = parser.append_classdef_attribute ($1, $2, $3); } ; @@ -1881,21 +1801,15 @@ { $$ = parser.make_classdef_attribute ($1); } | identifier '=' expression { - OCTAVE_YYUSE ($2); - - $$ = parser.make_classdef_attribute ($1, $3); + $$ = parser.make_classdef_attribute ($1, $2, $3); } | '~' identifier { - OCTAVE_YYUSE ($1); - - $$ = parser.make_not_classdef_attribute ($2); + $$ = parser.make_not_classdef_attribute ($1, $2); } | '!' identifier { - OCTAVE_YYUSE ($1); - - $$ = parser.make_not_classdef_attribute ($2); + $$ = parser.make_not_classdef_attribute ($1, $2); } ; @@ -1920,15 +1834,11 @@ superclass_list1 : EXPR_LT superclass { - OCTAVE_YYUSE ($1); - - $$ = parser.make_classdef_superclass_list ($2); + $$ = parser.make_classdef_superclass_list ($1, $2); } | superclass_list1 EXPR_AND superclass { - OCTAVE_YYUSE ($2); - - $$ = parser.append_classdef_superclass ($1, $3); + $$ = parser.append_classdef_superclass ($1, $2, $3); } ; @@ -1985,18 +1895,13 @@ ; properties_block - : properties_beg stash_comment opt_sep attr_list property_list END + : properties_beg opt_sep attr_list property_list END { - OCTAVE_YYUSE ($3); - - octave::comment_list *lc = $2; - octave::comment_list *tc = lexer.get_comment_list (); - - if (! ($$ = parser.make_classdef_properties_block - ($1, $4, $5, $6, lc, tc))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_classdef_properties_block ($1, $3, $4, $5))) { - // make_classdef_properties_block deleted $4, - // $5, LC, and TC. + // make_classdef_properties_block deleted $3 and $4. YYABORT; } } @@ -2035,18 +1940,18 @@ // identifier that becomes the next element in the // list. If the element at the end of the list // doesn't have a doc string, see whether the - // element we are adding is stroing an end-of-line + // element we are adding is storing an end-of-line // comment for us to use. octave::tree_classdef_property *last_elt = $1->back (); if (! last_elt->have_doc_string ()) { - octave::comment_list *cl = $3->comments (); - - if (cl) + octave::comment_list comments = $3->leading_comments (); + + if (! comments.empty ()) { - octave::comment_elt elt = cl->front (); + octave::comment_elt elt = comments.front (); if (elt.is_end_of_line ()) last_elt->doc_string (elt.text ()); @@ -2057,22 +1962,17 @@ } ; -class_property : stash_comment identifier arg_validation - { $$ = parser.make_classdef_property ($1, $2, $3); } +class_property : identifier arg_validation + { $$ = parser.make_classdef_property ($1, $2); } ; -methods_block : methods_beg stash_comment opt_sep attr_list methods_list END +methods_block : methods_beg opt_sep attr_list method_list END { - OCTAVE_YYUSE ($3); - - octave::comment_list *lc = $2; - octave::comment_list *tc = lexer.get_comment_list (); - - if (! ($$ = parser.make_classdef_methods_block - ($1, $4, $5, $6, lc, tc))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_classdef_methods_block ($1, $3, $4, $5))) { - // make_classdef_methods_block deleted $4, $5, - // LC, and TC. + // make_classdef_methods_block deleted $3 and $4. YYABORT; } } @@ -2087,7 +1987,7 @@ method_decl1 : identifier { - if (! ($$ = parser.start_classdef_external_method ($1, nullptr))) + if (! ($$ = parser.start_classdef_external_method ($1))) YYABORT; } | identifier param_list @@ -2097,12 +1997,12 @@ } ; -method_decl : stash_comment method_decl1 - { $$ = parser.finish_classdef_external_method ($2, nullptr, $1); } - | stash_comment return_list '=' +method_decl : method_decl1 { - OCTAVE_YYUSE ($3); - + $$ = parser.finish_classdef_external_method ($1); + } + | return_list '=' + { lexer.m_defining_fcn++; lexer.m_parsed_function_name.push (false); } @@ -2111,7 +2011,7 @@ lexer.m_defining_fcn--; lexer.m_parsed_function_name.pop (); - $$ = parser.finish_classdef_external_method ($5, $2, $1); + $$ = parser.finish_classdef_external_method ($4, $1, $2); } ; @@ -2121,12 +2021,12 @@ { $$ = $1; } ; -methods_list : // empty +method_list : // empty { lexer.m_classdef_element_names_are_keywords = true; $$ = nullptr; } - | methods_list1 opt_sep + | method_list1 opt_sep { OCTAVE_YYUSE ($2); @@ -2135,9 +2035,9 @@ } ; -methods_list1 : method - { $$ = parser.make_classdef_methods_list ($1); } - | methods_list1 opt_sep method +method_list1 : method + { $$ = parser.make_classdef_method_list ($1); } + | method_list1 opt_sep method { OCTAVE_YYUSE ($2); @@ -2145,18 +2045,13 @@ } ; -events_block : events_beg stash_comment opt_sep attr_list events_list END +events_block : events_beg opt_sep attr_list event_list END { - OCTAVE_YYUSE ($3); - - octave::comment_list *lc = $2; - octave::comment_list *tc = lexer.get_comment_list (); - - if (! ($$ = parser.make_classdef_events_block - ($1, $4, $5, $6, lc, tc))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_classdef_events_block ($1, $3, $4, $5))) { - // make_classdef_events_block deleted $4, $5, - // LC, and TC. + // make_classdef_events_block deleted $4 and $5. YYABORT; } } @@ -2169,12 +2064,12 @@ } ; -events_list : // empty +event_list : // empty { lexer.m_classdef_element_names_are_keywords = true; $$ = nullptr; } - | events_list1 opt_sep + | event_list1 opt_sep { OCTAVE_YYUSE ($2); @@ -2183,9 +2078,9 @@ } ; -events_list1 : class_event - { $$ = parser.make_classdef_events_list ($1); } - | events_list1 opt_sep class_event +event_list1 : class_event + { $$ = parser.make_classdef_event_list ($1); } + | event_list1 opt_sep class_event { OCTAVE_YYUSE ($2); @@ -2193,22 +2088,17 @@ } ; -class_event : stash_comment identifier - { $$ = parser.make_classdef_event ($1, $2); } +class_event : identifier + { $$ = parser.make_classdef_event ($1); } ; -enum_block : enumeration_beg stash_comment opt_sep attr_list enum_list END +enum_block : enumeration_beg opt_sep attr_list enum_list END { - OCTAVE_YYUSE ($3); - - octave::comment_list *lc = $2; - octave::comment_list *tc = lexer.get_comment_list (); - - if (! ($$ = parser.make_classdef_enum_block - ($1, $4, $5, $6, lc, tc))) + OCTAVE_YYUSE ($2); + + if (! ($$ = parser.make_classdef_enum_block ($1, $3, $4, $5))) { - // make_classdef_enum_block deleted $4, $5, LC, - // and TC. + // make_classdef_enum_block deleted $3 and $4. YYABORT; } } @@ -2245,11 +2135,9 @@ } ; -class_enum : stash_comment identifier '(' expression ')' +class_enum : identifier '(' expression ')' { - OCTAVE_YYUSE ($3, $5); - - $$ = parser.make_classdef_enum ($2, $4, $1); + $$ = parser.make_classdef_enum ($1, $2, $3, $4); } ; @@ -2272,12 +2160,6 @@ } ; -stash_comment : // empty - { - $$ = lexer.get_comment_list (); - } - ; - parse_error : LEXICAL_ERROR { $$ = 0; @@ -2533,6 +2415,15 @@ return list; } + template <typename LIST_T, typename ELT_T> + static LIST_T * + list_append (LIST_T *list, const token& /*sep_tok*/, ELT_T elt) + { + // FIXME XXX! need to capture SEP_TOK here + list->push_back (elt); + return list; + } + std::size_t base_parser::parent_scope_info::size () const { @@ -2886,9 +2777,9 @@ } tree_black_hole * - base_parser::make_black_hole () - { - return new tree_black_hole (); + base_parser::make_black_hole (token *tilde) + { + return new tree_black_hole (*tilde); } // Make a function handle. @@ -2973,9 +2864,13 @@ // Build a colon expression. tree_expression * - base_parser::make_colon_expression (tree_expression *base, - tree_expression *limit, - tree_expression *incr) + base_parser::make_colon_expression (tree_expression *base, token *colon_tok, tree_expression *limit) + { + return make_colon_expression (base, colon_tok, nullptr, nullptr, limit); + } + + tree_expression * + base_parser::make_colon_expression (tree_expression *base, token *colon_1_tok, tree_expression *incr, token *colon_2_tok, tree_expression *limit) { tree_expression *retval = nullptr; @@ -2991,8 +2886,10 @@ int l = base->line (); int c = base->column (); + token tmp_colon_2_tok = colon_2_tok ? *colon_2_tok : token (); + tree_colon_expression *expr - = new tree_colon_expression (base, limit, incr, l, c); + = new tree_colon_expression (base, *colon_1_tok, incr, tmp_colon_2_tok, limit, l, c); retval = expr; @@ -3053,12 +2950,11 @@ // Build a binary expression. tree_expression * - base_parser::make_binary_op (int op, tree_expression *op1, - token *tok, tree_expression *op2) + base_parser::make_binary_op (tree_expression *op1, token *op_tok, tree_expression *op2) { octave_value::binary_op t = octave_value::unknown_binary_op; - switch (op) + switch (op_tok->token_id ()) { case POW: t = octave_value::op_pow; @@ -3137,8 +3033,8 @@ break; } - int l = tok->line (); - int c = tok->column (); + int l = op_tok->line (); + int c = op_tok->column (); return maybe_compound_binary_expression (op1, op2, l, c, t); } @@ -3181,12 +3077,11 @@ // Build a boolean expression. tree_expression * - base_parser::make_boolean_op (int op, tree_expression *op1, - token *tok, tree_expression *op2) + base_parser::make_boolean_op (tree_expression *op1, token *op_tok, tree_expression *op2) { tree_boolean_expression::type t; - switch (op) + switch (op_tok->token_id ()) { case EXPR_AND_AND: t = tree_boolean_expression::bool_and; @@ -3201,8 +3096,8 @@ break; } - int l = tok->line (); - int c = tok->column (); + int l = op_tok->line (); + int c = op_tok->column (); return new tree_boolean_expression (op1, op2, l, c, t); } @@ -3210,11 +3105,11 @@ // Build a prefix expression. tree_expression * - base_parser::make_prefix_op (int op, tree_expression *op1, token *tok) + base_parser::make_prefix_op (token *op_tok, tree_expression *op1) { octave_value::unary_op t = octave_value::unknown_unary_op; - switch (op) + switch (op_tok->token_id ()) { case '~': case '!': @@ -3242,8 +3137,8 @@ break; } - int l = tok->line (); - int c = tok->column (); + int l = op_tok->line (); + int c = op_tok->column (); return new tree_prefix_expression (op1, l, c, t); } @@ -3251,11 +3146,11 @@ // Build a postfix expression. tree_expression * - base_parser::make_postfix_op (int op, tree_expression *op1, token *tok) + base_parser::make_postfix_op (tree_expression *op1, token *op_tok) { octave_value::unary_op t = octave_value::unknown_unary_op; - switch (op) + switch (op_tok->token_id ()) { case HERMITIAN: t = octave_value::op_hermitian; @@ -3278,8 +3173,8 @@ break; } - int l = tok->line (); - int c = tok->column (); + int l = op_tok->line (); + int c = op_tok->column (); return new tree_postfix_expression (op1, l, c, t); } @@ -3287,24 +3182,16 @@ // Build an unwind-protect command. tree_command * - base_parser::make_unwind_command (token *unwind_tok, - tree_statement_list *body, - tree_statement_list *cleanup_stmts, - token *end_tok, - comment_list *lc, - comment_list *mc) + base_parser::make_unwind_command (token *unwind_tok, tree_statement_list *body, token *cleanup_tok, tree_statement_list *cleanup_stmts, token *end_tok) { tree_command *retval = nullptr; if (end_token_ok (end_tok, token::unwind_protect_end)) { - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - int l = unwind_tok->line (); int c = unwind_tok->column (); - retval = new tree_unwind_protect_command (body, cleanup_stmts, - lc, mc, tc, l, c); + retval = new tree_unwind_protect_command (*unwind_tok, body, *cleanup_tok, cleanup_stmts, *end_tok, l, c); } else { @@ -3320,25 +3207,20 @@ // Build a try-catch command. tree_command * - base_parser::make_try_command (token *try_tok, - tree_statement_list *body, - char catch_sep, - tree_statement_list *cleanup_stmts, - token *end_tok, - comment_list *lc, - comment_list *mc) + base_parser::make_try_command (token *try_tok, tree_statement_list *body, token *catch_tok, char catch_sep, tree_statement_list *cleanup_stmts, token *end_tok) { tree_command *retval = nullptr; if (end_token_ok (end_tok, token::try_catch_end)) { - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - int l = try_tok->line (); int c = try_tok->column (); tree_identifier *id = nullptr; + // Look for exception ID. Could this be done in the grammar or + // does that create another shift-reduce conflict? + if (! catch_sep && cleanup_stmts && ! cleanup_stmts->empty ()) { tree_statement *stmt = cleanup_stmts->front (); @@ -3359,8 +3241,9 @@ } } - retval = new tree_try_catch_command (body, cleanup_stmts, id, - lc, mc, tc, l, c); + token tmp_catch_tok = catch_tok ? *catch_tok : token (); + + retval = new tree_try_catch_command (*try_tok, body, tmp_catch_tok, id, cleanup_stmts, *end_tok, l, c); } else { @@ -3376,11 +3259,7 @@ // Build a while command. tree_command * - base_parser::make_while_command (token *while_tok, - tree_expression *expr, - tree_statement_list *body, - token *end_tok, - comment_list *lc) + base_parser::make_while_command (token *while_tok, tree_expression *expr, tree_statement_list *body, token *end_tok) { tree_command *retval = nullptr; @@ -3388,14 +3267,12 @@ if (end_token_ok (end_tok, token::while_end)) { - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - m_lexer.m_looping--; int l = while_tok->line (); int c = while_tok->column (); - retval = new tree_while_command (expr, body, lc, tc, l, c); + retval = new tree_while_command (*while_tok, expr, body, *end_tok, l, c); } else { @@ -3411,44 +3288,35 @@ // Build a do-until command. tree_command * - base_parser::make_do_until_command (token *until_tok, - tree_statement_list *body, - tree_expression *expr, - comment_list *lc) + base_parser::make_do_until_command (token *do_tok, tree_statement_list *body, token *until_tok, tree_expression *expr) { maybe_warn_assign_as_truth_value (expr); - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - m_lexer.m_looping--; int l = until_tok->line (); int c = until_tok->column (); - return new tree_do_until_command (expr, body, lc, tc, l, c); + return new tree_do_until_command (*do_tok, body, *until_tok, expr, l, c); } // Build a for command. tree_command * - base_parser::make_for_command (int tok_id, token *for_tok, - tree_argument_list *lhs, - tree_expression *expr, - tree_expression *maxproc, - tree_statement_list *body, - token *end_tok, - comment_list *lc) + base_parser::make_for_command (token *for_tok, token *open_paren, tree_argument_list *lhs, token *eq_tok, tree_expression *expr, token *sep_tok, tree_expression *maxproc, token *close_paren, tree_statement_list *body, token *end_tok) { tree_command *retval = nullptr; - bool parfor = tok_id == PARFOR; + bool parfor = for_tok->token_id () == PARFOR; + + token tmp_open_paren = open_paren ? *open_paren : token (); + token tmp_close_paren = close_paren ? *close_paren : token (); + token tmp_sep_tok = sep_tok ? *sep_tok : token (); if (end_token_ok (end_tok, parfor ? token::parfor_end : token::for_end)) { expr->mark_as_for_cmd_expr (); - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - m_lexer.m_looping--; int l = for_tok->line (); @@ -3460,8 +3328,7 @@ m_lexer.mark_as_variable (tmp->name ()); - retval = new tree_simple_for_command (parfor, tmp, expr, maxproc, - body, lc, tc, l, c); + retval = new tree_simple_for_command (parfor, *for_tok, tmp_open_paren, tmp, *eq_tok, expr, tmp_sep_tok, maxproc, tmp_close_paren, body, *end_tok, l, c); delete lhs; } @@ -3478,8 +3345,7 @@ { m_lexer.mark_as_variables (lhs->variable_names ()); - retval = new tree_complex_for_command (lhs, expr, body, - lc, tc, l, c); + retval = new tree_complex_for_command (*for_tok, lhs, *eq_tok, expr, body, *end_tok, l, c); } } else @@ -3543,9 +3409,7 @@ // Build an spmd command. tree_spmd_command * - base_parser::make_spmd_command (token *spmd_tok, tree_statement_list *body, - token *end_tok, comment_list *lc, - comment_list *tc) + base_parser::make_spmd_command (token *spmd_tok, tree_statement_list *body, token *end_tok) { tree_spmd_command *retval = nullptr; @@ -3554,13 +3418,11 @@ int l = spmd_tok->line (); int c = spmd_tok->column (); - retval = new tree_spmd_command (body, lc, tc, l, c); + retval = new tree_spmd_command (body, l, c); } else { delete body; - delete lc; - delete tc; end_token_error (end_tok, token::spmd_end); } @@ -3571,51 +3433,42 @@ // Start an if command. tree_if_command_list * - base_parser::start_if_command (tree_expression *expr, - tree_statement_list *list) - { - maybe_warn_assign_as_truth_value (expr); - - // Line and column will be set in finish_if_command. - - tree_if_clause *t = new tree_if_clause (expr, list); - - return new tree_if_command_list (t); + base_parser::start_if_command (tree_if_clause *clause) + { + return new tree_if_command_list (clause); } // Finish an if command. tree_if_command * - base_parser::finish_if_command (token *if_tok, - tree_if_command_list *list, - token *end_tok, - comment_list *lc) + base_parser::finish_if_command (tree_if_command_list *list, tree_if_clause *else_clause, token *end_tok) { tree_if_command *retval = nullptr; if (end_token_ok (end_tok, token::if_end)) { - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - - int l = if_tok->line (); - int c = if_tok->column (); - - if (list && ! list->empty ()) + if (else_clause) + list_append (list, else_clause); + + token if_tok = list->if_token (); + + int l = if_tok.line (); + int c = if_tok.column (); + + tree_if_clause *elt = list->front (); + + if (elt) { - tree_if_clause *elt = list->front (); - - if (elt) - { - elt->line (l); - elt->column (c); - } + elt->line (l); + elt->column (c); } - retval = new tree_if_command (list, lc, tc, l, c); + retval = new tree_if_command (if_tok, list, *end_tok, l, c); } else { delete list; + delete else_clause; end_token_error (end_tok, token::if_end); } @@ -3623,35 +3476,26 @@ return retval; } - // Build an elseif clause. + // Build an if, elseif, or else clause. tree_if_clause * - base_parser::make_elseif_clause (token *elseif_tok, - tree_expression *expr, - tree_statement_list *list, - comment_list *lc) - { - maybe_warn_assign_as_truth_value (expr); - - int l = elseif_tok->line (); - int c = elseif_tok->column (); - - return new tree_if_clause (expr, list, lc, l, c); - } - - tree_if_clause * - base_parser::make_else_clause (token *else_tok, comment_list *lc, - tree_statement_list *list) - { - int l = else_tok->line (); - int c = else_tok->column (); - - return new tree_if_clause (list, lc, l, c); + base_parser::make_if_clause (token *tok, tree_expression *expr, tree_statement_list *list) + { + if (expr) + { + maybe_warn_assign_as_truth_value (expr); + + maybe_convert_to_braindead_shortcircuit (expr); + } + + int l = tok->line (); + int c = tok->column (); + + return new tree_if_clause (*tok, expr, list, l, c); } tree_if_command_list * - base_parser::append_if_clause (tree_if_command_list *list, - tree_if_clause *clause) + base_parser::append_if_clause (tree_if_command_list *list, tree_if_clause *clause) { return list_append (list, clause); } @@ -3659,18 +3503,12 @@ // Finish a switch command. tree_switch_command * - base_parser::finish_switch_command (token *switch_tok, - tree_expression *expr, - tree_switch_case_list *list, - token *end_tok, - comment_list *lc) + base_parser::finish_switch_command (token *switch_tok, tree_expression *expr, tree_switch_case_list *list, token *end_tok) { tree_switch_command *retval = nullptr; if (end_token_ok (end_tok, token::switch_end)) { - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - int l = switch_tok->line (); int c = switch_tok->column (); @@ -3685,7 +3523,7 @@ } } - retval = new tree_switch_command (expr, list, lc, tc, l, c); + retval = new tree_switch_command (*switch_tok, expr, list, *end_tok, l, c); } else { @@ -3707,27 +3545,23 @@ // Build a switch case. tree_switch_case * - base_parser::make_switch_case (token *case_tok, - tree_expression *expr, - tree_statement_list *list, - comment_list *lc) + base_parser::make_switch_case (token *case_tok, tree_expression *expr, tree_statement_list *list) { maybe_warn_variable_switch_label (expr); int l = case_tok->line (); int c = case_tok->column (); - return new tree_switch_case (expr, list, lc, l, c); + return new tree_switch_case (*case_tok, expr, list, l, c); } tree_switch_case * - base_parser::make_default_switch_case (token *default_tok, comment_list *lc, - tree_statement_list *list) + base_parser::make_default_switch_case (token *default_tok, tree_statement_list *list) { int l = default_tok->line (); int c = default_tok->column (); - return new tree_switch_case (list, lc, l, c); + return new tree_switch_case (*default_tok, list, l, c); } tree_switch_case_list * @@ -3740,12 +3574,11 @@ // Build an assignment to a variable. tree_expression * - base_parser::make_assign_op (int op, tree_argument_list *lhs, - token *eq_tok, tree_expression *rhs) + base_parser::make_assign_op (tree_argument_list *lhs, token *eq_tok, tree_expression *rhs) { octave_value::assign_op t = octave_value::unknown_assign_op; - switch (op) + switch (eq_tok->token_id ()) { case '=': t = octave_value::op_asn_eq; @@ -3894,12 +3727,9 @@ // First non-copyright comment in classdef body, before first // properties, methods, etc. block. - tree_statement *first_stmt = cmds->front (); - comment_list *leading_comments = first_stmt->comment_text (); - - std::string doc_string; - if (leading_comments) - doc_string = leading_comments->find_doc_string (); + comment_list leading_comments = cmds->leading_comments (); + + std::string doc_string = leading_comments.find_doc_string (); octave_user_script *script = new octave_user_script (m_lexer.m_fcn_file_full_name, @@ -3951,23 +3781,31 @@ // for a large mess. Maybe this could be a bit better organized? tree_function_def * - base_parser::make_function (token *fcn_tok, - tree_parameter_list *ret_list, - tree_identifier *id, - tree_parameter_list *param_list, - tree_statement_list *body, - tree_statement *end_fcn_stmt, - comment_list *lc, comment_list *bc) + base_parser::make_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, tree_identifier *id, tree_parameter_list *param_list, tree_statement_list *body, tree_statement *end_fcn_stmt) { // First non-copyright comments found above and below function keyword. comment_elt leading_doc_comment; comment_elt body_doc_comment; - if (lc) - leading_doc_comment = lc->find_doc_comment (); - - if (bc) - body_doc_comment = bc->find_doc_comment (); + comment_list lc = fcn_tok->leading_comments (); + + if (! lc.empty ()) + leading_doc_comment = lc.find_doc_comment (); + + if (body) + { + comment_list bc = body->leading_comments (); + + if (! bc.empty ()) + body_doc_comment = bc.find_doc_comment (); + } + else if (end_fcn_stmt) + { + comment_list ec = end_fcn_stmt->leading_comments (); + + if (! ec.empty ()) + body_doc_comment = ec.find_doc_comment (); + } // Choose which comment to use for doc string. @@ -4004,7 +3842,7 @@ octave_user_function *tmp_fcn = start_function (id, param_list, body, end_fcn_stmt, doc_string); - tree_function_def *retval = finish_function (ret_list, tmp_fcn, lc, l, c); + tree_function_def *retval = finish_function (fcn_tok, ret_list, eq_tok, tmp_fcn, l, c); recover_from_parsing_function (); @@ -4043,9 +3881,6 @@ = new octave_user_function (m_lexer.m_symtab_context.curr_scope (), param_list, nullptr, body); - comment_list *tc = m_lexer.m_comment_buf.get_comment_list (); - - fcn->stash_trailing_comment (tc); fcn->stash_fcn_end_location (end_fcn_stmt->line (), end_fcn_stmt->column ()); @@ -4146,20 +3981,17 @@ } tree_statement * - base_parser::make_end (const std::string& type, bool eof, + base_parser::make_end (const std::string& type, bool eof, token *end_tok, const filepos& beg_pos, const filepos& /*end_pos*/) { int l = beg_pos.line (); int c = beg_pos.column (); - return make_statement (new tree_no_op_command (type, eof, l, c)); + return make_statement (new tree_no_op_command (type, eof, *end_tok, l, c)); } tree_function_def * - base_parser::finish_function (tree_parameter_list *ret_list, - octave_user_function *fcn, - comment_list *lc, - int l, int c) + base_parser::finish_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, octave_user_function *fcn, int l, int c) { tree_function_def *retval = nullptr; @@ -4170,6 +4002,11 @@ if (fcn) { + fcn->set_fcn_tok (*fcn_tok); + + if (eq_tok) + fcn->set_eq_tok (*eq_tok); + std::string fcn_nm = fcn->name (); std::string file = fcn->fcn_file_name (); @@ -4183,9 +4020,6 @@ fcn_scope.cache_fcn_file_name (file); fcn_scope.cache_dir_name (m_lexer.m_dir_name); - if (lc) - fcn->stash_leading_comment (lc); - fcn->define_ret_list (ret_list); if (m_curr_fcn_depth > 0 || m_parsing_subfunctions) @@ -4267,11 +4101,7 @@ } tree_arguments_block * - base_parser::make_arguments_block (token *arguments_tok, - tree_args_block_attribute_list *attr_list, - tree_args_block_validation_list *validation_list, - token *end_tok, - comment_list *lc, comment_list *tc) + base_parser::make_arguments_block (token *arguments_tok, tree_args_block_attribute_list *attr_list, tree_args_block_validation_list *validation_list, token *end_tok) { tree_arguments_block *retval = nullptr; @@ -4288,9 +4118,6 @@ { delete attr_list; delete validation_list; - - delete lc; - delete tc; } return retval; @@ -4300,13 +4127,15 @@ base_parser::make_arg_validation (tree_arg_size_spec *size_spec, tree_identifier *class_name, tree_arg_validation_fcns *validation_fcns, + token *eq_tok, tree_expression *default_value) { // FIXME: Validate arguments and convert to more specific types // (std::string for arg_name and class_name, etc). - return new tree_arg_validation (size_spec, class_name, - validation_fcns, default_value); + token tmp_eq_tok = eq_tok ? *eq_tok : token (); + + return new tree_arg_validation (size_spec, class_name, validation_fcns, tmp_eq_tok, default_value); } tree_args_block_attribute_list * @@ -4371,17 +4200,8 @@ // and methods, and adding to the list of known objects) and creates // a parse tree containing meta information about the class. - // LC contains comments appearing before the classdef keyword. - // TC contains comments appearing between the classdef elements - // and the final end token for the classdef block. - tree_classdef * - base_parser::make_classdef (token *tok, - tree_classdef_attribute_list *a, - tree_identifier *id, - tree_classdef_superclass_list *sc, - tree_classdef_body *body, token *end_tok, - comment_list *lc, comment_list *bc, comment_list *tc) + base_parser::make_classdef (token *cdef_tok, tree_classdef_attribute_list *a, tree_identifier *id, tree_classdef_superclass_list *sc, tree_classdef_body *body, token *end_tok) { tree_classdef *retval = nullptr; @@ -4407,9 +4227,6 @@ delete id; delete sc; delete body; - delete lc; - delete bc; - delete tc; bison_error ("invalid classdef definition, the class name must match the filename", l, c); @@ -4418,29 +4235,13 @@ { if (end_token_ok (end_tok, token::classdef_end)) { - int l = tok->line (); - int c = tok->column (); - - // First non-copyright comments found above and below - // function keyword are candidates for the documentation - // string. Use the first one that is not empty. - - std::string doc_string; - - if (lc) - doc_string = lc->find_doc_string (); - - if (doc_string.empty () && bc) - doc_string = bc->find_doc_string (); + int l = cdef_tok->line (); + int c = cdef_tok->column (); if (! body) body = new tree_classdef_body (); - // FIXME - pass body comment to tree_classdef constructor. - - retval = new tree_classdef (m_lexer.m_symtab_context.curr_scope (), - doc_string, a, id, sc, body, lc, tc, - m_curr_package_name, full_name, l, c); + retval = new tree_classdef (m_lexer.m_symtab_context.curr_scope (), *cdef_tok, a, id, sc, body, *end_tok, m_curr_package_name, full_name, l, c); } else { @@ -4448,9 +4249,6 @@ delete id; delete sc; delete body; - delete lc; - delete bc; - delete tc; end_token_error (end_tok, token::switch_end); } @@ -4459,22 +4257,8 @@ return retval; } - // LC contains comments appearing before the properties keyword. - // If this properties block appears first in the list of classdef - // elements, this comment list will be used for the help text for the - // classdef block. - - // TC contains comments appearing between the list of properties - // and the final end token for the properties block and may be used to - // find the doc string for the final property in the list. - tree_classdef_properties_block * - base_parser::make_classdef_properties_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_property_list *plist, - token *end_tok, - comment_list *lc, - comment_list *tc) + base_parser::make_classdef_properties_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_property_list *plist, token *end_tok) { tree_classdef_properties_block *retval = nullptr; @@ -4486,37 +4270,34 @@ if (plist) { // If the element at the end of the list doesn't have a doc - // string, see whether the first element of TC is an - // end-of-line comment for us to use. - - if (tc) + // string, see whether the first element of the comments + // attached to the end token is an end-of-line comment for + // us to use. + + tree_classdef_property *last_elt = plist->back (); + + if (last_elt && ! last_elt->have_doc_string ()) { - tree_classdef_property *last_elt = plist->back (); - - if (! last_elt->have_doc_string ()) + comment_list comments = end_tok->leading_comments (); + + if (! comments.empty ()) { - comment_elt first_comment_elt = tc->front (); - - if (first_comment_elt.is_end_of_line ()) - { - std::string eol_comment = first_comment_elt.text (); - - last_elt->doc_string (eol_comment); - } + comment_elt elt = comments.front (); + + if (elt.is_end_of_line ()) + last_elt->doc_string (elt.text ()); } } } else plist = new tree_classdef_property_list (); - retval = new tree_classdef_properties_block (a, plist, lc, tc, l, c); + retval = new tree_classdef_properties_block (*tok, a, plist, *end_tok, l, c); } else { delete a; delete plist; - delete lc; - delete tc; end_token_error (end_tok, token::properties_end); } @@ -4531,28 +4312,18 @@ } tree_classdef_property * - base_parser::make_classdef_property (comment_list *lc, tree_identifier *id, - tree_arg_validation *av) + base_parser::make_classdef_property (tree_identifier *id, tree_arg_validation *av) { av->arg_name (id); if (av->size_spec () || av->class_name () || av->validation_fcns ()) warning ("size, class, and validation function specifications are not yet supported for classdef properties; INCORRECT RESULTS ARE POSSIBLE!"); - return new tree_classdef_property (av, lc); - } - - // LC contains comments appearing before the methods keyword. - // If this methods block appears first in the list of classdef - // elements, this comment list will be used for the help text for the - // classdef block. + return new tree_classdef_property (av); + } tree_classdef_methods_block * - base_parser::make_classdef_methods_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_methods_list *mlist, - token *end_tok, comment_list *lc, - comment_list *tc) + base_parser::make_classdef_methods_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_method_list *mlist, token *end_tok) { tree_classdef_methods_block *retval = nullptr; @@ -4562,16 +4333,14 @@ int c = tok->column (); if (! mlist) - mlist = new tree_classdef_methods_list (); - - retval = new tree_classdef_methods_block (a, mlist, lc, tc, l, c); + mlist = new tree_classdef_method_list (); + + retval = new tree_classdef_methods_block (*tok, a, mlist, *end_tok, l, c); } else { delete a; delete mlist; - delete lc; - delete tc; end_token_error (end_tok, token::methods_end); } @@ -4579,22 +4348,8 @@ return retval; } - // LC contains comments appearing before the events keyword. - // If this events block appears first in the list of classdef - // elements, this comment list will be used for the help text for the - // classdef block. - - // TC contains comments appearing between the list of events and - // the final end token for the events block and may be used to find - // the doc string for the final event in the list. - tree_classdef_events_block * - base_parser::make_classdef_events_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_events_list *elist, - token *end_tok, - comment_list *lc, - comment_list *tc) + base_parser::make_classdef_events_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_event_list *elist, token *end_tok) { tree_classdef_events_block *retval = nullptr; @@ -4604,16 +4359,14 @@ int c = tok->column (); if (! elist) - elist = new tree_classdef_events_list (); - - retval = new tree_classdef_events_block (a, elist, lc, tc, l, c); + elist = new tree_classdef_event_list (); + + retval = new tree_classdef_events_block (*tok, a, elist, *end_tok, l, c); } else { delete a; delete elist; - delete lc; - delete tc; end_token_error (end_tok, token::events_end); } @@ -4621,35 +4374,20 @@ return retval; } - tree_classdef_events_list * - base_parser::make_classdef_events_list (tree_classdef_event *e) - { - return new tree_classdef_events_list (e); + tree_classdef_event_list * + base_parser::make_classdef_event_list (tree_classdef_event *e) + { + return new tree_classdef_event_list (e); } tree_classdef_event * - base_parser::make_classdef_event (comment_list *lc, tree_identifier *id) - { - return new tree_classdef_event (id, lc); - } - - // LC contains comments appearing before the enumeration keyword. - // If this enumeration block appears first in the list of classdef - // elements, this comment list will be used for the help text for the - // classdef block. - - // TC contains comments appearing between the list of - // enumerations and the final end token for the enumeration block and - // may be used to find the doc string for the final enumeration in the - // list. + base_parser::make_classdef_event (tree_identifier *id) + { + return new tree_classdef_event (id); + } tree_classdef_enum_block * - base_parser::make_classdef_enum_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_enum_list *elist, - token *end_tok, - comment_list *lc, - comment_list *tc) + base_parser::make_classdef_enum_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_enum_list *elist, token *end_tok) { tree_classdef_enum_block *retval = nullptr; @@ -4661,14 +4399,12 @@ if (! elist) elist = new tree_classdef_enum_list (); - retval = new tree_classdef_enum_block (a, elist, lc, tc, l, c); + retval = new tree_classdef_enum_block (*tok, a, elist, *end_tok, l, c); } else { delete a; delete elist; - delete lc; - delete tc; end_token_error (end_tok, token::enumeration_end); } @@ -4683,10 +4419,9 @@ } tree_classdef_enum * - base_parser::make_classdef_enum (tree_identifier *id, tree_expression *expr, - comment_list *lc) - { - return new tree_classdef_enum (id, expr, lc); + base_parser::make_classdef_enum (tree_identifier *id, token *open_paren, tree_expression *expr, token *close_paren) + { + return new tree_classdef_enum (id, *open_paren, expr, *close_paren); } tree_classdef_property_list * @@ -4696,8 +4431,8 @@ return list_append (list, elt); } - tree_classdef_events_list * - base_parser::append_classdef_event (tree_classdef_events_list *list, + tree_classdef_event_list * + base_parser::append_classdef_event (tree_classdef_event_list *list, tree_classdef_event *elt) { return list_append (list, elt); @@ -4711,21 +4446,24 @@ } tree_classdef_superclass_list * - base_parser::make_classdef_superclass_list (tree_classdef_superclass *sc) - { + base_parser::make_classdef_superclass_list (token *lt_tok, tree_classdef_superclass *sc) + { + sc->set_separator (*lt_tok); + return new tree_classdef_superclass_list (sc); } tree_classdef_superclass * base_parser::make_classdef_superclass (token *fqident) { - return new tree_classdef_superclass (fqident->text ()); + return new tree_classdef_superclass (*fqident); } tree_classdef_superclass_list * - base_parser::append_classdef_superclass (tree_classdef_superclass_list *list, - tree_classdef_superclass *elt) - { + base_parser::append_classdef_superclass (tree_classdef_superclass_list *list, token *and_tok, tree_classdef_superclass *elt) + { + elt->set_separator (*and_tok); + return list_append (list, elt); } @@ -4736,25 +4474,29 @@ } tree_classdef_attribute * - base_parser::make_classdef_attribute (tree_identifier *id, - tree_expression *expr) + base_parser::make_classdef_attribute (tree_identifier *id) + { + return make_classdef_attribute (id, nullptr, nullptr); + } + + tree_classdef_attribute * + base_parser::make_classdef_attribute (tree_identifier *id, token *eq_tok, tree_expression *expr) { return (expr - ? new tree_classdef_attribute (id, expr) + ? new tree_classdef_attribute (id, *eq_tok, expr) : new tree_classdef_attribute (id)); } tree_classdef_attribute * - base_parser::make_not_classdef_attribute (tree_identifier *id) - { - return new tree_classdef_attribute (id, false); + base_parser::make_not_classdef_attribute (token *not_tok, tree_identifier *id) + { + return new tree_classdef_attribute (*not_tok, id, false); } tree_classdef_attribute_list * - base_parser::append_classdef_attribute (tree_classdef_attribute_list *list, - tree_classdef_attribute *elt) - { - return list_append (list, elt); + base_parser::append_classdef_attribute (tree_classdef_attribute_list *list, token *sep_tok, tree_classdef_attribute *elt) + { + return list_append (list, *sep_tok, elt); } tree_classdef_body * @@ -4859,17 +4601,15 @@ } tree_function_def * - base_parser::finish_classdef_external_method (octave_user_function *fcn, - tree_parameter_list *ret_list, - comment_list *cl) + base_parser::finish_classdef_external_method (octave_user_function *fcn, tree_parameter_list *ret_list, token *eq_tok) { if (! ret_list) ret_list = new tree_parameter_list (tree_parameter_list::out); fcn->define_ret_list (ret_list); - if (cl) - fcn->stash_leading_comment (cl); + if (eq_tok) + fcn->set_eq_tok (*eq_tok); int l = fcn->beginning_line (); int c = fcn->beginning_column (); @@ -4877,8 +4617,8 @@ return new tree_function_def (fcn, l, c); } - tree_classdef_methods_list * - base_parser::make_classdef_methods_list (tree_function_def *fcn_def) + tree_classdef_method_list * + base_parser::make_classdef_method_list (tree_function_def *fcn_def) { octave_value fcn; @@ -4887,11 +4627,11 @@ delete fcn_def; - return new tree_classdef_methods_list (fcn); - } - - tree_classdef_methods_list * - base_parser::append_classdef_method (tree_classdef_methods_list *list, + return new tree_classdef_method_list (fcn); + } + + tree_classdef_method_list * + base_parser::append_classdef_method (tree_classdef_method_list *list, tree_function_def *fcn_def) { octave_value fcn; @@ -4907,8 +4647,7 @@ } bool - base_parser::finish_classdef_file (tree_classdef *cls, - tree_statement_list *local_fcns) + base_parser::finish_classdef_file (tree_classdef *cls, tree_statement_list *local_fcns, token *eof_tok) { parse_tree_validator validator; @@ -4959,6 +4698,8 @@ std::string nm = fcn->name (); std::string file = fcn->fcn_file_name (); + fcn->attach_trailing_comments (eof_tok->leading_comments ()); + symtab.install_local_function (nm, ov_fcn, file); } @@ -4975,9 +4716,7 @@ // Make an index expression. tree_index_expression * - base_parser::make_index_expression (tree_expression *expr, - tree_argument_list *args, - char type) + base_parser::make_index_expression (tree_expression *expr, token *open_delim, tree_argument_list *args, token *close_delim, char type) { tree_index_expression *retval = nullptr; @@ -4996,14 +4735,17 @@ if (! expr->is_postfix_indexed ()) expr->set_postfix_index (type); + token tmp_open_delim = open_delim ? *open_delim : token (); + token tmp_close_delim = close_delim ? *close_delim : token (); + if (expr->is_index_expression ()) { retval = dynamic_cast<tree_index_expression *> (expr); - retval->append (args, type); + retval->append (tmp_open_delim, args, tmp_close_delim, type); } else - retval = new tree_index_expression (expr, args, l, c, type); + retval = new tree_index_expression (expr, tmp_open_delim, args, tmp_close_delim, l, c, type); } return retval; @@ -5012,8 +4754,7 @@ // Make an indirect reference expression. tree_index_expression * - base_parser::make_indirect_ref (tree_expression *expr, - const std::string& elt) + base_parser::make_indirect_ref (tree_expression *expr, token *dot_tok, token *struct_elt_tok) { tree_index_expression *retval = nullptr; @@ -5027,10 +4768,10 @@ { retval = dynamic_cast<tree_index_expression *> (expr); - retval->append (elt); + retval->append (*dot_tok, *struct_elt_tok); } else - retval = new tree_index_expression (expr, elt, l, c); + retval = new tree_index_expression (expr, *dot_tok, *struct_elt_tok, l, c); m_lexer.m_looking_at_indirect_ref = false; @@ -5040,8 +4781,7 @@ // Make an indirect reference expression with dynamic field name. tree_index_expression * - base_parser::make_indirect_ref (tree_expression *expr, - tree_expression *elt) + base_parser::make_indirect_ref (tree_expression *expr, token *dot_tok, token *open_paren, tree_expression *elt, token *close_paren) { tree_index_expression *retval = nullptr; @@ -5055,10 +4795,10 @@ { retval = dynamic_cast<tree_index_expression *> (expr); - retval->append (elt); + retval->append (*dot_tok, *open_paren, elt, *close_paren); } else - retval = new tree_index_expression (expr, elt, l, c); + retval = new tree_index_expression (expr, *dot_tok, *open_paren, elt, *close_paren, l, c); m_lexer.m_looking_at_indirect_ref = false; @@ -5068,8 +4808,7 @@ // Make a declaration command. tree_decl_command * - base_parser::make_decl_command (int tok_id, token *tok, - tree_decl_init_list *lst) + base_parser::make_decl_command (token *tok, tree_decl_init_list *lst) { tree_decl_command *retval = nullptr; @@ -5079,7 +4818,7 @@ if (lst) m_lexer.mark_as_variables (lst->variable_names ()); - switch (tok_id) + switch (tok->token_id ()) { case GLOBAL: { @@ -5287,11 +5026,12 @@ // Finish building an array_list. tree_expression * - base_parser::finish_array_list (tree_array_list *array_list, - token */*open_delim*/, token *close_delim) + base_parser::finish_array_list (token *open_delim, tree_array_list *array_list, token *close_delim) { tree_expression *retval = array_list; + array_list->mark_in_delims (*open_delim, *close_delim); + array_list->set_location (close_delim->line (), close_delim->column ()); if (array_list->all_elements_are_constant ()) @@ -5351,11 +5091,10 @@ // Finish building a matrix list. tree_expression * - base_parser::finish_matrix (tree_matrix *m, token *open_delim, - token *close_delim) + base_parser::finish_matrix (token *open_delim, tree_matrix *m, token *close_delim) { return (m - ? finish_array_list (m, open_delim, close_delim) + ? finish_array_list (open_delim, m, close_delim) : new tree_constant (octave_null_matrix::instance, close_delim->line (), close_delim->column ())); } @@ -5367,22 +5106,21 @@ } tree_matrix * - base_parser::append_matrix_row (tree_matrix *matrix, tree_argument_list *row) + base_parser::append_matrix_row (tree_matrix *matrix, token *sep_tok, tree_argument_list *row) { if (! matrix) return make_matrix (row); - return row ? list_append (matrix, row) : matrix; + return row ? list_append (matrix, *sep_tok, row) : matrix; } // Finish building a cell list. tree_expression * - base_parser::finish_cell (tree_cell *c, token *open_delim, - token *close_delim) + base_parser::finish_cell (token *open_delim, tree_cell *c, token *close_delim) { return (c - ? finish_array_list (c, open_delim, close_delim) + ? finish_array_list (open_delim, c, close_delim) : new tree_constant (octave_value (Cell ()), close_delim->line (), close_delim->column ())); } @@ -5394,29 +5132,20 @@ } tree_cell * - base_parser::append_cell_row (tree_cell *cell, tree_argument_list *row) + base_parser::append_cell_row (tree_cell *cell, token *sep_tok, tree_argument_list *row) { if (! cell) return make_cell (row); - return row ? list_append (cell, row) : cell; + return row ? list_append (cell, *sep_tok, row) : cell; } tree_identifier * base_parser::make_identifier (token *ident) { - // Find the token in the symbol table. symbol_scope scope = m_lexer.m_symtab_context.curr_scope (); - std::string nm = ident->text (); - - symbol_record sr = (scope ? scope.insert (nm) : symbol_record (nm)); - - - int l = ident->line (); - int c = ident->column (); - - return new tree_identifier (sr, l, c); + return new tree_identifier (scope, *ident); } tree_superclass_ref * @@ -5484,9 +5213,7 @@ tree_statement * base_parser::make_statement (T *arg) { - comment_list *comment = m_lexer.get_comment_list (); - - return new tree_statement (arg, comment); + return new tree_statement (arg); } tree_statement_list * @@ -5512,10 +5239,9 @@ } tree_argument_list * - base_parser::append_argument_list (tree_argument_list *list, - tree_expression *expr) - { - return list_append (list, expr); + base_parser::append_argument_list (tree_argument_list *list, token *sep_tok, tree_expression *expr) + { + return list_append (list, *sep_tok, expr); } tree_parameter_list * @@ -5525,31 +5251,27 @@ } tree_parameter_list * - base_parser::make_parameter_list (tree_parameter_list::in_or_out io, - tree_decl_elt *t) + base_parser::make_parameter_list (tree_parameter_list::in_or_out io, tree_decl_elt *t) { return new tree_parameter_list (io, t); } tree_parameter_list * - base_parser::make_parameter_list (tree_parameter_list::in_or_out io, - tree_identifier *id) + base_parser::make_parameter_list (tree_parameter_list::in_or_out io, tree_identifier *id) { return new tree_parameter_list (io, id); } tree_parameter_list * - base_parser::append_parameter_list (tree_parameter_list *list, - tree_decl_elt *t) - { - return list_append (list, t); + base_parser::append_parameter_list (tree_parameter_list *list, token *sep_tok, tree_decl_elt *t) + { + return list_append (list, *sep_tok, t); } tree_parameter_list * - base_parser::append_parameter_list (tree_parameter_list *list, - tree_identifier *id) - { - return list_append (list, new tree_decl_elt (id)); + base_parser::append_parameter_list (tree_parameter_list *list, token *sep_tok, tree_identifier *id) + { + return list_append (list, *sep_tok, new tree_decl_elt (id)); } void @@ -5949,8 +5671,7 @@ void base_parser::maybe_warn_assign_as_truth_value (tree_expression *expr) { - if (expr->is_assignment_expression () - && expr->paren_count () < 2) + if (expr->is_assignment_expression () && expr->delim_count () < 2) { if (m_lexer.m_fcn_file_full_name.empty ()) warning_with_id
--- a/libinterp/parse-tree/parse.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/parse.h Tue Apr 02 16:11:12 2024 -0400 @@ -48,7 +48,6 @@ OCTAVE_BEGIN_NAMESPACE(octave) -class comment_list; class parse_exception; class tree; class tree_anon_fcn_handle; @@ -67,9 +66,9 @@ class tree_classdef_enum_block; class tree_classdef_enum_list; class tree_classdef_events_block; -class tree_classdef_events_list; +class tree_classdef_event_list; class tree_classdef_methods_block; -class tree_classdef_methods_list; +class tree_classdef_method_list; class tree_classdef_properties_block; class tree_classdef_property_list; class tree_classdef_superclass_list; @@ -236,17 +235,17 @@ // Build a constant. OCTINTERP_API tree_constant * make_constant (token *tok); - OCTINTERP_API tree_black_hole * make_black_hole (); + OCTINTERP_API tree_black_hole * make_black_hole (token *tilde); OCTINTERP_API tree_matrix * make_matrix (tree_argument_list *row); OCTINTERP_API tree_matrix * - append_matrix_row (tree_matrix *matrix, tree_argument_list *row); + append_matrix_row (tree_matrix *matrix, token *sep_tok, tree_argument_list *row); OCTINTERP_API tree_cell * make_cell (tree_argument_list *row); OCTINTERP_API tree_cell * - append_cell_row (tree_cell *cell, tree_argument_list *row); + append_cell_row (tree_cell *cell, token *sep_tok, tree_argument_list *row); // Build a function handle. OCTINTERP_API tree_fcn_handle * make_fcn_handle (token *tok); @@ -258,13 +257,15 @@ // Build a colon expression. OCTINTERP_API tree_expression * - make_colon_expression (tree_expression *base, tree_expression *limit, - tree_expression *incr = nullptr); + make_colon_expression (tree_expression *base, token *colon_tok, tree_expression *limit); + + // Build a colon expression. + OCTINTERP_API tree_expression * + make_colon_expression (tree_expression *base, token *colon_1_tok, tree_expression *incr, token *colon_2_tok, tree_expression *limit); // Build a binary expression. OCTINTERP_API tree_expression * - make_binary_op (int op, tree_expression *op1, token *tok, - tree_expression *op2); + make_binary_op (tree_expression *op1, token *op_tok, tree_expression *op2); // Maybe convert EXPR to a braindead_shortcircuit expression. OCTINTERP_API void @@ -272,47 +273,35 @@ // Build a boolean expression. OCTINTERP_API tree_expression * - make_boolean_op (int op, tree_expression *op1, token *tok, - tree_expression *op2); + make_boolean_op (tree_expression *op1, token *op_tok, tree_expression *op2); // Build a prefix expression. OCTINTERP_API tree_expression * - make_prefix_op (int op, tree_expression *op1, token *tok); + make_prefix_op (token *op_tok, tree_expression *op1); // Build a postfix expression. OCTINTERP_API tree_expression * - make_postfix_op (int op, tree_expression *op1, token *tok); + make_postfix_op (tree_expression *op1, token *op_tok); // Build an unwind-protect command. OCTINTERP_API tree_command * - make_unwind_command (token *unwind_tok, tree_statement_list *body, - tree_statement_list *cleanup, token *end_tok, - comment_list *lc, comment_list *mc); + make_unwind_command (token *unwind_tok, tree_statement_list *body, token *cleanup_tok, tree_statement_list *cleanup, token *end_tok); // Build a try-catch command. OCTINTERP_API tree_command * - make_try_command (token *try_tok, tree_statement_list *body, - char catch_sep, tree_statement_list *cleanup, - token *end_tok, comment_list *lc, - comment_list *mc); + make_try_command (token *try_tok, tree_statement_list *body, token *catch_tok, char catch_sep, tree_statement_list *cleanup, token *end_tok); // Build a while command. OCTINTERP_API tree_command * - make_while_command (token *while_tok, tree_expression *expr, - tree_statement_list *body, token *end_tok, - comment_list *lc); + make_while_command (token *while_tok, tree_expression *expr, tree_statement_list *body, token *end_tok); // Build a do-until command. OCTINTERP_API tree_command * - make_do_until_command (token *until_tok, tree_statement_list *body, - tree_expression *expr, comment_list *lc); + make_do_until_command (token *do_tok, tree_statement_list *body, token *until_tok, tree_expression *expr); // Build a for command. OCTINTERP_API tree_command * - make_for_command (int tok_id, token *for_tok, tree_argument_list *lhs, - tree_expression *expr, tree_expression *maxproc, - tree_statement_list *body, token *end_tok, - comment_list *lc); + make_for_command (token *for_tok, token *open_paren, tree_argument_list *lhs, token *eq_tok, tree_expression *expr, token *sep_tok, tree_expression *maxproc, token *close_paren, tree_statement_list *body, token *end_tok); // Build a break command. OCTINTERP_API tree_command * make_break_command (token *break_tok); @@ -326,55 +315,43 @@ // Build an spmd command. OCTINTERP_API tree_spmd_command * - make_spmd_command (token *spmd_tok, tree_statement_list *body, - token *end_tok, comment_list *lc, comment_list *tc); + make_spmd_command (token *spmd_tok, tree_statement_list *body, token *end_tok); // Start an if command. OCTINTERP_API tree_if_command_list * - start_if_command (tree_expression *expr, tree_statement_list *list); + start_if_command (tree_if_clause *clause); // Finish an if command. OCTINTERP_API tree_if_command * - finish_if_command (token *if_tok, tree_if_command_list *list, - token *end_tok, comment_list *lc); + finish_if_command (tree_if_command_list *list, tree_if_clause *else_clause, token *end_tok); // Build an elseif clause. OCTINTERP_API tree_if_clause * - make_elseif_clause (token *elseif_tok, tree_expression *expr, - tree_statement_list *list, comment_list *lc); - - OCTINTERP_API tree_if_clause * - make_else_clause (token *else_tok, comment_list *lc, - tree_statement_list *list); + make_if_clause (token *if_tok, tree_expression *expr, tree_statement_list *list); OCTINTERP_API tree_if_command_list * append_if_clause (tree_if_command_list *list, tree_if_clause *clause); // Finish a switch command. OCTINTERP_API tree_switch_command * - finish_switch_command (token *switch_tok, tree_expression *expr, - tree_switch_case_list *list, token *end_tok, - comment_list *lc); + finish_switch_command (token *switch_tok, tree_expression *expr, tree_switch_case_list *list, token *end_tok); OCTINTERP_API tree_switch_case_list * make_switch_case_list (tree_switch_case *switch_case); // Build a switch case. OCTINTERP_API tree_switch_case * - make_switch_case (token *case_tok, tree_expression *expr, - tree_statement_list *list, comment_list *lc); + make_switch_case (token *case_tok, tree_expression *expr, tree_statement_list *list); OCTINTERP_API tree_switch_case * - make_default_switch_case (token *default_tok, comment_list *lc, - tree_statement_list *list); + make_default_switch_case (token *default_tok, tree_statement_list *list); OCTINTERP_API tree_switch_case_list * append_switch_case (tree_switch_case_list *list, tree_switch_case *elt); // Build an assignment to a variable. OCTINTERP_API tree_expression * - make_assign_op (int op, tree_argument_list *lhs, token *eq_tok, - tree_expression *rhs); + make_assign_op (tree_argument_list *lhs, token *eq_tok, tree_expression *rhs); // Define a script. OCTINTERP_API void @@ -386,10 +363,7 @@ // Define a function. OCTINTERP_API tree_function_def * - make_function (token *fcn_tok, tree_parameter_list *ret_list, - tree_identifier *id, tree_parameter_list *param_list, - tree_statement_list *body, tree_statement *end_fcn_stmt, - comment_list *lc, comment_list *bc); + make_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, tree_identifier *id, tree_parameter_list *param_list, tree_statement_list *body, tree_statement *end_fcn_stmt); // Begin defining a function. OCTINTERP_API octave_user_function * @@ -399,8 +373,7 @@ // Create a no-op statement for end_function. OCTINTERP_API tree_statement * - make_end (const std::string& type, bool eof, - const filepos& beg_pos, const filepos& end_pos); + make_end (const std::string& type, bool eof, token *tok, const filepos& beg_pos, const filepos& end_pos); // Do most of the work for defining a function. OCTINTERP_API octave_user_function * @@ -408,19 +381,14 @@ // Finish defining a function. OCTINTERP_API tree_function_def * - finish_function (tree_parameter_list *ret_list, - octave_user_function *fcn, comment_list *lc, - int l, int c); + finish_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, octave_user_function *fcn, int l, int c); OCTINTERP_API tree_statement_list * append_function_body (tree_statement_list *body, tree_statement_list *list); // Make an arguments validation block. OCTINTERP_API tree_arguments_block * - make_arguments_block (token *arguments_tok, - tree_args_block_attribute_list *attr_list, - tree_args_block_validation_list *validation_list, - token *end_tok, comment_list *lc, comment_list *tc); + make_arguments_block (token *arguments_tok, tree_args_block_attribute_list *attr_list, tree_args_block_validation_list *validation_list, token *end_tok); OCTINTERP_API tree_args_block_attribute_list * make_args_attribute_list (tree_identifier *attribute_name); @@ -430,7 +398,8 @@ make_arg_validation (tree_arg_size_spec *size_spec, tree_identifier *class_name, tree_arg_validation_fcns *validation_fcns, - tree_expression *default_value); + token *eq_tok = nullptr, + tree_expression *default_value = nullptr); // Make an argument validation list. OCTINTERP_API tree_args_block_validation_list * @@ -454,94 +423,73 @@ recover_from_parsing_function (); OCTINTERP_API tree_classdef * - make_classdef (token *tok, tree_classdef_attribute_list *a, - tree_identifier *id, tree_classdef_superclass_list *sc, - tree_classdef_body *body, token *end_tok, - comment_list *lc, comment_list *bc, comment_list *tc); + make_classdef (token *tok, tree_classdef_attribute_list *a, tree_identifier *id, tree_classdef_superclass_list *sc, tree_classdef_body *body, token *end_tok); OCTINTERP_API tree_classdef_properties_block * - make_classdef_properties_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_property_list *plist, - token *end_tok, comment_list *lc, - comment_list *tc); + make_classdef_properties_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_property_list *plist, token *end_tok); OCTINTERP_API tree_classdef_property_list * make_classdef_property_list (tree_classdef_property *prop); OCTINTERP_API tree_classdef_property * - make_classdef_property (comment_list *lc, tree_identifier *id, - tree_arg_validation *av); + make_classdef_property (tree_identifier *id, tree_arg_validation *av); OCTINTERP_API tree_classdef_property_list * append_classdef_property (tree_classdef_property_list *list, tree_classdef_property *elt); OCTINTERP_API tree_classdef_methods_block * - make_classdef_methods_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_methods_list *mlist, - token *end_tok, comment_list *lc, - comment_list *tc); + make_classdef_methods_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_method_list *mlist, token *end_tok); OCTINTERP_API tree_classdef_events_block * - make_classdef_events_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_events_list *elist, - token *end_tok, comment_list *lc, - comment_list *tc); + make_classdef_events_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_event_list *elist, token *end_tok); - OCTINTERP_API tree_classdef_events_list * - make_classdef_events_list (tree_classdef_event *e); + OCTINTERP_API tree_classdef_event_list * + make_classdef_event_list (tree_classdef_event *e); OCTINTERP_API tree_classdef_event * - make_classdef_event (comment_list *lc, tree_identifier *id); + make_classdef_event (tree_identifier *id); - OCTINTERP_API tree_classdef_events_list * - append_classdef_event (tree_classdef_events_list *list, + OCTINTERP_API tree_classdef_event_list * + append_classdef_event (tree_classdef_event_list *list, tree_classdef_event *elt); OCTINTERP_API tree_classdef_enum_block * - make_classdef_enum_block (token *tok, - tree_classdef_attribute_list *a, - tree_classdef_enum_list *elist, - token *end_tok, comment_list *lc, - comment_list *tc); + make_classdef_enum_block (token *tok, tree_classdef_attribute_list *a, tree_classdef_enum_list *elist, token *end_tok); OCTINTERP_API tree_classdef_enum_list * make_classdef_enum_list (tree_classdef_enum *e); OCTINTERP_API tree_classdef_enum * - make_classdef_enum (tree_identifier *id, tree_expression *expr, - comment_list *lc); + make_classdef_enum (tree_identifier *id, token *open_paren, tree_expression *expr, token *close_paren); OCTINTERP_API tree_classdef_enum_list * append_classdef_enum (tree_classdef_enum_list *list, tree_classdef_enum *elt); OCTINTERP_API tree_classdef_superclass_list * - make_classdef_superclass_list (tree_classdef_superclass *sc); + make_classdef_superclass_list (token *lt_tok, tree_classdef_superclass *sc); OCTINTERP_API tree_classdef_superclass * make_classdef_superclass (token *fqident); OCTINTERP_API tree_classdef_superclass_list * - append_classdef_superclass (tree_classdef_superclass_list *list, - tree_classdef_superclass *elt); + append_classdef_superclass (tree_classdef_superclass_list *list, token *and_tok, tree_classdef_superclass *elt); OCTINTERP_API tree_classdef_attribute_list * make_classdef_attribute_list (tree_classdef_attribute *attr); OCTINTERP_API tree_classdef_attribute * - make_classdef_attribute (tree_identifier *id, - tree_expression *expr = nullptr); + make_classdef_attribute (tree_identifier *id); OCTINTERP_API tree_classdef_attribute * - make_not_classdef_attribute (tree_identifier *id); + make_classdef_attribute (tree_identifier *id, token *eq_tok, tree_expression *expr); + + OCTINTERP_API tree_classdef_attribute * + make_not_classdef_attribute (token *not_tok, tree_identifier *id); OCTINTERP_API tree_classdef_attribute_list * - append_classdef_attribute (tree_classdef_attribute_list *list, - tree_classdef_attribute *elt); + append_classdef_attribute (tree_classdef_attribute_list *list, token *sep_tok, tree_classdef_attribute *elt); OCTINTERP_API tree_classdef_body * make_classdef_body (tree_classdef_properties_block *pb); @@ -572,41 +520,36 @@ tree_classdef_enum_block *block); OCTINTERP_API octave_user_function * - start_classdef_external_method (tree_identifier *id, - tree_parameter_list *pl); + start_classdef_external_method (tree_identifier *id, tree_parameter_list *pl = nullptr); OCTINTERP_API tree_function_def * - finish_classdef_external_method (octave_user_function *fcn, - tree_parameter_list *ret_list, - comment_list *cl); + finish_classdef_external_method (octave_user_function *fcn, tree_parameter_list *ret_list = nullptr, token *eq_tok = nullptr); - OCTINTERP_API tree_classdef_methods_list * - make_classdef_methods_list (tree_function_def *fcn_def); + OCTINTERP_API tree_classdef_method_list * + make_classdef_method_list (tree_function_def *fcn_def); - OCTINTERP_API tree_classdef_methods_list * - append_classdef_method (tree_classdef_methods_list *list, + OCTINTERP_API tree_classdef_method_list * + append_classdef_method (tree_classdef_method_list *list, tree_function_def *fcn_def); OCTINTERP_API bool - finish_classdef_file (tree_classdef *cls, - tree_statement_list *local_fcns); + finish_classdef_file (tree_classdef *cls, tree_statement_list *local_fcns, token *eof_tok); // Make an index expression. OCTINTERP_API tree_index_expression * - make_index_expression (tree_expression *expr, - tree_argument_list *args, char type); + make_index_expression (tree_expression *expr, token *open_paren, tree_argument_list *args, token *close_paren, char type); // Make an indirect reference expression. OCTINTERP_API tree_index_expression * - make_indirect_ref (tree_expression *expr, const std::string&); + make_indirect_ref (tree_expression *expr, token *dot_tok, token *struct_elt_tok); // Make an indirect reference expression with dynamic field name. OCTINTERP_API tree_index_expression * - make_indirect_ref (tree_expression *expr, tree_expression *field); + make_indirect_ref (tree_expression *expr, token *dot_tok, token *open_paren, tree_expression *field, token *close_paren); // Make a declaration command. OCTINTERP_API tree_decl_command * - make_decl_command (int tok_id, token *tok, tree_decl_init_list *lst); + make_decl_command (token *tok, tree_decl_init_list *lst); OCTINTERP_API tree_decl_init_list * make_decl_init_list (tree_decl_elt *elt); @@ -632,16 +575,15 @@ // Finish building an array_list (common action for finish_matrix // and finish_cell). OCTINTERP_API tree_expression * - finish_array_list (tree_array_list *a, token *open_delim, - token *close_delim); + finish_array_list (token *open_delim, tree_array_list *a, token *close_delim); // Finish building a matrix list. OCTINTERP_API tree_expression * - finish_matrix (tree_matrix *m, token *open_delim, token *close_delim); + finish_matrix (token *open_delim, tree_matrix *m, token *close_delim); // Finish building a cell list. OCTINTERP_API tree_expression * - finish_cell (tree_cell *c, token *open_delim, token *close_delim); + finish_cell (token *open_delim, tree_cell *c, token *close_delim); OCTINTERP_API tree_identifier * make_identifier (token *ident); @@ -673,7 +615,7 @@ make_argument_list (tree_expression *expr); OCTINTERP_API tree_argument_list * - append_argument_list (tree_argument_list *list, tree_expression *expr); + append_argument_list (tree_argument_list *list, token *sep_tok, tree_expression *expr); OCTINTERP_API tree_parameter_list * make_parameter_list (tree_parameter_list::in_or_out io); @@ -682,14 +624,13 @@ make_parameter_list (tree_parameter_list::in_or_out io, tree_decl_elt *t); OCTINTERP_API tree_parameter_list * - make_parameter_list (tree_parameter_list::in_or_out io, - tree_identifier *id); + make_parameter_list (tree_parameter_list::in_or_out io, tree_identifier *id); OCTINTERP_API tree_parameter_list * - append_parameter_list (tree_parameter_list *list, tree_decl_elt *t); + append_parameter_list (tree_parameter_list *list, token *sep_tok, tree_decl_elt *t); OCTINTERP_API tree_parameter_list * - append_parameter_list (tree_parameter_list *list, tree_identifier *id); + append_parameter_list (tree_parameter_list *list, token *sep_tok, tree_identifier *id); // Don't allow parsing command syntax. If the parser/lexer is // reset, this setting is also reset to the default (allow command
--- a/libinterp/parse-tree/pt-arg-list.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-arg-list.h Tue Apr 02 16:11:12 2024 -0400 @@ -35,7 +35,9 @@ #include "str-vec.h" +#include "pt-delimiter-list.h" #include "pt-walk.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -64,6 +66,12 @@ ~tree_argument_list (); + tree_argument_list * mark_in_delims (const token& open_delim, const token& close_delim) + { + m_delims.push (open_delim, close_delim); + return this; + } + bool has_magic_tilde () const { return m_list_includes_magic_tilde; @@ -108,6 +116,8 @@ bool m_list_includes_magic_tilde; bool m_simple_assign_lhs; + + tree_delimiter_list m_delims; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-args-block.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-args-block.h Tue Apr 02 16:11:12 2024 -0400 @@ -41,6 +41,8 @@ OCTAVE_BEGIN_NAMESPACE(octave) +class comment_list; + class tree_arg_size_spec { public: @@ -102,10 +104,11 @@ tree_arg_validation (tree_arg_size_spec *size_spec, tree_identifier *class_name, tree_arg_validation_fcns *validation_fcns, + const token& eq_tok, tree_expression *default_value) : m_arg_name (nullptr), m_size_spec (size_spec), m_class_name (class_name), m_validation_fcns (validation_fcns), - m_default_value (default_value) + m_eq_tok (eq_tok), m_default_value (default_value) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_arg_validation) @@ -149,6 +152,7 @@ tree_arg_size_spec *m_size_spec; tree_identifier *m_class_name; tree_arg_validation_fcns *m_validation_fcns; + token m_eq_tok; tree_expression *m_default_value; }; @@ -211,12 +215,8 @@ { public: - tree_arguments_block (tree_args_block_attribute_list *attr_list, - tree_args_block_validation_list *validation_list, - int l = -1, int c = -1) - : tree_command (l, c), m_attr_list (attr_list), - m_validation_list (validation_list), - m_lead_comm (nullptr), m_trail_comm (nullptr) + tree_arguments_block (tree_args_block_attribute_list *attr_list, tree_args_block_validation_list *validation_list, int l = -1, int c = -1) + : tree_command (l, c), m_attr_list (attr_list), m_validation_list (validation_list) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_arguments_block) @@ -225,9 +225,6 @@ { delete m_attr_list; delete m_validation_list; - - delete m_lead_comm; - delete m_trail_comm; } tree_args_block_attribute_list * attribute_list () @@ -240,10 +237,6 @@ return m_validation_list; } - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } - void accept (tree_walker& tw) { tw.visit_arguments_block (*this); @@ -254,12 +247,6 @@ tree_args_block_attribute_list *m_attr_list; tree_args_block_validation_list *m_validation_list; - - // Comment preceding ARGUMENTS token. - comment_list *m_lead_comm; - - // Comment preceding ENDARGUMENTS token. - comment_list *m_trail_comm; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-assign.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-assign.h Tue Apr 02 16:11:12 2024 -0400 @@ -34,9 +34,11 @@ class octave_value; class octave_value_list; +#include "comment-list.h" #include "ov.h" #include "pt-exp.h" #include "pt-walk.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -64,6 +66,8 @@ ~tree_simple_assignment (); + comment_list leading_comments () const { return m_lhs->leading_comments (); } + bool rvalue_ok () const { return true; } bool is_assignment_expression () const { return true; }
--- a/libinterp/parse-tree/pt-classdef.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-classdef.cc Tue Apr 02 16:11:12 2024 -0400 @@ -29,6 +29,7 @@ #include <iostream> +#include "comment-list.h" #include "ov.h" #include "ov-classdef.h" #include "pt-args-block.h" @@ -121,33 +122,39 @@ // Classdef property -std::string -check_for_doc_string (comment_list *comments) +static std::string +check_for_doc_string (const comment_list& comments) { - // If the comment list ends in a block comment or full-line comment, - // then it is the doc string for this property. + if (! comments.empty ()) + { + // If the comment list ends in a block comment or full-line + // comment, then it is the doc string for this property. - if (comments) - { - comment_elt last_elt = comments->back (); + comment_elt last_elt = comments.back (); - if (last_elt.is_block () || last_elt.is_full_line ()) + if (! last_elt.is_copyright () + && (last_elt.is_block () || last_elt.is_full_line ())) return last_elt.text (); } return ""; } -tree_classdef_property::tree_classdef_property (tree_arg_validation *av, - comment_list *comments) - : m_av (av), m_comments (comments), - m_doc_string (check_for_doc_string (m_comments)) +tree_classdef_property::tree_classdef_property (tree_arg_validation *av) + : m_av (av), m_doc_string (check_for_doc_string (leading_comments ())) { } tree_classdef_property::~tree_classdef_property () { delete m_av; - delete m_comments; +} + +comment_list +tree_classdef_property::leading_comments () +{ + tree_identifier *id = ident (); + + return id->leading_comments (); } tree_identifier * @@ -178,21 +185,19 @@ // Classdef properties_block -// Classdef methods_list +// Classdef method_list // Classdef methods_block // Classdef event -tree_classdef_event::tree_classdef_event (tree_identifier *i, - comment_list *comments) - : m_id (i), m_comments (comments), - m_doc_string (check_for_doc_string (m_comments)) +tree_classdef_event::tree_classdef_event (tree_identifier *i) + : m_id (i) { } -// Classdef events_list +// Classdef event_list -tree_classdef_events_list::~tree_classdef_events_list () +tree_classdef_event_list::~tree_classdef_event_list () { while (! empty ()) { @@ -206,11 +211,8 @@ // Classdef enum -tree_classdef_enum::tree_classdef_enum (tree_identifier *i, - tree_expression *e, - comment_list *comments) - : m_id (i), m_expr (e), m_comments (comments), - m_doc_string (check_for_doc_string (m_comments)) +tree_classdef_enum::tree_classdef_enum (tree_identifier *i, const token& open_paren, tree_expression *e, const token& close_paren) + : m_id (i), m_open_paren (open_paren), m_expr (e), m_close_paren (close_paren) { } // Classdef enum_list @@ -230,82 +232,55 @@ // Classdef body tree_classdef_body::tree_classdef_body () - : m_properties_lst (), m_methods_lst (), m_events_lst (), m_enum_lst () + : m_property_lst (), m_method_lst (), m_event_lst (), m_enum_lst () { } tree_classdef_body::tree_classdef_body (tree_classdef_properties_block *pb) - : m_properties_lst (), m_methods_lst (), m_events_lst (), m_enum_lst (), - m_doc_string (pb ? get_doc_string (pb->leading_comment ()) : "") + : m_property_lst (), m_method_lst (), m_event_lst (), m_enum_lst () { append (pb); } tree_classdef_body::tree_classdef_body (tree_classdef_methods_block *mb) - : m_properties_lst (), m_methods_lst (), m_events_lst (), m_enum_lst (), - m_doc_string (mb ? get_doc_string (mb->leading_comment ()) : "") + : m_property_lst (), m_method_lst (), m_event_lst (), m_enum_lst () { append (mb); } tree_classdef_body::tree_classdef_body (tree_classdef_events_block *evb) - : m_properties_lst (), m_methods_lst (), m_events_lst (), m_enum_lst (), - m_doc_string (evb ? get_doc_string (evb->leading_comment ()) : "") + : m_property_lst (), m_method_lst (), m_event_lst (), m_enum_lst () { append (evb); } tree_classdef_body::tree_classdef_body (tree_classdef_enum_block *enb) - : m_properties_lst (), m_methods_lst (), m_events_lst (), m_enum_lst (), - m_doc_string (enb ? get_doc_string (enb->leading_comment ()) : "") + : m_property_lst (), m_method_lst (), m_event_lst (), m_enum_lst () { append (enb); } +comment_list +tree_classdef_body::leading_comments () const +{ + if (! m_all_elements.empty ()) + { + tree_base_classdef_block *element = m_all_elements.front (); + + if (element) + return element->leading_comments (); + } + + return comment_list (); +} + tree_classdef_body::~tree_classdef_body () { - while (! m_properties_lst.empty ()) - { - auto p = m_properties_lst.begin (); - delete *p; - m_properties_lst.erase (p); - } - - while (! m_methods_lst.empty ()) + while (! m_all_elements.empty ()) { - auto p = m_methods_lst.begin (); + auto p = m_all_elements.begin (); delete *p; - m_methods_lst.erase (p); - } - - while (! m_events_lst.empty ()) - { - auto p = m_events_lst.begin (); - delete *p; - m_events_lst.erase (p); + m_all_elements.erase (p); } - - while (! m_enum_lst.empty ()) - { - auto p = m_enum_lst.begin (); - delete *p; - m_enum_lst.erase (p); - } -} - -std::string -tree_classdef_body::get_doc_string (comment_list *comments) const -{ - // Grab the first comment from the list and use it as the doc string - // for this classdef body. - - if (comments) - { - comment_elt first_elt = comments->front (); - - return first_elt.text (); - } - - return ""; } // Classdef
--- a/libinterp/parse-tree/pt-classdef.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-classdef.h Tue Apr 02 16:11:12 2024 -0400 @@ -30,18 +30,19 @@ class octave_value; -#include "comment-list.h" #include "pt-cmd.h" +#include "pt-delimiter-list.h" #include "pt-exp.h" #include "pt-walk.h" #include "pt-id.h" +#include "token.h" #include <list> OCTAVE_BEGIN_NAMESPACE(octave) +class coment_list; class interpreter; - class tree_arg_validation; class tree_superclass_ref : public tree_expression @@ -128,13 +129,16 @@ { public: - tree_classdef_attribute (tree_identifier *i = nullptr, - tree_expression *e = nullptr) - : m_id (i), m_expr (e), m_neg (false) + tree_classdef_attribute (tree_identifier *i) + : m_id (i) { } - tree_classdef_attribute (tree_identifier *i, bool b) - : m_id (i), m_expr (nullptr), m_neg (b) + tree_classdef_attribute (tree_identifier *i, const token eq_tok, tree_expression *e) + : m_id (i), m_eq_tok (eq_tok), m_expr (e) + { } + + tree_classdef_attribute (const token& not_tok, tree_identifier *i, bool b) + : m_not_tok (not_tok), m_id (i), m_neg (b) { } OCTAVE_DISABLE_COPY_MOVE (tree_classdef_attribute) @@ -158,9 +162,11 @@ private: + token m_not_tok; tree_identifier *m_id; - tree_expression *m_expr; - bool m_neg; + token m_eq_tok; + tree_expression *m_expr {nullptr}; + bool m_neg {false}; }; class tree_classdef_attribute_list : public std::list<tree_classdef_attribute *> @@ -179,25 +185,37 @@ ~tree_classdef_attribute_list (); + tree_classdef_attribute_list * mark_in_delims (const token& open_delim, token& close_delim) + { + m_delims.push (open_delim, close_delim); + return this; + } + void accept (tree_walker& tw) { tw.visit_classdef_attribute_list (*this); } + +private: + + tree_delimiter_list m_delims; }; class tree_classdef_superclass { public: - tree_classdef_superclass (const std::string& cname) - : m_cls_name (cname) + tree_classdef_superclass (const token& fqident) + : m_fqident (fqident) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_superclass) ~tree_classdef_superclass () = default; - std::string class_name () { return m_cls_name; } + void set_separator (const token& sep_tok) { m_sep_tok = sep_tok; } + + std::string class_name () { return m_fqident.text (); } void accept (tree_walker& tw) { @@ -206,7 +224,13 @@ private: - std::string m_cls_name; + // The '<' or '&&' token introducing an element of a superclass list + // element. Is there a better name for it? + + token m_sep_tok; + + // The fully-qualified identifier token for this superclass element. + token m_fqident; }; class tree_classdef_superclass_list @@ -235,76 +259,84 @@ } }; -template <typename T> -class tree_classdef_element : public tree +class tree_base_classdef_block : public tree { public: - tree_classdef_element (tree_classdef_attribute_list *a, T *elt_list, - comment_list *lc, comment_list *tc, - int l = -1, int c = -1) - : tree (l, c), m_attr_list (a), m_elt_list (elt_list), - m_lead_comm (lc), m_trail_comm (tc) + tree_base_classdef_block (const token& block_tok, tree_classdef_attribute_list *a, const token& end_tok, int l = -1, int c = -1) + : tree (l, c), m_block_tok (block_tok), m_attr_list (a), m_end_tok (end_tok) { } - OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_element) + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_base_classdef_block) - ~tree_classdef_element () + ~tree_base_classdef_block () { delete m_attr_list; - delete m_elt_list; - delete m_lead_comm; - delete m_trail_comm; } + comment_list leading_comments () const { return m_block_tok.leading_comments (); } + tree_classdef_attribute_list * attribute_list () { return m_attr_list; } - T * element_list () { return m_elt_list; } - - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } - void accept (tree_walker&) { } private: + token m_block_tok; + // List of attributes that apply to this class. tree_classdef_attribute_list *m_attr_list; - // The list of objects contained in this block. - T *m_elt_list; + token m_end_tok; +}; + +template <typename T> +class tree_classdef_block : public tree_base_classdef_block +{ +public: + + tree_classdef_block (const token& block_tok, tree_classdef_attribute_list *a, T *elt_list, const token& end_tok, int l = -1, int c = -1) + : tree_base_classdef_block (block_tok, a, end_tok, l, c), m_elt_list (elt_list) + { } + + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_block) - // Comments preceding the token marking the beginning of the block. - comment_list *m_lead_comm; + ~tree_classdef_block () + { + delete m_elt_list; + } + + T * element_list () { return m_elt_list; } - // Comments preceding the END token marking the end of the block. - comment_list *m_trail_comm; +private: + + T *m_elt_list; }; +// FIXME: should this class be derived from tree? + class tree_classdef_property { public: - tree_classdef_property (tree_arg_validation *av, - comment_list *comments = nullptr); + tree_classdef_property (tree_arg_validation *av); OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_property) ~tree_classdef_property (); - tree_identifier * ident (); - - tree_expression * expression (); + comment_list leading_comments (); - comment_list * comments () const { return m_comments; } - - void doc_string (const std::string& txt) { m_doc_string = txt; } + void doc_string (const std::string& s) { m_doc_string = s; } std::string doc_string () const { return m_doc_string; } bool have_doc_string () const { return ! m_doc_string.empty (); } + tree_identifier * ident (); + + tree_expression * expression (); + void accept (tree_walker& tw) { tw.visit_classdef_property (*this); @@ -313,7 +345,7 @@ private: tree_arg_validation *m_av; - comment_list *m_comments; + std::string m_doc_string; }; @@ -338,65 +370,61 @@ } }; -class tree_classdef_properties_block - : public tree_classdef_element<tree_classdef_property_list> +class tree_classdef_properties_block : public tree_classdef_block<tree_classdef_property_list> { public: - tree_classdef_properties_block (tree_classdef_attribute_list *a, - tree_classdef_property_list *plist, - comment_list *lc, comment_list *tc, - int l = -1, int c = -1) - : tree_classdef_element<tree_classdef_property_list> (a, plist, lc, tc, l, c) + tree_classdef_properties_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_property_list *plist, const token& end_tok, int l = -1, int c = -1) + : tree_classdef_block<tree_classdef_property_list> (block_tok, a, plist, end_tok, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_properties_block) ~tree_classdef_properties_block () = default; + tree_classdef_property_list * property_list () { return element_list (); } + void accept (tree_walker& tw) { tw.visit_classdef_properties_block (*this); } }; -class tree_classdef_methods_list : public std::list<octave_value> +class tree_classdef_method_list : public std::list<octave_value> { public: - tree_classdef_methods_list () { } + tree_classdef_method_list () { } - tree_classdef_methods_list (const octave_value& f) { push_back (f); } + tree_classdef_method_list (const octave_value& f) { push_back (f); } - tree_classdef_methods_list (const std::list<octave_value>& a) + tree_classdef_method_list (const std::list<octave_value>& a) : std::list<octave_value> (a) { } - OCTAVE_DISABLE_COPY_MOVE (tree_classdef_methods_list) + OCTAVE_DISABLE_COPY_MOVE (tree_classdef_method_list) - ~tree_classdef_methods_list () = default; + ~tree_classdef_method_list () = default; void accept (tree_walker& tw) { - tw.visit_classdef_methods_list (*this); + tw.visit_classdef_method_list (*this); } }; -class tree_classdef_methods_block - : public tree_classdef_element<tree_classdef_methods_list> +class tree_classdef_methods_block : public tree_classdef_block<tree_classdef_method_list> { public: - tree_classdef_methods_block (tree_classdef_attribute_list *a, - tree_classdef_methods_list *mlist, - comment_list *lc, comment_list *tc, - int l = -1, int c = -1) - : tree_classdef_element<tree_classdef_methods_list> (a, mlist, lc, tc, l, c) + tree_classdef_methods_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_method_list *mlist, const token& end_tok, int l = -1, int c = -1) + : tree_classdef_block<tree_classdef_method_list> (block_tok, a, mlist, end_tok, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_methods_block) ~tree_classdef_methods_block () = default; + tree_classdef_method_list * method_list () { return element_list (); } + void accept (tree_walker& tw) { tw.visit_classdef_methods_block (*this); @@ -407,27 +435,17 @@ { public: - tree_classdef_event (tree_identifier *i = nullptr, - comment_list *comments = nullptr); + tree_classdef_event (tree_identifier *i = nullptr); OCTAVE_DISABLE_COPY_MOVE (tree_classdef_event) ~tree_classdef_event () { delete m_id; - delete m_comments; } tree_identifier * ident () { return m_id; } - comment_list * comments () const { return m_comments; } - - void doc_string (const std::string& txt) { m_doc_string = txt; } - - std::string doc_string () const { return m_doc_string; } - - bool have_doc_string () const { return ! m_doc_string.empty (); } - void accept (tree_walker& tw) { tw.visit_classdef_event (*this); @@ -436,48 +454,44 @@ private: tree_identifier *m_id; - comment_list *m_comments; - std::string m_doc_string; }; -class tree_classdef_events_list : public std::list<tree_classdef_event *> +class tree_classdef_event_list : public std::list<tree_classdef_event *> { public: - tree_classdef_events_list () { } + tree_classdef_event_list () { } - tree_classdef_events_list (tree_classdef_event *e) { push_back (e); } + tree_classdef_event_list (tree_classdef_event *e) { push_back (e); } - tree_classdef_events_list (const std::list<tree_classdef_event *>& a) + tree_classdef_event_list (const std::list<tree_classdef_event *>& a) : std::list<tree_classdef_event *> (a) { } - OCTAVE_DISABLE_COPY_MOVE (tree_classdef_events_list) + OCTAVE_DISABLE_COPY_MOVE (tree_classdef_event_list) - ~tree_classdef_events_list (); + ~tree_classdef_event_list (); void accept (tree_walker& tw) { - tw.visit_classdef_events_list (*this); + tw.visit_classdef_event_list (*this); } }; -class tree_classdef_events_block - : public tree_classdef_element<tree_classdef_events_list> +class tree_classdef_events_block : public tree_classdef_block<tree_classdef_event_list> { public: - tree_classdef_events_block (tree_classdef_attribute_list *a, - tree_classdef_events_list *elist, - comment_list *lc, comment_list *tc, - int l = -1, int c = -1) - : tree_classdef_element<tree_classdef_events_list> (a, elist, lc, tc, l, c) + tree_classdef_events_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_event_list *elist, const token& end_tok, int l = -1, int c = -1) + : tree_classdef_block<tree_classdef_event_list> (block_tok, a, elist, end_tok, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_events_block) ~tree_classdef_events_block () = default; + tree_classdef_event_list * event_list () { return element_list (); } + void accept (tree_walker& tw) { tw.visit_classdef_events_block (*this); @@ -488,8 +502,7 @@ { public: - tree_classdef_enum (tree_identifier *i, tree_expression *e, - comment_list *comments); + tree_classdef_enum (tree_identifier *i, const token& open_paren, tree_expression *e, const token& close_paren); OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_enum) @@ -497,20 +510,15 @@ { delete m_id; delete m_expr; - delete m_comments; } tree_identifier * ident () { return m_id; } + token open_paren () const { return m_open_paren; } + tree_expression * expression () { return m_expr; } - comment_list * comments () const { return m_comments; } - - void doc_string (const std::string& txt) { m_doc_string = txt; } - - std::string doc_string () const { return m_doc_string; } - - bool have_doc_string () const { return ! m_doc_string.empty (); } + token close_paren () const { return m_close_paren; } void accept (tree_walker& tw) { @@ -520,9 +528,9 @@ private: tree_identifier *m_id; + token m_open_paren; tree_expression *m_expr; - comment_list *m_comments; - std::string m_doc_string; + token m_close_paren; }; class tree_classdef_enum_list : public std::list<tree_classdef_enum *> @@ -547,49 +555,43 @@ } }; -class tree_classdef_enum_block - : public tree_classdef_element<tree_classdef_enum_list> +class tree_classdef_enum_block : public tree_classdef_block<tree_classdef_enum_list> { public: - tree_classdef_enum_block (tree_classdef_attribute_list *a, - tree_classdef_enum_list *elist, - comment_list *lc, comment_list *tc, - int l = -1, int c = -1) - : tree_classdef_element<tree_classdef_enum_list> (a, elist, lc, tc, l, c) + tree_classdef_enum_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_enum_list *elist, const token& end_tok, int l = -1, int c = -1) + : tree_classdef_block<tree_classdef_enum_list> (block_tok, a, elist, end_tok, l, c) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_enum_block) ~tree_classdef_enum_block () = default; + tree_classdef_enum_list * enum_list () { return element_list (); } + void accept (tree_walker& tw) { tw.visit_classdef_enum_block (*this); } }; +// FIXME: should this class be derived from tree? + class tree_classdef_body { public: - typedef std::list<tree_classdef_properties_block *>::iterator - properties_list_iterator; - typedef std::list<tree_classdef_properties_block *>::const_iterator - properties_list_const_iterator; + typedef std::list<tree_classdef_properties_block *>::iterator property_list_iterator; + typedef std::list<tree_classdef_properties_block *>::const_iterator property_list_const_iterator; - typedef std::list<tree_classdef_methods_block *>::iterator - methods_list_iterator; - typedef std::list<tree_classdef_methods_block *>::const_iterator - methods_list_const_iterator; + typedef std::list<tree_classdef_methods_block *>::iterator method_list_iterator; + typedef std::list<tree_classdef_methods_block *>::const_iterator method_list_const_iterator; - typedef std::list<tree_classdef_events_block *>::iterator events_list_iterator; - typedef std::list<tree_classdef_events_block *>::const_iterator - events_list_const_iterator; + typedef std::list<tree_classdef_events_block *>::iterator event_list_iterator; + typedef std::list<tree_classdef_events_block *>::const_iterator event_list_const_iterator; typedef std::list<tree_classdef_enum_block *>::iterator enum_list_iterator; - typedef std::list<tree_classdef_enum_block *>::const_iterator - enum_list_const_iterator; + typedef std::list<tree_classdef_enum_block *>::const_iterator enum_list_const_iterator; tree_classdef_body (); @@ -605,43 +607,49 @@ ~tree_classdef_body (); + comment_list leading_comments () const; + tree_classdef_body * append (tree_classdef_properties_block *pb) { - m_properties_lst.push_back (pb); + m_property_lst.push_back (pb); + m_all_elements.push_back (pb); return this; } tree_classdef_body * append (tree_classdef_methods_block *mb) { - m_methods_lst.push_back (mb); + m_method_lst.push_back (mb); + m_all_elements.push_back (mb); return this; } tree_classdef_body * append (tree_classdef_events_block *evb) { - m_events_lst.push_back (evb); + m_event_lst.push_back (evb); + m_all_elements.push_back (evb); return this; } tree_classdef_body * append (tree_classdef_enum_block *enb) { m_enum_lst.push_back (enb); + m_all_elements.push_back (enb); return this; } - std::list<tree_classdef_properties_block *> properties_list () + std::list<tree_classdef_properties_block *> property_list () { - return m_properties_lst; + return m_property_lst; } - std::list<tree_classdef_methods_block *> methods_list () + std::list<tree_classdef_methods_block *> method_list () { - return m_methods_lst; + return m_method_lst; } - std::list<tree_classdef_events_block *> events_list () + std::list<tree_classdef_events_block *> event_list () { - return m_events_lst; + return m_event_lst; } std::list<tree_classdef_enum_block *> enum_list () @@ -649,12 +657,6 @@ return m_enum_lst; } - void doc_string (const std::string& txt) { m_doc_string = txt; } - - std::string doc_string () const { return m_doc_string; } - - bool have_doc_string () const { return ! m_doc_string.empty (); } - void accept (tree_walker& tw) { tw.visit_classdef_body (*this); @@ -662,17 +664,15 @@ private: - std::string get_doc_string (comment_list *comment) const; - - std::list<tree_classdef_properties_block *> m_properties_lst; + std::list<tree_classdef_properties_block *> m_property_lst; - std::list<tree_classdef_methods_block *> m_methods_lst; + std::list<tree_classdef_methods_block *> m_method_lst; - std::list<tree_classdef_events_block *> m_events_lst; + std::list<tree_classdef_events_block *> m_event_lst; std::list<tree_classdef_enum_block *> m_enum_lst; - std::string m_doc_string; + std::list<tree_base_classdef_block *> m_all_elements; }; // Classdef definition. @@ -681,17 +681,11 @@ { public: - tree_classdef (const symbol_scope& scope, const std::string& help_text, - tree_classdef_attribute_list *a, tree_identifier *i, - tree_classdef_superclass_list *sc, - tree_classdef_body *b, comment_list *lc, - comment_list *tc, const std::string& pn = "", - const std::string& fn = "", int l = -1, int c = -1) - : tree_command (l, c), m_scope (scope), m_help_text (help_text), - m_attr_list (a), m_id (i), - m_supclass_list (sc), m_element_list (b), m_lead_comm (lc), - m_trail_comm (tc), m_pack_name (pn), m_file_name (fn) - { } + tree_classdef (const symbol_scope& scope, const token& cdef_tok, tree_classdef_attribute_list *a, tree_identifier *i, tree_classdef_superclass_list *sc, tree_classdef_body *b, const token& end_tok, const std::string& pn = "", const std::string& fn = "", int l = -1, int c = -1) + : tree_command (l, c), m_scope (scope), m_cdef_tok (cdef_tok), m_attr_list (a), m_id (i), m_supclass_list (sc), m_body (b), m_end_tok (end_tok), m_pack_name (pn), m_file_name (fn) + { + cache_doc_string (); + } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef) @@ -700,9 +694,7 @@ delete m_attr_list; delete m_id; delete m_supclass_list; - delete m_element_list; - delete m_lead_comm; - delete m_trail_comm; + delete m_body; } symbol_scope scope () { return m_scope; } @@ -715,10 +707,9 @@ tree_classdef_superclass_list * superclass_list () { return m_supclass_list; } - tree_classdef_body * body () { return m_element_list; } + tree_classdef_body * body () { return m_body; } - comment_list * leading_comment () { return m_lead_comm; } - comment_list * trailing_comment () { return m_trail_comm; } + comment_list leading_comments () const { return m_cdef_tok.leading_comments (); } std::string package_name () const { return m_pack_name; } @@ -727,10 +718,7 @@ octave_value make_meta_class (interpreter& interp, bool is_at_folder = false); - std::string doc_string () const - { - return m_help_text; - } + std::string doc_string () const { return m_doc_string; } void accept (tree_walker& tw) { @@ -739,13 +727,31 @@ private: + void cache_doc_string () + { + // First non-copyright comments found above and below classdef + // keyword are candidates for the documentation string. Use the + // first one that is not empty. + + comment_list comments = m_cdef_tok.leading_comments (); + + m_doc_string = comments.find_doc_string (); + + if (m_doc_string.empty ()) + { + comments = m_body->leading_comments (); + + m_doc_string = comments.find_doc_string (); + } + } + // The scope that was used when parsing the classdef object and that // corresponds to any identifiers that were found in attribute lists // (for example). Used again when computing the meta class object. symbol_scope m_scope; - std::string m_help_text; + token m_cdef_tok; tree_classdef_attribute_list *m_attr_list; @@ -753,10 +759,11 @@ tree_classdef_superclass_list *m_supclass_list; - tree_classdef_body *m_element_list; + tree_classdef_body *m_body; - comment_list *m_lead_comm; - comment_list *m_trail_comm; + token m_end_tok; + + std::string m_doc_string; std::string m_pack_name; std::string m_file_name;
--- a/libinterp/parse-tree/pt-cmd.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-cmd.h Tue Apr 02 16:11:12 2024 -0400 @@ -30,10 +30,12 @@ #include <string> +#include "comment-list.h" #include "ov-fcn.h" #include "pt.h" #include "pt-bp.h" #include "pt-walk.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -57,14 +59,25 @@ { public: - tree_no_op_command (const std::string& cmd = "no_op", bool e = false, - int l = -1, int c = -1) - : tree_command (l, c), m_eof (e), m_orig_cmd (cmd) { } + tree_no_op_command (const std::string& cmd, bool eof, const token& tok, int l = -1, int c = -1) + : tree_command (l, c), m_eof (eof), m_tok (tok), m_orig_cmd (cmd) { } - OCTAVE_DISABLE_COPY_MOVE (tree_no_op_command) + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_no_op_command) ~tree_no_op_command () = default; + comment_list leading_comments () const { return m_tok.leading_comments (); } + + void attach_trailing_comments (const comment_list& lst) + { + m_tok.trailing_comments (lst); + } + + comment_list trailing_comments () const + { + return m_tok.trailing_comments (); + } + void accept (tree_walker& tw) { tw.visit_no_op_command (*this); @@ -83,6 +96,9 @@ bool m_eof; + // If defined, may be END token or EOF. + token m_tok; + std::string m_orig_cmd; };
--- a/libinterp/parse-tree/pt-colon.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-colon.cc Tue Apr 02 16:11:12 2024 -0400 @@ -41,9 +41,10 @@ { tree_colon_expression *new_ce = new tree_colon_expression (m_base ? m_base->dup (scope) : nullptr, + m_colon_1_tok, + m_increment ? m_increment->dup (scope) : nullptr, + m_colon_2_tok, m_limit ? m_limit->dup (scope) : nullptr, - m_increment ? m_increment->dup (scope) - : nullptr, line (), column ()); new_ce->copy_base (*this);
--- a/libinterp/parse-tree/pt-colon.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-colon.h Tue Apr 02 16:11:12 2024 -0400 @@ -46,19 +46,13 @@ { public: - tree_colon_expression (int l = -1, int c = -1) - : tree_expression (l, c), m_base (nullptr), m_limit (nullptr), - m_increment (nullptr), m_save_base (false) { } + tree_colon_expression (tree_expression *base, const token& colon_1_tok, tree_expression *limit, int l = -1, int c = -1) + : tree_expression (l, c), m_base (base), m_colon_1_tok (colon_1_tok), m_limit (limit) + { } - tree_colon_expression (tree_expression *bas, tree_expression *lim, - int l = -1, int c = -1) - : tree_expression (l, c), m_base (bas), m_limit (lim), - m_increment (nullptr), m_save_base (false) { } - - tree_colon_expression (tree_expression *bas, tree_expression *lim, - tree_expression *inc, int l = -1, int c = -1) - : tree_expression (l, c), m_base (bas), m_limit (lim), - m_increment (inc), m_save_base (false) { } + tree_colon_expression (tree_expression *base, const token& colon_1_tok, tree_expression *increment, const token& colon_2_tok, tree_expression *limit, int l = -1, int c = -1) + : tree_expression (l, c), m_base (base), m_colon_1_tok (colon_1_tok), m_increment (increment), m_colon_2_tok (colon_2_tok), m_limit (limit) + { } OCTAVE_DISABLE_COPY_MOVE (tree_colon_expression) @@ -103,10 +97,12 @@ // The components of the expression. tree_expression *m_base; + token m_colon_1_tok; + tree_expression *m_increment {nullptr}; + token m_colon_2_tok; tree_expression *m_limit; - tree_expression *m_increment; - bool m_save_base; + bool m_save_base {false}; }; OCTAVE_END_NAMESPACE(octave)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libinterp/parse-tree/pt-delimiter-list.h Tue Apr 02 16:11:12 2024 -0400 @@ -0,0 +1,59 @@ +//////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2024 The Octave Project Developers +// +// See the file COPYRIGHT.md in the top-level directory of this +// distribution or <https://octave.org/copyright/>. +// +// This file is part of Octave. +// +// Octave is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Octave is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Octave; see the file COPYING. If not, see +// <https://www.gnu.org/licenses/>. +// +//////////////////////////////////////////////////////////////////////// + +#if ! defined (octave_tree_delimiter_list_h) +#define octave_tree_delimiter_list_h 1 + +#include "octave-config.h" + +#include <stack> + +#include "token.h" + +OCTAVE_BEGIN_NAMESPACE(octave) + +class tree_delimiter_list +{ +public: + + typedef std::pair<token, token> element_type; + + OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (tree_delimiter_list) + + size_t count () const { return m_delimiters.size (); } + + void push (const token& open_delim, const token& close_delim) + { + m_delimiters.push (element_type (open_delim, close_delim)); + } + +private: + + std::stack<element_type> m_delimiters; +}; + +OCTAVE_END_NAMESPACE(octave) + +#endif
--- a/libinterp/parse-tree/pt-eval.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Tue Apr 02 16:11:12 2024 -0400 @@ -3441,7 +3441,7 @@ if (expr) { tree_expression *expr_dup = expr->dup (new_scope); - tree_statement *stmt = new tree_statement (expr_dup, nullptr); + tree_statement *stmt = new tree_statement (expr_dup); stmt_list = new tree_statement_list (stmt); }
--- a/libinterp/parse-tree/pt-except.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-except.cc Tue Apr 02 16:11:12 2024 -0400 @@ -52,9 +52,6 @@ delete m_expr_id; delete m_try_code; delete m_catch_code; - delete m_lead_comm; - delete m_mid_comm; - delete m_trail_comm; } // Simple exception handling. @@ -63,9 +60,6 @@ { delete m_unwind_protect_code; delete m_cleanup_code; - delete m_lead_comm; - delete m_mid_comm; - delete m_trail_comm; } OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-except.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-except.h Tue Apr 02 16:11:12 2024 -0400 @@ -43,20 +43,8 @@ { public: - tree_try_catch_command (int l = -1, int c = -1) - : tree_command (l, c), m_try_code (nullptr), m_catch_code (nullptr), - m_expr_id (nullptr), m_lead_comm (nullptr), m_mid_comm (nullptr), - m_trail_comm (nullptr) - { } - - tree_try_catch_command (tree_statement_list *tc, tree_statement_list *cc, - tree_identifier *id, - comment_list *cl = nullptr, - comment_list *cm = nullptr, - comment_list *ct = nullptr, - int l = -1, int c = -1) - : tree_command (l, c), m_try_code (tc), m_catch_code (cc), - m_expr_id (id), m_lead_comm (cl), m_mid_comm (cm), m_trail_comm (ct) + tree_try_catch_command (const token try_tok, tree_statement_list *tc, const token catch_tok, tree_identifier *id, tree_statement_list *cc, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_try_tok (try_tok), m_try_code (tc), m_catch_tok (catch_tok), m_expr_id (id), m_catch_code (cc), m_end_tok (end_tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_try_catch_command) @@ -69,12 +57,6 @@ tree_statement_list * cleanup () { return m_catch_code; } - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * middle_comment () { return m_mid_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } - void accept (tree_walker& tw) { tw.visit_try_catch_command (*this); @@ -82,23 +64,20 @@ private: + token m_try_tok; + // The first block of code to attempt to execute. tree_statement_list *m_try_code; - // The code to execute if an error occurs in the first block. - tree_statement_list *m_catch_code; + token m_catch_tok; // Identifier to modify. tree_identifier *m_expr_id; - // Comment preceding TRY token. - comment_list *m_lead_comm; + // The code to execute if an error occurs in the first block. + tree_statement_list *m_catch_code; - // Comment preceding CATCH token. - comment_list *m_mid_comm; - - // Comment preceding END_TRY_CATCH token. - comment_list *m_trail_comm; + token m_end_tok; }; // Simple exception handling. @@ -107,20 +86,8 @@ { public: - tree_unwind_protect_command (int l = -1, int c = -1) - : tree_command (l, c), - m_unwind_protect_code (nullptr), m_cleanup_code (nullptr), - m_lead_comm (nullptr), m_mid_comm (nullptr), m_trail_comm (nullptr) - { } - - tree_unwind_protect_command (tree_statement_list *tc, - tree_statement_list *cc, - comment_list *cl = nullptr, - comment_list *cm = nullptr, - comment_list *ct = nullptr, - int l = -1, int c = -1) - : tree_command (l, c), m_unwind_protect_code (tc), m_cleanup_code (cc), - m_lead_comm (cl), m_mid_comm (cm), m_trail_comm (ct) + tree_unwind_protect_command (const token& unwind_tok, tree_statement_list *tc, const token& cleanup_tok, tree_statement_list *cc, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_unwind_tok (unwind_tok), m_unwind_protect_code (tc), m_cleanup_tok (cleanup_tok), m_cleanup_code (cc), m_end_tok (end_tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_unwind_protect_command) @@ -131,12 +98,6 @@ tree_statement_list * cleanup () { return m_cleanup_code; } - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * middle_comment () { return m_mid_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } - void accept (tree_walker& tw) { tw.visit_unwind_protect_command (*this); @@ -144,21 +105,18 @@ private: + token m_unwind_tok; + // The first body of code to attempt to execute. tree_statement_list *m_unwind_protect_code; + token m_cleanup_tok; + // The body of code to execute no matter what happens in the first // body of code. tree_statement_list *m_cleanup_code; - // Comment preceding UNWIND_PROTECT token. - comment_list *m_lead_comm; - - // Comment preceding UNWIND_PROTECT_CLEANUP token. - comment_list *m_mid_comm; - - // Comment preceding END_UNWIND_PROTECT token. - comment_list *m_trail_comm; + token m_end_tok; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-exp.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-exp.h Tue Apr 02 16:11:12 2024 -0400 @@ -34,7 +34,9 @@ class octave_value; #include "pt.h" +#include "pt-delimiter-list.h" #include "pt-eval.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -48,8 +50,7 @@ public: tree_expression (int l = -1, int c = -1) - : tree (l, c), m_num_parens (0), m_postfix_index_type ('\0'), - m_for_cmd_expr (false), m_print_flag (false) { } + : tree (l, c), m_postfix_index_type ('\0'), m_for_cmd_expr (false), m_print_flag (false) { } OCTAVE_DISABLE_COPY_MOVE (tree_expression) @@ -85,7 +86,14 @@ virtual octave_lvalue lvalue (tree_evaluator&); - int paren_count () const { return m_num_parens; } + // The number of times this expression appears directly inside a set + // of delimiters. + // + // (([e1]) + e2) ==> 2 for expression e1 + // ==> 1 for expression ([e1]) + e2 + // ==> 0 for expression e2 + + size_t delim_count () const { return m_delims.count (); } bool is_postfix_indexed () const { return (m_postfix_index_type != '\0'); } @@ -107,9 +115,9 @@ bool is_for_cmd_expr () const { return m_for_cmd_expr; } - tree_expression * mark_in_parens () + tree_expression * mark_in_delims (const token& open_delim, const token& close_delim) { - m_num_parens++; + m_delims.push (open_delim, close_delim); return this; } @@ -127,9 +135,9 @@ virtual void copy_base (const tree_expression& e) { - m_num_parens = e.m_num_parens; m_postfix_index_type = e.m_postfix_index_type; m_print_flag = e.m_print_flag; + m_delims = e.m_delims; } virtual octave_value evaluate (tree_evaluator& tw, int nargout = 1) = 0; @@ -139,14 +147,6 @@ protected: - // A count of the number of times this expression appears directly - // inside a set of parentheses. - // - // (((e1)) + e2) ==> 2 for expression e1 - // ==> 1 for expression ((e1)) + e2 - // ==> 0 for expression e2 - int m_num_parens; - // The first index type associated with this expression. This field // is 0 (character '\0') if the expression has no associated index. // See the code in tree_identifier::rvalue for the rationale. @@ -158,6 +158,9 @@ // Print result of rvalue for this expression? bool m_print_flag; + + // Tokens for any delimiters surrounding this expression. + tree_delimiter_list m_delims; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-id.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-id.cc Tue Apr 02 16:11:12 2024 -0400 @@ -81,8 +81,7 @@ symbol_record new_sym = scope.find_symbol (name ()); - tree_identifier *new_id - = new tree_identifier (new_sym, line (), column ()); + tree_identifier *new_id = new tree_identifier (new_sym, m_token); new_id->copy_base (*this);
--- a/libinterp/parse-tree/pt-id.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-id.h Tue Apr 02 16:11:12 2024 -0400 @@ -35,11 +35,13 @@ class octave_value_list; class octave_function; +#include "comment-list.h" #include "oct-lvalue.h" #include "pt-bp.h" #include "pt-exp.h" #include "pt-walk.h" #include "symscope.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -53,12 +55,15 @@ public: - tree_identifier (int l = -1, int c = -1) - : tree_expression (l, c), m_sym () { } + tree_identifier (const token& tok) + : tree_expression (tok.line (), tok.column ()), m_sym (), m_token (tok) + { } - tree_identifier (const symbol_record& s, - int l = -1, int c = -1) - : tree_expression (l, c), m_sym (s) { } + tree_identifier (symbol_scope& scope, const token& tok) + : tree_expression (tok.line (), tok.column ()), + m_sym (scope ? scope.insert (tok.text ()) : symbol_record (tok.text ())), + m_token (tok) + { } OCTAVE_DISABLE_COPY_MOVE (tree_identifier) @@ -68,6 +73,8 @@ std::string name () const { return m_sym.name (); } + comment_list leading_comments () const { return m_token.leading_comments (); } + virtual bool is_black_hole () const { return false; } void mark_as_formal_parameter () { m_sym.mark_formal (); } @@ -105,18 +112,38 @@ symbol_record symbol () const { return m_sym; } + tree_identifier * mark_get_set (const token& get_set_tok, const token& dot_tok) + { + m_get_set_tok = get_set_tok; + m_dot_tok = dot_tok; + + return this; + } + protected: + tree_identifier (symbol_record& sym, const token& tok) + : tree_expression (tok.line (), tok.column ()), m_sym (sym), m_token (tok) + { } + // The symbol record that this identifier references. symbol_record m_sym; + + // These will be defined for get.ID or set.ID function names. + token m_get_set_tok; + token m_dot_tok; + + // The IDENT token from the lexer. + token m_token; }; class tree_black_hole : public tree_identifier { public: - tree_black_hole (int l = -1, int c = -1) - : tree_identifier (l, c) { } + tree_black_hole (const token& token) + : tree_identifier (token) + { } OCTAVE_DISABLE_COPY_MOVE (tree_black_hole) @@ -128,7 +155,7 @@ tree_black_hole * dup (symbol_scope&) const { - return new tree_black_hole; + return new tree_black_hole (m_token); } octave_lvalue lvalue (tree_evaluator& tw);
--- a/libinterp/parse-tree/pt-idx.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-idx.cc Tue Apr 02 16:11:12 2024 -0400 @@ -47,38 +47,31 @@ // Index expressions. tree_index_expression::tree_index_expression (int l, int c) - : tree_expression (l, c), m_expr (nullptr), m_args (0), m_type (), - m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { } + : tree_expression (l, c) +{ } -tree_index_expression::tree_index_expression (tree_expression *e, - tree_argument_list *lst, - int l, int c, char t) - : tree_expression (l, c), m_expr (e), m_args (0), m_type (), - m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) +tree_index_expression::tree_index_expression (tree_expression *e, const token& open_delim, tree_argument_list *lst, const token& close_delim, int l, int c, char t) + : tree_expression (l, c), m_expr (e), m_args (0), m_type (), m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { - append (lst, t); + append (open_delim, lst, close_delim, t); } -tree_index_expression::tree_index_expression (tree_expression *e, - const std::string& n, - int l, int c) - : tree_expression (l, c), m_expr (e), m_args (0), m_type (), - m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) +tree_index_expression::tree_index_expression (tree_expression *e, const token& dot_tok, const token& struct_elt_tok, int l, int c) + : tree_expression (l, c), m_expr (e), m_args (0), m_type (), m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { - append (n); + append (dot_tok, struct_elt_tok); } -tree_index_expression::tree_index_expression (tree_expression *e, - tree_expression *df, - int l, int c) - : tree_expression (l, c), m_expr (e), m_args (0), m_type (), - m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) +tree_index_expression::tree_index_expression (tree_expression *e, const token& dot_tok, const token& open_paren, tree_expression *df, const token& close_paren, int l, int c) + : tree_expression (l, c), m_expr (e), m_args (0), m_type (), m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { - append (df); + append (dot_tok, open_paren, df, close_paren); } +// FIXME: Need to handle open_delim and close_delim. + tree_index_expression * -tree_index_expression::append (tree_argument_list *lst, char t) +tree_index_expression::append (const token& /*open_delim*/, tree_argument_list *lst, const token& /*close_delim*/, char t) { m_args.push_back (lst); m_type.append (1, t); @@ -91,19 +84,23 @@ return this; } +// FIXME: Need to handle dot_tok. + tree_index_expression * -tree_index_expression::append (const std::string& n) +tree_index_expression::append (const token& /*dot_tok*/, const token& struct_elt_tok) { m_args.push_back (static_cast<tree_argument_list *> (nullptr)); m_type += '.'; - m_arg_nm.push_back (n); + m_arg_nm.push_back (struct_elt_tok.text ()); m_dyn_field.push_back (static_cast<tree_expression *> (nullptr)); return this; } +// FIXME: Need to handle dot_tok, open_paren, and close_paren. + tree_index_expression * -tree_index_expression::append (tree_expression *df) +tree_index_expression::append (const token& /*dot_tok*/, const token& /*open_paren*/, tree_expression *df, const token& /*close_paren*/) { m_args.push_back (static_cast<tree_argument_list *> (nullptr)); m_type += '.';
--- a/libinterp/parse-tree/pt-idx.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-idx.h Tue Apr 02 16:11:12 2024 -0400 @@ -52,26 +52,22 @@ { public: - tree_index_expression (tree_expression *e = nullptr, - tree_argument_list *lst = nullptr, - int l = -1, int c = -1, char t = '('); + tree_index_expression (tree_expression *e, const token& open_delim, tree_argument_list *lst, const token& close_delim, int l, int c, char t); - tree_index_expression (tree_expression *e, const std::string& n, - int l = -1, int c = -1); + tree_index_expression (tree_expression *e, const token& dot_tok, const token& struct_elt_tok, int l = -1, int c = -1); - tree_index_expression (tree_expression *e, tree_expression *df, - int l = -1, int c = -1); + tree_index_expression (tree_expression *e, const token& dot_tok, const token& open_paren, tree_expression *df, const token& close_paren, int l = -1, int c = -1); OCTAVE_DISABLE_COPY_MOVE (tree_index_expression) ~tree_index_expression (); tree_index_expression * - append (tree_argument_list *lst = nullptr, char t = '('); + append (const token& open_delim, tree_argument_list *lst, const token& close_delim, char t = '('); - tree_index_expression * append (const std::string& n); + tree_index_expression * append (const token& dot_tok, const token& struct_elt_tok); - tree_index_expression * append (tree_expression *df); + tree_index_expression * append (const token& dot_tok, const token& open_paren, tree_expression *df, const token& close_paren); bool is_index_expression () const { return true; } @@ -121,7 +117,7 @@ private: // The LHS of this index expression. - tree_expression *m_expr; + tree_expression *m_expr {nullptr}; // The indices (only valid if type == paren || type == brace). std::list<tree_argument_list *> m_args; @@ -137,7 +133,7 @@ std::list<tree_expression *> m_dyn_field; // TRUE if this expression was parsed as a word list command. - bool m_word_list_cmd; + bool m_word_list_cmd {false}; tree_index_expression (int l, int c);
--- a/libinterp/parse-tree/pt-loop.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-loop.cc Tue Apr 02 16:11:12 2024 -0400 @@ -39,9 +39,15 @@ tree_while_command::~tree_while_command () { delete m_expr; - delete m_list; - delete m_lead_comm; - delete m_trail_comm; + delete m_body; +} + +// Do-until. + +tree_do_until_command::~tree_do_until_command () +{ + delete m_body; + delete m_expr; } // For. @@ -51,18 +57,14 @@ delete m_lhs; delete m_expr; delete m_maxproc; - delete m_list; - delete m_lead_comm; - delete m_trail_comm; + delete m_body; } tree_complex_for_command::~tree_complex_for_command () { delete m_lhs; delete m_expr; - delete m_list; - delete m_lead_comm; - delete m_trail_comm; + delete m_body; } OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-loop.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-loop.h Tue Apr 02 16:11:12 2024 -0400 @@ -35,6 +35,7 @@ OCTAVE_BEGIN_NAMESPACE(octave) +class comment_list; class tree_argument_list; class tree_expression; class tree_statement_list; @@ -45,25 +46,8 @@ { public: - tree_while_command (int l = -1, int c = -1) - : tree_command (l, c), m_expr (nullptr), m_list (nullptr), - m_lead_comm (nullptr), m_trail_comm (nullptr) - { } - - tree_while_command (tree_expression *e, - comment_list *lc = nullptr, - comment_list *tc = nullptr, - int l = -1, int c = -1) - : tree_command (l, c), m_expr (e), m_list (nullptr), - m_lead_comm (lc), m_trail_comm (tc) - { } - - tree_while_command (tree_expression *e, tree_statement_list *lst, - comment_list *lc = nullptr, - comment_list *tc = nullptr, - int l = -1, int c = -1) - : tree_command (l, c), m_expr (e), m_list (lst), m_lead_comm (lc), - m_trail_comm (tc) + tree_while_command (const token& while_tok, tree_expression *expr, tree_statement_list *body, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_while_tok (while_tok), m_expr (expr), m_body (body), m_end_tok (end_tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_while_command) @@ -72,64 +56,60 @@ tree_expression * condition () { return m_expr; } - tree_statement_list * body () { return m_list; } - - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } + tree_statement_list * body () { return m_body; } void accept (tree_walker& tw) { tw.visit_while_command (*this); } -protected: +private: + + token m_while_tok; // Expression to test. tree_expression *m_expr; // List of commands to execute. - tree_statement_list *m_list; + tree_statement_list *m_body {nullptr}; - // Comment preceding WHILE token. - comment_list *m_lead_comm; - - // Comment preceding ENDWHILE token. - comment_list *m_trail_comm; + token m_end_tok; }; // Do-Until. -class tree_do_until_command : public tree_while_command +class tree_do_until_command : public tree_command { public: - tree_do_until_command (int l = -1, int c = -1) - : tree_while_command (l, c) - { } - - tree_do_until_command (tree_expression *e, - comment_list *lc = nullptr, - comment_list *tc = nullptr, - int l = -1, int c = -1) - : tree_while_command (e, lc, tc, l, c) - { } - - tree_do_until_command (tree_expression *e, tree_statement_list *lst, - comment_list *lc = nullptr, - comment_list *tc = nullptr, - int l = -1, int c = -1) - : tree_while_command (e, lst, lc, tc, l, c) + tree_do_until_command (const token& do_tok, tree_statement_list *body, const token& until_tok, tree_expression *expr, int l = -1, int c = -1) + : tree_command (l, c), m_do_tok (do_tok), m_body (body), m_until_tok (until_tok), m_expr (expr) { } OCTAVE_DISABLE_COPY_MOVE (tree_do_until_command) - ~tree_do_until_command () = default; + ~tree_do_until_command (); + + tree_statement_list * body () { return m_body; } + + tree_expression * condition () { return m_expr; } void accept (tree_walker& tw) { tw.visit_do_until_command (*this); } + +private: + + token m_do_tok; + + // List of commands to execute. + tree_statement_list *m_body {nullptr}; + + token m_until_tok; + + // Expression to test. + tree_expression *m_expr; }; // For. @@ -138,29 +118,19 @@ { public: - tree_simple_for_command (int l = -1, int c = -1) - : tree_command (l, c), m_parallel (false), m_lhs (nullptr), - m_expr (nullptr), m_maxproc (nullptr), m_list (nullptr), - m_lead_comm (nullptr), m_trail_comm (nullptr) - { } - - tree_simple_for_command (bool parallel_arg, tree_expression *le, - tree_expression *re, - tree_expression *maxproc_arg, - tree_statement_list *lst, - comment_list *lc = nullptr, - comment_list *tc = nullptr, - int l = -1, int c = -1) - : tree_command (l, c), m_parallel (parallel_arg), m_lhs (le), - m_expr (re), m_maxproc (maxproc_arg), m_list (lst), - m_lead_comm (lc), m_trail_comm (tc) + tree_simple_for_command (bool parfor, const token& for_tok, const token& open_paren, tree_expression *le, const token& eq_tok, + tree_expression *re, const token& sep_tok, tree_expression *maxproc_arg, const token& close_paren, + tree_statement_list *body, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_parfor (parfor), m_for_tok (for_tok), m_open_paren (open_paren), m_lhs (le), m_eq_tok (eq_tok), + m_expr (re), m_sep_tok (sep_tok), m_maxproc (maxproc_arg), m_close_paren (close_paren), + m_body (body), m_end_tok (end_tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_simple_for_command) ~tree_simple_for_command (); - bool in_parallel () { return m_parallel; } + bool in_parallel () { return m_parfor; } tree_expression * left_hand_side () { return m_lhs; } @@ -168,11 +138,7 @@ tree_expression * maxproc_expr () { return m_maxproc; } - tree_statement_list * body () { return m_list; } - - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } + tree_statement_list * body () { return m_body; } void accept (tree_walker& tw) { @@ -180,46 +146,44 @@ } private: - // TRUE means operate in parallel (subject to the value of the - // maxproc expression). - bool m_parallel; + + // FIXME: it would be better to get this info from FOR_TOK. + bool m_parfor {false}; + + token m_for_tok; + + token m_open_paren; // Expression to modify. tree_expression *m_lhs; + token m_eq_tok; + // Expression to evaluate. tree_expression *m_expr; + token m_sep_tok; + // Expression to tell how many processors should be used (only valid // if parallel is TRUE). - tree_expression *m_maxproc; + tree_expression *m_maxproc {nullptr}; + + token m_close_paren; // List of commands to execute. - tree_statement_list *m_list; + tree_statement_list *m_body; - // Comment preceding FOR token. - comment_list *m_lead_comm; - - // Comment preceding ENDFOR token. - comment_list *m_trail_comm; + token m_end_tok; }; class tree_complex_for_command : public tree_command { public: - tree_complex_for_command (int l = -1, int c = -1) - : tree_command (l, c), m_lhs (nullptr), m_expr (nullptr), - m_list (nullptr), m_lead_comm (nullptr), m_trail_comm (nullptr) - { } - - tree_complex_for_command (tree_argument_list *le, tree_expression *re, - tree_statement_list *lst, - comment_list *lc = nullptr, - comment_list *tc = nullptr, - int l = -1, int c = -1) - : tree_command (l, c), m_lhs (le), m_expr (re), m_list (lst), - m_lead_comm (lc), m_trail_comm (tc) + tree_complex_for_command (const token& for_tok, tree_argument_list *le, const token& eq_tok, tree_expression *re, + tree_statement_list *body, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_for_tok (for_tok), m_lhs (le), m_eq_tok (eq_tok), m_expr (re), + m_body (body), m_end_tok (end_tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_complex_for_command) @@ -230,11 +194,7 @@ tree_expression * control_expr () { return m_expr; } - tree_statement_list * body () { return m_list; } - - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } + tree_statement_list * body () { return m_body; } void accept (tree_walker& tw) { @@ -243,20 +203,20 @@ private: + token m_for_tok; + // Expression to modify. tree_argument_list *m_lhs; + token m_eq_tok; + // Expression to evaluate. tree_expression *m_expr; // List of commands to execute. - tree_statement_list *m_list; + tree_statement_list *m_body; - // Comment preceding FOR token. - comment_list *m_lead_comm; - - // Comment preceding ENDFOR token. - comment_list *m_trail_comm; + token m_end_tok; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-misc.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-misc.h Tue Apr 02 16:11:12 2024 -0400 @@ -73,6 +73,14 @@ ~tree_parameter_list (); + tree_parameter_list * mark_in_delims (const token& open_delim, const token& close_delim) + { + m_open_delim = open_delim; + m_close_delim = close_delim; + + return this; + } + void mark_as_formal_parameters (); void mark_varargs () { m_marked_for_varargs = 1; } @@ -109,6 +117,9 @@ // -1: takes varargs only // 0: does not take varargs. int m_marked_for_varargs; + + token m_open_delim; + token m_close_delim; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-pr-code.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-pr-code.cc Tue Apr 02 16:11:12 2024 -0400 @@ -238,7 +238,7 @@ void tree_print_code::visit_simple_for_command (tree_simple_for_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -281,8 +281,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << (cmd.in_parallel () ? "endparfor" : "endfor"); @@ -291,7 +289,7 @@ void tree_print_code::visit_complex_for_command (tree_complex_for_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -324,8 +322,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "endfor"; @@ -334,7 +330,7 @@ void tree_print_code::visit_spmd_command (tree_spmd_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -353,8 +349,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "endspmd"; @@ -395,11 +389,11 @@ void tree_print_code::visit_octave_user_function_header (octave_user_function& fcn) { - comment_list *leading_comment = fcn.leading_comment (); + comment_list leading_comments = fcn.leading_comments (); - if (leading_comment) + if (! leading_comments.empty ()) { - print_comment_list (leading_comment); + print_comment_list (leading_comments); newline (); } @@ -430,7 +424,7 @@ void tree_print_code::visit_octave_user_function_trailer (octave_user_function& fcn) { - print_indented_comment (fcn.trailing_comment ()); + print_indented_comment (fcn.trailing_comments ()); newline (); } @@ -486,7 +480,7 @@ void tree_print_code::visit_if_command (tree_if_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -497,8 +491,6 @@ if (list) list->accept (*this); - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "endif"; @@ -519,7 +511,7 @@ { if (! first_elt) { - print_indented_comment (elt->leading_comment ()); + print_indented_comment (elt->leading_comments ()); indent (); @@ -566,7 +558,7 @@ case '(': { char nc = m_nesting.top (); - if ((nc == '[' || nc == '{') && expr.paren_count () == 0) + if ((nc == '[' || nc == '{') && expr.delim_count () == 0) m_os << '('; else m_os << " ("; @@ -584,7 +576,7 @@ case '{': { char nc = m_nesting.top (); - if ((nc == '[' || nc == '{') && expr.paren_count () == 0) + if ((nc == '[' || nc == '{') && expr.delim_count () == 0) m_os << '{'; else m_os << " {"; @@ -896,7 +888,7 @@ void tree_print_code::visit_statement (tree_statement& stmt) { - print_comment_list (stmt.comment_text ()); + print_comment_list (stmt.leading_comments ()); tree_command *cmd = stmt.command (); @@ -938,7 +930,7 @@ void tree_print_code::visit_switch_case (tree_switch_case& cs) { - print_comment_list (cs.leading_comment ()); + print_comment_list (cs.leading_comments ()); indent (); @@ -971,7 +963,7 @@ void tree_print_code::visit_switch_command (tree_switch_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -995,7 +987,7 @@ decrement_indent_level (); } - print_indented_comment (cmd.leading_comment ()); + print_indented_comment (cmd.leading_comments ()); indent (); @@ -1005,7 +997,7 @@ void tree_print_code::visit_try_catch_command (tree_try_catch_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -1025,8 +1017,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.middle_comment ()); - indent (); m_os << "catch"; @@ -1050,8 +1040,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "end_try_catch"; @@ -1060,7 +1048,7 @@ void tree_print_code::visit_unwind_protect_command (tree_unwind_protect_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -1079,8 +1067,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.middle_comment ()); - indent (); m_os << "unwind_protect_cleanup"; @@ -1098,8 +1084,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "end_unwind_protect"; @@ -1108,7 +1092,7 @@ void tree_print_code::visit_while_command (tree_while_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -1132,8 +1116,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "endwhile"; @@ -1142,7 +1124,7 @@ void tree_print_code::visit_do_until_command (tree_do_until_command& cmd) { - print_comment_list (cmd.leading_comment ()); + print_comment_list (cmd.leading_comments ()); indent (); @@ -1161,8 +1143,6 @@ decrement_indent_level (); } - print_indented_comment (cmd.trailing_comment ()); - indent (); m_os << "until "; @@ -1247,7 +1227,7 @@ void tree_print_code::print_parens (const tree_expression& expr, const char *txt) { - int n = expr.paren_count (); + int n = expr.delim_count (); for (int i = 0; i < n; i++) m_os << txt; @@ -1314,26 +1294,23 @@ } void -tree_print_code::print_comment_list (comment_list *comment_list) +tree_print_code::print_comment_list (const comment_list& comment_list) { - if (comment_list) - { - auto p = comment_list->begin (); + auto p = comment_list.begin (); - while (p != comment_list->end ()) - { - comment_elt elt = *p++; + while (p != comment_list.end ()) + { + comment_elt elt = *p++; - print_comment_elt (elt); + print_comment_elt (elt); - if (p != comment_list->end ()) - newline (); - } + if (p != comment_list.end ()) + newline (); } } void -tree_print_code::print_indented_comment (comment_list *comment_list) +tree_print_code::print_indented_comment (const comment_list& comment_list) { increment_indent_level ();
--- a/libinterp/parse-tree/pt-pr-code.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-pr-code.h Tue Apr 02 16:11:12 2024 -0400 @@ -195,11 +195,11 @@ void print_parens (const tree_expression& expr, const char *txt); - void print_comment_list (comment_list *comment_list); + void print_comment_list (const comment_list& comment_list); void print_comment_elt (const comment_elt& comment_elt); - void print_indented_comment (comment_list *comment_list); + void print_indented_comment (const comment_list& comment_list); // Must create with an output stream!
--- a/libinterp/parse-tree/pt-select.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-select.cc Tue Apr 02 16:11:12 2024 -0400 @@ -39,7 +39,6 @@ { delete m_expr; delete m_list; - delete m_lead_comm; } // If. @@ -47,8 +46,6 @@ tree_if_command::~tree_if_command () { delete m_list; - delete m_lead_comm; - delete m_trail_comm; } // Switch cases. @@ -57,7 +54,6 @@ { delete m_label; delete m_list; - delete m_lead_comm; } // Switch. @@ -66,8 +62,6 @@ { delete m_expr; delete m_list; - delete m_lead_comm; - delete m_trail_comm; } OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-select.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-select.h Tue Apr 02 16:11:12 2024 -0400 @@ -33,9 +33,11 @@ #include "comment-list.h" #include "pt-cmd.h" #include "pt-walk.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) +class comment_list; class tree_expression; class tree_statement_list; @@ -45,30 +47,23 @@ { public: - tree_if_clause (int l = -1, int c = -1) - : tree (l, c), m_expr (nullptr), m_list (nullptr), m_lead_comm (nullptr) + tree_if_clause (const token& tok, tree_expression *e, tree_statement_list *sl, int l = -1, int c = -1) + : tree (l, c), m_tok (tok), m_expr (e), m_list (sl) { } - tree_if_clause (tree_statement_list *sl, comment_list *lc = nullptr, - int l = -1, int c = -1) - : tree (l, c), m_expr (nullptr), m_list (sl), m_lead_comm (lc) { } - - tree_if_clause (tree_expression *e, tree_statement_list *sl, - comment_list *lc = nullptr, - int l = -1, int c = -1) - : tree (l, c), m_expr (e), m_list (sl), m_lead_comm (lc) { } - - OCTAVE_DISABLE_COPY_MOVE (tree_if_clause) + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_if_clause) ~tree_if_clause (); + token if_token () const { return m_tok; } + bool is_else_clause () { return ! m_expr; } tree_expression * condition () { return m_expr; } tree_statement_list * commands () { return m_list; } - comment_list * leading_comment () { return m_lead_comm; } + comment_list leading_comments () const { return m_tok.leading_comments (); } void accept (tree_walker& tw) { @@ -77,14 +72,13 @@ private: + token m_tok; + // The condition to test. - tree_expression *m_expr; + tree_expression *m_expr = nullptr; // The list of statements to evaluate if expr is true. tree_statement_list *m_list; - - // Comment preceding ELSE or ELSEIF token. - comment_list *m_lead_comm; }; class tree_if_command_list : public std::list<tree_if_clause *> @@ -107,6 +101,17 @@ } } + token if_token () const + { + if (! empty ()) + { + tree_if_clause *p = front (); + return p->if_token (); + } + + return token (); + } + void accept (tree_walker& tw) { tw.visit_if_command_list (*this); @@ -117,25 +122,21 @@ { public: - tree_if_command (int l = -1, int c = -1) - : tree_command (l, c), m_list (nullptr), - m_lead_comm (nullptr), m_trail_comm (nullptr) + tree_if_command (const token& if_tok, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_if_tok (if_tok), m_end_tok (end_tok) { } - tree_if_command (tree_if_command_list *lst, comment_list *lc, - comment_list *tc, int l = -1, int c = -1) - : tree_command (l, c), m_list (lst), m_lead_comm (lc), m_trail_comm (tc) + tree_if_command (const token& if_tok, tree_if_command_list *lst, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_if_tok (if_tok), m_list (lst), m_end_tok (end_tok) { } - OCTAVE_DISABLE_COPY_MOVE (tree_if_command) + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_if_command) ~tree_if_command (); tree_if_command_list * cmd_list () { return m_list; } - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } + comment_list leading_comments () const { return m_if_tok.leading_comments (); } void accept (tree_walker& tw) { @@ -144,14 +145,12 @@ private: - // List of if commands (if, elseif, elseif, ... else, endif) - tree_if_command_list *m_list; + token m_if_tok; - // Comment preceding IF token. - comment_list *m_lead_comm; + // List of if commands (if, elseif, elseif, ... else, endif) + tree_if_command_list *m_list = nullptr; - // Comment preceding ENDIF token. - comment_list *m_trail_comm; + token m_end_tok; }; // Switch. @@ -160,20 +159,15 @@ { public: - tree_switch_case (int l = -1, int c = -1) - : tree (l, c), m_label (nullptr), m_list (nullptr), m_lead_comm (nullptr) + tree_switch_case (const token& tok, tree_statement_list *sl, int l = -1, int c = -1) + : tree (l, c), m_tok (tok), m_list (sl) { } - tree_switch_case (tree_statement_list *sl, comment_list *lc = nullptr, - int l = -1, int c = -1) - : tree (l, c), m_label (nullptr), m_list (sl), m_lead_comm (lc) { } + tree_switch_case (const token& tok, tree_expression *e, tree_statement_list *sl, int l = -1, int c = -1) + : tree (l, c), m_tok (tok), m_label (e), m_list (sl) + { } - tree_switch_case (tree_expression *e, tree_statement_list *sl, - comment_list *lc = nullptr, - int l = -1, int c = -1) - : tree (l, c), m_label (e), m_list (sl), m_lead_comm (lc) { } - - OCTAVE_DISABLE_COPY_MOVE (tree_switch_case) + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_switch_case) ~tree_switch_case (); @@ -183,7 +177,7 @@ tree_statement_list * commands () { return m_list; } - comment_list * leading_comment () { return m_lead_comm; } + comment_list leading_comments () const { return m_tok.leading_comments (); } void accept (tree_walker& tw) { @@ -192,14 +186,13 @@ private: + token m_tok; + // The case label. - tree_expression *m_label; + tree_expression *m_label = nullptr; // The list of statements to evaluate if the label matches. tree_statement_list *m_list; - - // Comment preceding CASE or OTHERWISE token. - comment_list *m_lead_comm; }; class tree_switch_case_list : public std::list<tree_switch_case *> @@ -232,17 +225,11 @@ { public: - tree_switch_command (int l = -1, int c = -1) - : tree_command (l, c), m_expr (nullptr), m_list (nullptr), - m_lead_comm (nullptr), m_trail_comm (nullptr) { } + tree_switch_command (const token& switch_tok, tree_expression *e, tree_switch_case_list *lst, const token& end_tok, int l = -1, int c = -1) + : tree_command (l, c), m_switch_tok (switch_tok), m_expr (e), m_list (lst), m_end_tok (end_tok) + { } - tree_switch_command (tree_expression *e, tree_switch_case_list *lst, - comment_list *lc, comment_list *tc, - int l = -1, int c = -1) - : tree_command (l, c), m_expr (e), m_list (lst), m_lead_comm (lc), - m_trail_comm (tc) { } - - OCTAVE_DISABLE_COPY_MOVE (tree_switch_command) + OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_switch_command) ~tree_switch_command (); @@ -250,9 +237,7 @@ tree_switch_case_list * case_list () { return m_list; } - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } + comment_list leading_comments () const { return m_switch_tok.leading_comments (); } void accept (tree_walker& tw) { @@ -261,17 +246,15 @@ private: + token m_switch_tok; + // Value on which to switch. tree_expression *m_expr; // List of cases (case 1, case 2, ..., default) tree_switch_case_list *m_list; - // Comment preceding SWITCH token. - comment_list *m_lead_comm; - - // Comment preceding ENDSWITCH token. - comment_list *m_trail_comm; + token m_end_tok; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-spmd.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-spmd.cc Tue Apr 02 16:11:12 2024 -0400 @@ -36,8 +36,6 @@ tree_spmd_command::~tree_spmd_command () { delete m_body; - delete m_lead_comm; - delete m_trail_comm; } OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-spmd.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-spmd.h Tue Apr 02 16:11:12 2024 -0400 @@ -33,7 +33,7 @@ OCTAVE_BEGIN_NAMESPACE(octave) -class tree_comment_list; +class comment_list; class tree_statement_list; // Spmd. @@ -42,9 +42,8 @@ { public: - tree_spmd_command (tree_statement_list *body, comment_list *lc, - comment_list *tc, int l = -1, int c = -1) - : tree_command (l, c), m_body (body), m_lead_comm (lc), m_trail_comm (tc) + tree_spmd_command (tree_statement_list *body, int l = -1, int c = -1) + : tree_command (l, c), m_body (body) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_spmd_command) @@ -53,10 +52,6 @@ tree_statement_list * body () { return m_body; } - comment_list * leading_comment () { return m_lead_comm; } - - comment_list * trailing_comment () { return m_trail_comm; } - void accept (tree_walker& tw) { tw.visit_spmd_command (*this); @@ -66,12 +61,6 @@ // List of commands. tree_statement_list *m_body; - - // Comment preceding SPMD token. - comment_list *m_lead_comm; - - // Comment preceding ENDSPMD token. - comment_list *m_trail_comm; }; OCTAVE_END_NAMESPACE(octave)
--- a/libinterp/parse-tree/pt-stmt.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-stmt.cc Tue Apr 02 16:11:12 2024 -0400 @@ -57,7 +57,6 @@ { delete m_command; delete m_expression; - delete m_comment_list; } void @@ -107,6 +106,14 @@ : false); } +comment_list +tree_statement::leading_comments () const +{ + return (m_command + ? m_command->leading_comments () + : m_expression->leading_comments ()); +} + std::string tree_statement::bp_cond () const { @@ -182,6 +189,20 @@ return retval; } +comment_list +tree_statement_list::leading_comments () const +{ + if (! empty ()) + { + tree_statement *elt = front (); + + if (elt) + return elt->leading_comments (); + } + + return comment_list (); +} + // Create a "breakpoint" tree-walker, and get it to "walk" this // statement list // (FIXME: What does that do???)
--- a/libinterp/parse-tree/pt-stmt.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-stmt.h Tue Apr 02 16:11:12 2024 -0400 @@ -54,14 +54,16 @@ public: tree_statement () - : m_command (nullptr), m_expression (nullptr), - m_comment_list (nullptr) { } + : m_command (nullptr), m_expression (nullptr) + { } - tree_statement (tree_command *c, comment_list *cl) - : m_command (c), m_expression (nullptr), m_comment_list (cl) { } + tree_statement (tree_command *c) + : m_command (c), m_expression (nullptr) + { } - tree_statement (tree_expression *e, comment_list *cl) - : m_command (nullptr), m_expression (e), m_comment_list (cl) { } + tree_statement (tree_expression *e) + : m_command (nullptr), m_expression (e) + { } OCTAVE_DISABLE_COPY_MOVE (tree_statement) @@ -83,6 +85,8 @@ bool is_active_breakpoint (tree_evaluator& tw) const; + comment_list leading_comments () const; + std::string bp_cond () const; int line () const; @@ -96,11 +100,9 @@ tree_expression * expression () { return m_expression; } - comment_list * comment_text () { return m_comment_list; } - bool is_null_statement () const { - return ! (m_command || m_expression || m_comment_list); + return ! (m_command || m_expression); } bool is_end_of_fcn_or_script () const; @@ -129,9 +131,6 @@ // Expression to evaluate. tree_expression *m_expression; - - // Comment associated with this statement. - comment_list *m_comment_list; }; // A list of statements to evaluate. @@ -172,6 +171,8 @@ bool is_script_body () const { return m_script_body; } + comment_list leading_comments () const; + int set_breakpoint (int line, const std::string& condition); void delete_breakpoint (int line);
--- a/libinterp/parse-tree/pt-walk.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-walk.cc Tue Apr 02 16:11:12 2024 -0400 @@ -722,14 +722,14 @@ void tree_walker::visit_classdef_properties_block (tree_classdef_properties_block& blk) { - tree_classdef_property_list *property_list = blk.element_list (); + tree_classdef_property_list *property_list = blk.property_list (); if (property_list) property_list->accept (*this); } void -tree_walker::visit_classdef_methods_list (tree_classdef_methods_list& lst) +tree_walker::visit_classdef_method_list (tree_classdef_method_list& lst) { for (auto ov_meth : lst) { @@ -743,10 +743,10 @@ void tree_walker::visit_classdef_methods_block (tree_classdef_methods_block& blk) { - tree_classdef_methods_list *methods_list = blk.element_list (); + tree_classdef_method_list *method_list = blk.method_list (); - if (methods_list) - methods_list->accept (*this); + if (method_list) + method_list->accept (*this); } void @@ -756,7 +756,7 @@ } void -tree_walker::visit_classdef_events_list (tree_classdef_events_list& lst) +tree_walker::visit_classdef_event_list (tree_classdef_event_list& lst) { for (auto *elt : lst) { @@ -768,10 +768,10 @@ void tree_walker::visit_classdef_events_block (tree_classdef_events_block& blk) { - tree_classdef_events_list *events_list = blk.element_list (); + tree_classdef_event_list *event_list = blk.event_list (); - if (events_list) - events_list->accept (*this); + if (event_list) + event_list->accept (*this); } void @@ -793,7 +793,7 @@ void tree_walker::visit_classdef_enum_block (tree_classdef_enum_block& blk) { - tree_classdef_enum_list *enum_list = blk.element_list (); + tree_classdef_enum_list *enum_list = blk.enum_list (); if (enum_list) enum_list->accept (*this); @@ -802,20 +802,20 @@ void tree_walker::visit_classdef_body (tree_classdef_body& body) { - for (auto *elt : body.properties_list ()) + for (auto *elt : body.property_list ()) { if (elt) elt->accept (*this); } - for (auto *elt : body.methods_list ()) + for (auto *elt : body.method_list ()) { if (elt) elt->accept (*this); } - for (auto *elt : body.events_list ()) + for (auto *elt : body.event_list ()) { if (elt) elt->accept (*this);
--- a/libinterp/parse-tree/pt-walk.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt-walk.h Tue Apr 02 16:11:12 2024 -0400 @@ -96,10 +96,10 @@ class tree_classdef_property; class tree_classdef_property_list; class tree_classdef_properties_block; -class tree_classdef_methods_list; +class tree_classdef_method_list; class tree_classdef_methods_block; class tree_classdef_event; -class tree_classdef_events_list; +class tree_classdef_event_list; class tree_classdef_events_block; class tree_classdef_enum; class tree_classdef_enum_list; @@ -233,13 +233,13 @@ virtual void visit_classdef_properties_block (tree_classdef_properties_block&); - virtual void visit_classdef_methods_list (tree_classdef_methods_list&); + virtual void visit_classdef_method_list (tree_classdef_method_list&); virtual void visit_classdef_methods_block (tree_classdef_methods_block&); virtual void visit_classdef_event (tree_classdef_event&); - virtual void visit_classdef_events_list (tree_classdef_events_list&); + virtual void visit_classdef_event_list (tree_classdef_event_list&); virtual void visit_classdef_events_block (tree_classdef_events_block&);
--- a/libinterp/parse-tree/pt.cc Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt.cc Tue Apr 02 16:11:12 2024 -0400 @@ -30,6 +30,7 @@ #include <sstream> #include <string> +#include "comment-list.h" #include "interpreter.h" #include "ov-fcn.h" #include "pt.h" @@ -39,6 +40,12 @@ OCTAVE_BEGIN_NAMESPACE(octave) +comment_list +tree::leading_comments () const +{ + return comment_list (); +} + // Hide the details of the string buffer so that we are less likely to // create a memory leak.
--- a/libinterp/parse-tree/pt.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/pt.h Tue Apr 02 16:11:12 2024 -0400 @@ -36,6 +36,7 @@ OCTAVE_BEGIN_NAMESPACE(octave) +class comment_list; class tree_evaluator; class tree_walker; @@ -67,6 +68,9 @@ m_column_num = c; } + // FIXME: maybe make this a pure virtual function? + virtual comment_list leading_comments () const; + virtual void set_breakpoint (const std::string& condition) { if (m_bp_cond)
--- a/libinterp/parse-tree/token.h Tue Apr 02 12:59:14 2024 -0400 +++ b/libinterp/parse-tree/token.h Tue Apr 02 16:11:12 2024 -0400 @@ -31,6 +31,7 @@ #include <string> #include <variant> +#include "comment-list.h" #include "error.h" #include "filepos.h" #include "ov.h" @@ -43,6 +44,7 @@ enum token_type { + invalid_token, generic_token, keyword_token, string_token, @@ -73,32 +75,36 @@ public: - token (int id, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_comment_list (lst) + token () + : m_type_tag (invalid_token) { } - token (int id, bool is_kw, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (is_kw ? keyword_token : generic_token), m_comment_list (lst) + token (int id, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_leading_comments (lst) { } - token (int id, const char *s, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (string_token), m_tok_info (s), m_comment_list (lst) + token (int id, bool is_kw, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (is_kw ? keyword_token : generic_token), m_leading_comments (lst) { } - token (int id, const std::string& s, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (string_token), m_tok_info (s), m_comment_list (lst) + token (int id, const char *s, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (string_token), m_tok_info (s), m_leading_comments (lst) + { } + + token (int id, const std::string& s, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (string_token), m_tok_info (s), m_leading_comments (lst) { } - token (int id, const octave_value& val, const std::string& s, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (numeric_token), m_tok_info (val), m_orig_text (s), m_comment_list (lst) + token (int id, const octave_value& val, const std::string& s, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (numeric_token), m_tok_info (val), m_orig_text (s), m_leading_comments (lst) { } - token (int id, end_tok_type t, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (ettype_token), m_tok_info (t), m_comment_list (lst) + token (int id, end_tok_type t, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (ettype_token), m_tok_info (t), m_leading_comments (lst) { } - token (int id, const std::string& meth, const std::string& cls, const filepos& beg_pos, const filepos& end_pos, comment_list *lst = nullptr) - : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (scls_name_token), m_tok_info (meth, cls), m_comment_list (lst) + token (int id, const std::string& meth, const std::string& cls, const filepos& beg_pos, const filepos& end_pos, const comment_list& lst = comment_list ()) + : m_beg_pos (beg_pos), m_end_pos (end_pos), m_tok_id (id), m_type_tag (scls_name_token), m_tok_info (meth, cls), m_leading_comments (lst) { } OCTAVE_DEFAULT_COPY_MOVE_DELETE (token) @@ -123,6 +129,12 @@ void beg_pos (const filepos& pos) { m_beg_pos = pos; } void end_pos (const filepos& pos) { m_end_pos = pos; } + comment_list leading_comments () const { return m_leading_comments; } + comment_list trailing_comments () const { return m_trailing_comments; } + + void leading_comments (const comment_list& lst) { m_leading_comments = lst; } + void trailing_comments (const comment_list& lst) { m_trailing_comments = lst; } + // These will probably be removed. int line () const { return m_beg_pos.line (); } int column () const { return m_beg_pos.column (); } @@ -153,7 +165,7 @@ filepos m_beg_pos; filepos m_end_pos; - int m_tok_id; + int m_tok_id {-1}; token_type m_type_tag {generic_token}; @@ -241,7 +253,12 @@ std::string m_orig_text; - comment_list *m_comment_list; + // Comments that appear prior to the token. + comment_list m_leading_comments; + + // Comments that appear after the token. This list is only used to + // hold comments that appear after the last token in a file. + comment_list m_trailing_comments; }; OCTAVE_END_NAMESPACE(octave)