# HG changeset patch # User John W. Eaton # Date 1712206808 14400 # Node ID ac3633dd67d1fde792cbfae03faf42065c67d7cd # Parent 0b4118c91dc994306cf8b1b9eb56b3f631ccc809# Parent 5b13f73bda6fe1a06783f682e974022f54e9a651 maint: merge default to bytecode-interpreter diff -r 0b4118c91dc9 -r ac3633dd67d1 libgui/src/m-editor/file-editor-tab.cc --- a/libgui/src/m-editor/file-editor-tab.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libgui/src/m-editor/file-editor-tab.cc Thu Apr 04 01:00:08 2024 -0400 @@ -1802,6 +1802,7 @@ { dlg->setWindowModality (Qt::NonModal); dlg->show (); + dlg->raise (); } } diff -r 0b4118c91dc9 -r ac3633dd67d1 libgui/src/m-editor/file-editor.cc --- a/libgui/src/m-editor/file-editor.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libgui/src/m-editor/file-editor.cc Thu Apr 04 01:00:08 2024 -0400 @@ -1194,6 +1194,7 @@ msgBox->setWindowModality (Qt::NonModal); msgBox->setAttribute (Qt::WA_DeleteOnClose); msgBox->show (); + msgBox->raise (); return; } @@ -1220,6 +1221,7 @@ msgBox->setWindowModality (Qt::NonModal); msgBox->setAttribute (Qt::WA_DeleteOnClose); msgBox->show (); + msgBox->raise (); return; } @@ -1820,6 +1822,7 @@ msgBox->setWindowModality (Qt::NonModal); msgBox->setAttribute (Qt::WA_DeleteOnClose); msgBox->show (); + msgBox->raise (); } else { diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/octave-value/cdef-class.cc --- a/libinterp/octave-value/cdef-class.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/octave-value/cdef-class.cc Thu Apr 04 01:00:08 2024 -0400 @@ -730,12 +730,15 @@ if (pfcn == nullptr) continue; - const int e = pfcn->ending_line (); - if (line <= e && e <= closest_match_end_line && pfcn->is_defined () + octave::filepos end_pos = pfcn->end_pos (); + + int end_line = end_pos.line (); + + if (line <= end_line && end_line <= closest_match_end_line && pfcn->is_defined () && pfcn->is_user_code ()) { closest_match = fcn; - closest_match_end_line = e; + closest_match_end_line = end_line; } } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/octave-value/ov-fcn.cc --- a/libinterp/octave-value/ov-fcn.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/octave-value/ov-fcn.cc Thu Apr 04 01:00:08 2024 -0400 @@ -27,18 +27,17 @@ # include "config.h" #endif +#include "lo-array-errwarn.h" #include "unwind-prot.h" #include "error.h" +#include "filepos.h" +#include "interpreter-private.h" +#include "interpreter.h" +#include "ov-fcn.h" #include "ovl.h" -#include "ov-fcn.h" #include "pt-eval.h" - -#include "error.h" -#include "interpreter-private.h" #include "symtab.h" -#include "interpreter.h" -#include "lo-array-errwarn.h" #include "pt-bytecode-walk.h" @@ -54,6 +53,18 @@ panic_impossible (); } +octave::filepos +octave_function::beg_pos () const +{ + panic_impossible (); +} + +octave::filepos +octave_function::end_pos () const +{ + panic_impossible (); +} + octave_value_list octave_function::call (octave::tree_evaluator& tw, int nargout, const octave_value_list& args) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/octave-value/ov-fcn.h --- a/libinterp/octave-value/ov-fcn.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/octave-value/ov-fcn.h Thu Apr 04 01:00:08 2024 -0400 @@ -40,6 +40,7 @@ OCTAVE_BEGIN_NAMESPACE(octave) +class filepos; class stack_frame; class tree_evaluator; class tree_walker; @@ -161,6 +162,9 @@ virtual std::string src_file_name () const { return ""; } + virtual octave::filepos beg_pos () const; + virtual octave::filepos end_pos () const; + // The name to show in the profiler (also used as map-key). virtual std::string profiler_name () const { return name (); } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/octave-value/ov-usr-fcn.cc --- a/libinterp/octave-value/ov-usr-fcn.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.cc Thu Apr 04 01:00:08 2024 -0400 @@ -27,6 +27,8 @@ # include "config.h" #endif +#include + #include #include "file-info.h" @@ -40,6 +42,7 @@ #include "defun.h" #include "error.h" #include "errwarn.h" +#include "filepos.h" #include "input.h" #include "ovl.h" #include "ov-usr-fcn.h" @@ -47,6 +50,7 @@ #include "pager.h" #include "pt-cmd.h" #include "pt-eval.h" +#include "pt-id.h" #include "pt-jump.h" #include "pt-misc.h" #include "pt-pr-code.h" @@ -89,6 +93,16 @@ delete m_file_info; } +octave::filepos octave_user_code::beg_pos () const +{ + return m_cmd_list->beg_pos (); +} + +octave::filepos octave_user_code::end_pos () const +{ + return m_cmd_list->end_pos (); +} + void octave_user_code::get_file_info () { @@ -259,17 +273,8 @@ // Ugh. This really needs to be simplified (code/data? // extrinsic/intrinsic state?). -octave_user_function::octave_user_function -(const octave::symbol_scope& scope, octave::tree_parameter_list *pl, - octave::tree_parameter_list *rl, octave::tree_statement_list *cl) - : octave_user_code ("", "", scope, cl, ""), - m_param_list (pl), m_ret_list (rl), - 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), - m_subfunction (false), m_inline_function (false), - m_anonymous_function (false), m_nested_function (false), - m_class_constructor (none), m_class_method (none) +octave_user_function::octave_user_function (const octave::symbol_scope& scope, octave::tree_identifier *id, octave::tree_parameter_list *pl, octave::tree_parameter_list *rl, octave::tree_statement_list *cl) + : octave_user_code ("", "", scope, cl, ""), m_id (id), m_param_list (pl), m_ret_list (rl), m_num_named_args (m_param_list ? m_param_list->size () : 0) { if (m_cmd_list) m_cmd_list->mark_as_function_body (); @@ -277,6 +282,7 @@ octave_user_function::~octave_user_function () { + delete m_id; delete m_param_list; delete m_ret_list; } @@ -349,13 +355,14 @@ // 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 // the next line after the function keyword if there are no statements. -// More precisely, the new location should probably be on the next line -// after the end of the parameter list, but we aren't tracking that -// information (yet). void octave_user_function::maybe_relocate_end_internal () { + // This shouldn't happen, but check and return early anyway. + if (m_anonymous_function) + return; + if (m_cmd_list && ! m_cmd_list->empty ()) { octave::tree_statement *last_stmt = m_cmd_list->back (); @@ -363,28 +370,37 @@ if (last_stmt && last_stmt->is_end_of_fcn_or_script () && last_stmt->is_end_of_file ()) { - octave::tree_statement_list::reverse_iterator - next_to_last_elt = m_cmd_list->rbegin (); - + octave::tree_statement_list::reverse_iterator next_to_last_elt = m_cmd_list->rbegin (); next_to_last_elt++; - int new_eof_line; - int new_eof_col; + octave::filepos new_eof_pos; if (next_to_last_elt == m_cmd_list->rend ()) { - new_eof_line = beginning_line (); - new_eof_col = beginning_column (); + // Empty function body, just the end statement. Set the + // new beginning of that statement to the end of the + // argument list (if any) or the end of the function name. + + // M_ID is only nullptr if this is an anonymous function + // and we shouldn't be updating the end position for that. + // So if there is no name and no parameter list, just + // return early. + + if (m_param_list) + new_eof_pos = m_param_list->end_pos (); + else if (m_id) + new_eof_pos = m_id->end_pos (); + else + return; } else { octave::tree_statement *next_to_last_stmt = *next_to_last_elt; - new_eof_line = next_to_last_stmt->line (); - new_eof_col = next_to_last_stmt->column (); + new_eof_pos = next_to_last_stmt->end_pos (); } - last_stmt->set_location (new_eof_line + 1, new_eof_col); + last_stmt->update_end_pos (new_eof_pos); } } } @@ -419,9 +435,14 @@ { std::ostringstream result; + octave::filepos bp = beg_pos (); + + int bp_line = bp.line (); + int bp_column = bp.column (); + if (is_anonymous_function ()) result << "anonymous@" << fcn_file_name () - << ':' << m_location_line << ':' << m_location_column; + << ':' << bp_line << ':' << bp_column; else if (is_subfunction ()) result << parent_fcn_name () << '>' << name (); else if (is_class_method ()) @@ -430,7 +451,7 @@ result << '@' << name (); else if (is_inline_function ()) result << "inline@" << fcn_file_name () - << ':' << m_location_line << ':' << m_location_column; + << ':' << bp_line << ':' << bp_column; else result << name (); @@ -691,20 +712,23 @@ octave_value octave_user_function::dump () const { + octave::filepos bp = beg_pos (); + octave::filepos ep = end_pos (); + std::map m - = {{ "user_code", octave_user_code::dump () }, - { "line", m_location_line }, - { "col", m_location_column }, - { "end_line", m_end_location_line }, - { "end_col", m_end_location_column }, - { "system_fcn_file", m_system_fcn_file }, - { "num_named_args", m_num_named_args }, - { "subfunction", m_subfunction }, - { "inline_function", m_inline_function }, - { "anonymous_function", m_anonymous_function }, - { "nested_function", m_nested_function }, - { "ctor_type", ctor_type_str () }, - { "class_method", m_class_method } + = {{ "user_code", octave_user_code::dump () }, + { "line", bp.line () }, + { "col", bp.column () }, + { "end_line", ep.line () }, + { "end_col", ep.column () }, + { "system_fcn_file", m_system_fcn_file }, + { "num_named_args", m_num_named_args }, + { "subfunction", m_subfunction }, + { "inline_function", m_inline_function }, + { "anonymous_function", m_anonymous_function }, + { "nested_function", m_nested_function }, + { "ctor_type", ctor_type_str () }, + { "class_method", m_class_method } }; return octave_value (m); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/octave-value/ov-usr-fcn.h --- a/libinterp/octave-value/ov-usr-fcn.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/octave-value/ov-usr-fcn.h Thu Apr 04 01:00:08 2024 -0400 @@ -31,6 +31,7 @@ #include #include "comment-list.h" +#include "filepos.h" #include "ovl.h" #include "ov-fcn.h" #include "ov-typeinfo.h" @@ -47,8 +48,10 @@ OCTAVE_BEGIN_NAMESPACE(octave) +class filepos; class file_info; class stack_frame; +class tree_identifier; class tree_parameter_list; class tree_statement_list; class tree_evaluator; @@ -82,6 +85,9 @@ bool is_user_code () const { return true; } + octave::filepos beg_pos () const; + octave::filepos end_pos () const; + std::string get_code_line (std::size_t line); std::deque get_code_lines (std::size_t line, @@ -227,10 +233,8 @@ { public: - octave_user_function (const octave::symbol_scope& scope = octave::symbol_scope::anonymous (), - octave::tree_parameter_list *pl = nullptr, - octave::tree_parameter_list *rl = nullptr, - octave::tree_statement_list *cl = nullptr); + octave_user_function (const octave::symbol_scope& scope = octave::symbol_scope::anonymous (), octave::tree_identifier *id = nullptr, + octave::tree_parameter_list *pl = nullptr, octave::tree_parameter_list *rl = nullptr, octave::tree_statement_list *cl = nullptr); OCTAVE_DISABLE_COPY_MOVE (octave_user_function) @@ -254,23 +258,8 @@ void attach_trailing_comments (const octave::comment_list& lst); - void stash_fcn_location (int line, int col) - { - m_location_line = line; - m_location_column = col; - } - - int beginning_line () const { return m_location_line; } - int beginning_column () const { return m_location_column; } - - void stash_fcn_end_location (int line, int col) - { - m_end_location_line = line; - m_end_location_column = col; - } - - int ending_line () const { return m_end_location_line; } - int ending_column () const { return m_end_location_column; } + octave::filepos beg_pos () const { return m_fcn_tok.beg_pos(); } + // The end_pos function is defined in the octave_user_code class. void maybe_relocate_end (); @@ -437,6 +426,9 @@ std::string ctor_type_str () const; std::string method_type_str () const; + // Name of this function. + octave::tree_identifier *m_id; + // List of arguments for this function. These are local variables. octave::tree_parameter_list *m_param_list; @@ -444,42 +436,38 @@ // this function. octave::tree_parameter_list *m_ret_list; - // FIXME: Should we also be caching the final token (END or EOF) as - // m_end_tok? + // We don't keep track of an end token separately because functions + // may still be defined without an explicit END. If there is an + // explicit END, the final statement will contain it. + octave::token m_fcn_tok; octave::token m_eq_tok; - // Location where this function was defined. - int m_location_line; - int m_location_column; - int m_end_location_line; - int m_end_location_column; - // True if this function came from a file that is considered to be a // system function. This affects whether we check the time stamp // on the file to see if it has changed. - bool m_system_fcn_file; + bool m_system_fcn_file {false}; // The number of arguments that have names. int m_num_named_args; // TRUE means this is a m_subfunction of a primary function. - bool m_subfunction; + bool m_subfunction {false}; // TRUE means this is an inline function. - bool m_inline_function; + bool m_inline_function {false}; // TRUE means this is an anonymous function. - bool m_anonymous_function; + bool m_anonymous_function {false}; // TRUE means this is a nested function. - bool m_nested_function; + bool m_nested_function {false}; // Enum describing whether this function is the constructor for class object. - class_method_type m_class_constructor; + class_method_type m_class_constructor {none}; // Enum describing whether this function is a method for a class. - class_method_type m_class_method; + class_method_type m_class_method {none}; void maybe_relocate_end_internal (); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/bp-table.cc --- a/libinterp/parse-tree/bp-table.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/bp-table.cc Thu Apr 04 01:00:08 2024 -0400 @@ -665,12 +665,10 @@ // Return the sub/nested/main function of MAIN_FCN that contains // line number LINENO of the source file. -// If END_LINE != 0, *END_LINE is set to last line of the returned function. +// If FOUND_ENDING_LINE != 0, *FOUND_ENDING_LINE is set to last line of the returned function. static octave_user_code * -find_fcn_by_line (octave_user_code *main_fcn, - int lineno, - int *end_line = nullptr) +find_fcn_by_line (octave_user_code *main_fcn, int lineno, int *found_end_line = nullptr) { octave_user_code *retval = nullptr; octave_user_code *next_fcn = nullptr; // 1st function starting after lineno @@ -686,21 +684,26 @@ auto *dbg_subfcn = str_val_p.second.user_function_value (); // Check if lineno is within dbg_subfcn. - // FIXME: we could break when beginning_line() > lineno, + // FIXME: we could break when the beginning line > lineno, // but that makes the code "fragile" // if the order of walking subfcns changes, // for a minor speed improvement in non-critical code. - if (dbg_subfcn->ending_line () < earliest_end - && dbg_subfcn->ending_line () >= lineno - && dbg_subfcn->beginning_line () <= lineno) + + filepos beg_pos = dbg_subfcn->beg_pos (); + filepos end_pos = dbg_subfcn->end_pos (); + + int beginning_line = beg_pos.line (); + int ending_line = end_pos.line (); + + if (ending_line < earliest_end && ending_line >= lineno && beginning_line <= lineno) { - earliest_end = dbg_subfcn->ending_line (); + earliest_end = ending_line; retval = find_fcn_by_line (dbg_subfcn, lineno, &earliest_end); } // Find the first fcn starting after lineno. // This is used if line is not inside any function. - if (dbg_subfcn->beginning_line () >= lineno && ! next_fcn) + if (beginning_line >= lineno && ! next_fcn) next_fcn = dbg_subfcn; } } @@ -709,8 +712,11 @@ // or in the main function, which we check now. if (main_fcn->is_user_function ()) { - int e = dynamic_cast (main_fcn)->ending_line (); - if (e >= lineno && e < earliest_end) + filepos end_pos = dynamic_cast (main_fcn)->end_pos (); + + int ending_line = end_pos.line (); + + if (ending_line >= lineno && ending_line < earliest_end) retval = main_fcn; if (! retval) @@ -722,8 +728,8 @@ retval = main_fcn; } - if (end_line && earliest_end < *end_line) - *end_line = earliest_end; + if (found_end_line && earliest_end < *found_end_line) + *found_end_line = earliest_end; return retval; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/oct-parse.yy --- a/libinterp/parse-tree/oct-parse.yy Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/oct-parse.yy Thu Apr 04 01:00:08 2024 -0400 @@ -210,6 +210,8 @@ %token HERMITIAN TRANSPOSE %token PLUS_PLUS MINUS_MINUS POW EPOW %token NUMBER +// The result of a constant folding operation. +%token CONSTANT %token STRUCT_ELT %token NAME %token END @@ -634,7 +636,7 @@ anon_fcn_handle : '@' param_list anon_fcn_begin expression { - $$ = parser.make_anon_fcn_handle ($2, $4, $1->beg_pos ()); + $$ = parser.make_anon_fcn_handle ($1, $2, $4); if (! $$) { // make_anon_fcn_handle deleted $2 and $4. @@ -1470,8 +1472,7 @@ } else { - octave::tree_statement *end_of_script - = parser.make_end ("endscript", true, $4, $4->beg_pos (), $4->end_pos ()); + octave::tree_statement *end_of_script = parser.make_end ("endscript", true, $4); parser.make_script ($3, end_of_script); } @@ -1543,7 +1544,7 @@ parser.endfunction_found (true); if (parser.end_token_ok ($1, octave::token::function_end)) - $$ = parser.make_end ("endfunction", false, $1, $1->beg_pos (), $1->end_pos ()); + $$ = parser.make_end ("endfunction", false, $1); else { parser.end_token_error ($1, octave::token::function_end); @@ -1580,7 +1581,7 @@ YYABORT; } - $$ = parser.make_end ("endfunction", true, $1, $1->beg_pos (), $1->end_pos ()); + $$ = parser.make_end ("endfunction", true, $1); } ; @@ -2718,9 +2719,6 @@ tree_constant * base_parser::make_constant (token *tok) { - int l = tok->line (); - int c = tok->column (); - int op = tok->token_id (); tree_constant *retval = nullptr; @@ -2728,17 +2726,11 @@ switch (op) { case ':': - { - octave_value tmp (octave_value::magic_colon_t); - retval = new tree_constant (tmp); - } + retval = new tree_constant (octave_value (octave_value::magic_colon_t), *tok); break; case NUMBER: - { - retval = new tree_constant (tok->number (), l, c); - retval->stash_original_text (tok->text_rep ()); - } + retval = new tree_constant (tok->number (), tok->text_rep (), *tok); break; case DQ_STRING: @@ -2757,14 +2749,13 @@ tmp = octave_null_sq_str::instance; } - retval = new tree_constant (tmp, l, c); - if (op == DQ_STRING) txt = undo_string_escapes (txt); - // FIXME: maybe this should also be handled by + // FIXME: maybe the addition of delims should be handled by // tok->text_rep () for character strings? - retval->stash_original_text (delim + txt + delim); + + retval = new tree_constant (tmp, delim + txt + delim, *tok); } break; @@ -2787,10 +2778,7 @@ tree_fcn_handle * base_parser::make_fcn_handle (token *tok) { - int l = tok->line (); - int c = tok->column (); - - tree_fcn_handle *retval = new tree_fcn_handle (tok->text (), l, c); + tree_fcn_handle *retval = new tree_fcn_handle (*tok); return retval; } @@ -2798,9 +2786,7 @@ // Make an anonymous function handle. tree_anon_fcn_handle * - base_parser::make_anon_fcn_handle (tree_parameter_list *param_list, - tree_expression *expr, - const filepos& at_pos) + base_parser::make_anon_fcn_handle (token *at_tok, tree_parameter_list *param_list, tree_expression *expr) { // FIXME: We need to examine EXPR and issue an error if any // sub-expression contains an assignment, compound assignment, @@ -2813,8 +2799,7 @@ delete param_list; delete expr; - bison_error (validator.message (), validator.line (), - validator.column ()); + bison_error (validator.message (), validator.line (), validator.column ()); return nullptr; } @@ -2828,12 +2813,8 @@ fcn_scope.mark_static (); - int at_line = at_pos.line (); - int at_column = at_pos.column (); - tree_anon_fcn_handle *retval - = new tree_anon_fcn_handle (param_list, expr, fcn_scope, - parent_scope, at_line, at_column); + = new tree_anon_fcn_handle (*at_tok, param_list, expr, fcn_scope, parent_scope); std::ostringstream buf; @@ -2848,7 +2829,9 @@ buf << ": *terminal input*"; else if (m_lexer.input_from_eval_string ()) buf << ": *eval string*"; - buf << ": line: " << at_line << " column: " << at_column; + + filepos at_pos = at_tok->beg_pos (); + buf << ": line: " << at_pos.line () << " column: " << at_pos.column (); std::string scope_name = buf.str (); @@ -2883,13 +2866,10 @@ return retval; } - 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, *colon_1_tok, incr, tmp_colon_2_tok, limit, l, c); + = new tree_colon_expression (base, *colon_1_tok, incr, tmp_colon_2_tok, limit); retval = expr; @@ -2922,16 +2902,17 @@ if (msg.empty ()) { - tree_constant *tc_retval - = new tree_constant (tmp, expr->line (), expr->column ()); - std::ostringstream buf; tree_print_code tpc (buf); expr->accept (tpc); - tc_retval->stash_original_text (buf.str ()); + std::string orig_text = buf.str (); + + token tok (CONSTANT, tmp, orig_text, expr->beg_pos (), expr->end_pos ()); + + tree_constant *tc_retval = new tree_constant (tmp, orig_text, tok); delete expr; @@ -3033,10 +3014,7 @@ break; } - int l = op_tok->line (); - int c = op_tok->column (); - - return maybe_compound_binary_expression (op1, op2, l, c, t); + return maybe_compound_binary_expression (op1, *op_tok, op2, t); } void @@ -3044,8 +3022,9 @@ { if (expr->is_binary_expression ()) { - tree_binary_expression *binexp - = dynamic_cast (expr); + tree_binary_expression *binexp = dynamic_cast (expr); + + token op_tok = binexp->operator_token (); tree_expression *lhs = binexp->lhs (); tree_expression *rhs = binexp->rhs (); @@ -3063,13 +3042,9 @@ { binexp->preserve_operands (); - int line = expr->line (); - int column = expr->column (); - delete expr; - expr = new tree_braindead_shortcircuit_binary_expression - (lhs, rhs, line, column, op_type); + expr = new tree_braindead_shortcircuit_binary_expression (lhs, op_tok, rhs, op_type); } } } @@ -3096,10 +3071,7 @@ break; } - int l = op_tok->line (); - int c = op_tok->column (); - - return new tree_boolean_expression (op1, op2, l, c, t); + return new tree_boolean_expression (op1, *op_tok, op2, t); } // Build a prefix expression. @@ -3137,10 +3109,7 @@ break; } - int l = op_tok->line (); - int c = op_tok->column (); - - return new tree_prefix_expression (op1, l, c, t); + return new tree_prefix_expression (*op_tok, op1, t); } // Build a postfix expression. @@ -3173,10 +3142,7 @@ break; } - int l = op_tok->line (); - int c = op_tok->column (); - - return new tree_postfix_expression (op1, l, c, t); + return new tree_postfix_expression (op1, *op_tok, t); } // Build an unwind-protect command. @@ -3188,10 +3154,7 @@ if (end_token_ok (end_tok, token::unwind_protect_end)) { - int l = unwind_tok->line (); - int c = unwind_tok->column (); - - retval = new tree_unwind_protect_command (*unwind_tok, body, *cleanup_tok, cleanup_stmts, *end_tok, l, c); + retval = new tree_unwind_protect_command (*unwind_tok, body, *cleanup_tok, cleanup_stmts, *end_tok); } else { @@ -3213,9 +3176,6 @@ if (end_token_ok (end_tok, token::try_catch_end)) { - 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 @@ -3243,7 +3203,7 @@ 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); + retval = new tree_try_catch_command (*try_tok, body, tmp_catch_tok, id, cleanup_stmts, *end_tok); } else { @@ -3269,10 +3229,7 @@ { m_lexer.m_looping--; - int l = while_tok->line (); - int c = while_tok->column (); - - retval = new tree_while_command (*while_tok, expr, body, *end_tok, l, c); + retval = new tree_while_command (*while_tok, expr, body, *end_tok); } else { @@ -3294,10 +3251,7 @@ m_lexer.m_looping--; - int l = until_tok->line (); - int c = until_tok->column (); - - return new tree_do_until_command (*do_tok, body, *until_tok, expr, l, c); + return new tree_do_until_command (*do_tok, body, *until_tok, expr); } // Build a for command. @@ -3319,16 +3273,13 @@ m_lexer.m_looping--; - int l = for_tok->line (); - int c = for_tok->column (); - if (lhs->size () == 1) { tree_expression *tmp = lhs->remove_front (); m_lexer.mark_as_variable (tmp->name ()); - 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); + 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); delete lhs; } @@ -3345,7 +3296,7 @@ { m_lexer.mark_as_variables (lhs->variable_names ()); - retval = new tree_complex_for_command (*for_tok, lhs, *eq_tok, expr, body, *end_tok, l, c); + retval = new tree_complex_for_command (*for_tok, lhs, *eq_tok, expr, body, *end_tok); } } else @@ -3366,16 +3317,13 @@ tree_command * base_parser::make_break_command (token *break_tok) { - int l = break_tok->line (); - int c = break_tok->column (); - if (! m_lexer.m_looping) { bison_error ("break must appear within a loop"); return nullptr; } else - return new tree_break_command (l, c); + return new tree_break_command (*break_tok); } // Build a continue command. @@ -3383,16 +3331,13 @@ tree_command * base_parser::make_continue_command (token *continue_tok) { - int l = continue_tok->line (); - int c = continue_tok->column (); - if (! m_lexer.m_looping) { bison_error ("continue must appear within a loop"); return nullptr; } else - return new tree_continue_command (l, c); + return new tree_continue_command (*continue_tok); } // Build a return command. @@ -3400,10 +3345,7 @@ tree_command * base_parser::make_return_command (token *return_tok) { - int l = return_tok->line (); - int c = return_tok->column (); - - return new tree_return_command (l, c); + return new tree_return_command (*return_tok); } // Build an spmd command. @@ -3414,12 +3356,7 @@ tree_spmd_command *retval = nullptr; if (end_token_ok (end_tok, token::spmd_end)) - { - int l = spmd_tok->line (); - int c = spmd_tok->column (); - - retval = new tree_spmd_command (body, l, c); - } + retval = new tree_spmd_command (*spmd_tok, body, *end_tok); else { delete body; @@ -3452,18 +3389,7 @@ token if_tok = list->if_token (); - int l = if_tok.line (); - int c = if_tok.column (); - - tree_if_clause *elt = list->front (); - - if (elt) - { - elt->line (l); - elt->column (c); - } - - retval = new tree_if_command (if_tok, list, *end_tok, l, c); + retval = new tree_if_command (if_tok, list, *end_tok); } else { @@ -3488,10 +3414,7 @@ maybe_convert_to_braindead_shortcircuit (expr); } - int l = tok->line (); - int c = tok->column (); - - return new tree_if_clause (*tok, expr, list, l, c); + return new tree_if_clause (*tok, expr, list); } tree_if_command_list * @@ -3508,23 +3431,7 @@ tree_switch_command *retval = nullptr; if (end_token_ok (end_tok, token::switch_end)) - { - int l = switch_tok->line (); - int c = switch_tok->column (); - - if (list && ! list->empty ()) - { - tree_switch_case *elt = list->front (); - - if (elt) - { - elt->line (l); - elt->column (c); - } - } - - retval = new tree_switch_command (*switch_tok, expr, list, *end_tok, l, c); - } + retval = new tree_switch_command (*switch_tok, expr, list, *end_tok); else { delete expr; @@ -3549,19 +3456,13 @@ { maybe_warn_variable_switch_label (expr); - int l = case_tok->line (); - int c = case_tok->column (); - - return new tree_switch_case (*case_tok, expr, list, l, c); + return new tree_switch_case (*case_tok, expr, list); } tree_switch_case * 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 (*default_tok, list, l, c); + return new tree_switch_case (*default_tok, list); } tree_switch_case_list * @@ -3637,9 +3538,6 @@ break; } - int l = eq_tok->line (); - int c = eq_tok->column (); - if (! lhs->is_simple_assign_lhs () && t != octave_value::op_asn_eq) { // Multiple assignments like [x,y] OP= rhs are only valid for @@ -3679,7 +3577,7 @@ m_lexer.mark_as_variable (tmp->name ()); - return new tree_simple_assignment (tmp, rhs, false, l, c, t); + return new tree_simple_assignment (tmp, rhs, false, t); } else { @@ -3701,7 +3599,7 @@ m_lexer.mark_as_variables (names); - return new tree_multi_assignment (lhs, rhs, false, l, c); + return new tree_multi_assignment (lhs, rhs, false); } } @@ -3836,13 +3734,9 @@ else doc_string = leading_doc_comment.text (); - int l = fcn_tok->line (); - int c = fcn_tok->column (); - - octave_user_function *tmp_fcn - = start_function (id, param_list, body, end_fcn_stmt, doc_string); - - tree_function_def *retval = finish_function (fcn_tok, ret_list, eq_tok, tmp_fcn, l, c); + octave_user_function *tmp_fcn = start_function (id, param_list, body, end_fcn_stmt, doc_string); + + tree_function_def *retval = finish_function (fcn_tok, ret_list, eq_tok, tmp_fcn); recover_from_parsing_function (); @@ -3862,8 +3756,6 @@ std::string id_name = id->name (); - delete id; - if (m_lexer.m_parsing_classdef_get_method) id_name.insert (0, "get."); else if (m_lexer.m_parsing_classdef_set_method) @@ -3878,11 +3770,7 @@ body->push_back (end_fcn_stmt); octave_user_function *fcn - = new octave_user_function (m_lexer.m_symtab_context.curr_scope (), - param_list, nullptr, body); - - fcn->stash_fcn_end_location (end_fcn_stmt->line (), - end_fcn_stmt->column ()); + = new octave_user_function (m_lexer.m_symtab_context.curr_scope (), id, param_list, nullptr, body); // If input is coming from a file, issue a warning if the name of // the file does not match the name of the function stated in the @@ -3981,17 +3869,13 @@ } tree_statement * - base_parser::make_end (const std::string& type, bool eof, token *end_tok, - const filepos& beg_pos, const filepos& /*end_pos*/) + base_parser::make_end (const std::string& type, bool eof, token *end_tok) { - int l = beg_pos.line (); - int c = beg_pos.column (); - - return make_statement (new tree_no_op_command (type, eof, *end_tok, l, c)); + return make_statement (new tree_no_op_command (type, eof, *end_tok)); } tree_function_def * - base_parser::finish_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, octave_user_function *fcn, int l, int c) + base_parser::finish_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, octave_user_function *fcn) { tree_function_def *retval = nullptr; @@ -4024,8 +3908,6 @@ if (m_curr_fcn_depth > 0 || m_parsing_subfunctions) { - fcn->stash_fcn_location (l, c); - octave_value ov_fcn (fcn); if (m_endfunction_found && m_function_scopes.size () > 1) @@ -4077,7 +3959,7 @@ m_lexer.m_buffer_function_text = false; } - retval = new tree_function_def (fcn, l, c); + retval = new tree_function_def (fcn); } } @@ -4106,14 +3988,7 @@ tree_arguments_block *retval = nullptr; if (end_token_ok (end_tok, token::arguments_end)) - { - filepos beg_pos = arguments_tok->beg_pos (); - - int l = beg_pos.line (); - int c = beg_pos.column (); - - retval = new tree_arguments_block (attr_list, validation_list, l, c); - } + retval = new tree_arguments_block (*arguments_tok, attr_list, validation_list, *end_tok); else { delete attr_list; @@ -4235,13 +4110,10 @@ { if (end_token_ok (end_tok, token::classdef_end)) { - int l = cdef_tok->line (); - int c = cdef_tok->column (); - if (! body) body = new tree_classdef_body (); - 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); + 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); } else { @@ -4264,9 +4136,6 @@ if (end_token_ok (end_tok, token::properties_end)) { - int l = tok->line (); - int c = tok->column (); - if (plist) { // If the element at the end of the list doesn't have a doc @@ -4292,7 +4161,7 @@ else plist = new tree_classdef_property_list (); - retval = new tree_classdef_properties_block (*tok, a, plist, *end_tok, l, c); + retval = new tree_classdef_properties_block (*tok, a, plist, *end_tok); } else { @@ -4329,13 +4198,10 @@ if (end_token_ok (end_tok, token::methods_end)) { - int l = tok->line (); - int c = tok->column (); - if (! mlist) mlist = new tree_classdef_method_list (); - retval = new tree_classdef_methods_block (*tok, a, mlist, *end_tok, l, c); + retval = new tree_classdef_methods_block (*tok, a, mlist, *end_tok); } else { @@ -4355,13 +4221,10 @@ if (end_token_ok (end_tok, token::events_end)) { - int l = tok->line (); - int c = tok->column (); - if (! elist) elist = new tree_classdef_event_list (); - retval = new tree_classdef_events_block (*tok, a, elist, *end_tok, l, c); + retval = new tree_classdef_events_block (*tok, a, elist, *end_tok); } else { @@ -4393,13 +4256,10 @@ if (end_token_ok (end_tok, token::enumeration_end)) { - int l = tok->line (); - int c = tok->column (); - if (! elist) elist = new tree_classdef_enum_list (); - retval = new tree_classdef_enum_block (*tok, a, elist, *end_tok, l, c); + retval = new tree_classdef_enum_block (*tok, a, elist, *end_tok); } else { @@ -4552,8 +4412,7 @@ } octave_user_function* - base_parser::start_classdef_external_method (tree_identifier *id, - tree_parameter_list *pl) + base_parser::start_classdef_external_method (tree_identifier *id, tree_parameter_list *pl) { octave_user_function* retval = nullptr; @@ -4562,7 +4421,6 @@ if (! m_curr_class_name.empty ()) { - std::string mname = id->name (); // Methods that cannot be declared outside the classdef file: @@ -4577,14 +4435,9 @@ // Create a dummy function that is used until the real method // is loaded. - retval = new octave_user_function (symbol_scope::anonymous (), pl); + retval = new octave_user_function (symbol_scope::anonymous (), id, pl); retval->stash_function_name (mname); - - int l = id->line (); - int c = id->column (); - - retval->stash_fcn_location (l, c); } else bison_error ("invalid external method declaration, an external " @@ -4594,9 +4447,6 @@ else bison_error ("external methods are only allowed in @-folders"); - if (! retval) - delete id; - return retval; } @@ -4611,10 +4461,7 @@ if (eq_tok) fcn->set_eq_tok (*eq_tok); - int l = fcn->beginning_line (); - int c = fcn->beginning_column (); - - return new tree_function_def (fcn, l, c); + return new tree_function_def (fcn); } tree_classdef_method_list * @@ -4720,7 +4567,10 @@ { tree_index_expression *retval = nullptr; - if (args && args->has_magic_tilde ()) + if (! args) + args = new tree_argument_list (); + + if (args->has_magic_tilde ()) { delete expr; delete args; @@ -4729,9 +4579,6 @@ } else { - int l = expr->line (); - int c = expr->column (); - if (! expr->is_postfix_indexed ()) expr->set_postfix_index (type); @@ -4745,7 +4592,7 @@ retval->append (tmp_open_delim, args, tmp_close_delim, type); } else - retval = new tree_index_expression (expr, tmp_open_delim, args, tmp_close_delim, l, c, type); + retval = new tree_index_expression (expr, tmp_open_delim, args, tmp_close_delim, type); } return retval; @@ -4758,9 +4605,6 @@ { tree_index_expression *retval = nullptr; - int l = expr->line (); - int c = expr->column (); - if (! expr->is_postfix_indexed ()) expr->set_postfix_index ('.'); @@ -4771,7 +4615,7 @@ retval->append (*dot_tok, *struct_elt_tok); } else - retval = new tree_index_expression (expr, *dot_tok, *struct_elt_tok, l, c); + retval = new tree_index_expression (expr, *dot_tok, *struct_elt_tok); m_lexer.m_looking_at_indirect_ref = false; @@ -4785,9 +4629,6 @@ { tree_index_expression *retval = nullptr; - int l = expr->line (); - int c = expr->column (); - if (! expr->is_postfix_indexed ()) expr->set_postfix_index ('.'); @@ -4798,7 +4639,7 @@ retval->append (*dot_tok, *open_paren, elt, *close_paren); } else - retval = new tree_index_expression (expr, *dot_tok, *open_paren, elt, *close_paren, l, c); + retval = new tree_index_expression (expr, *dot_tok, *open_paren, elt, *close_paren); m_lexer.m_looking_at_indirect_ref = false; @@ -4812,9 +4653,6 @@ { tree_decl_command *retval = nullptr; - int l = tok->line (); - int c = tok->column (); - if (lst) m_lexer.mark_as_variables (lst->variable_names ()); @@ -4822,7 +4660,7 @@ { case GLOBAL: { - retval = new tree_decl_command ("global", lst, l, c); + retval = new tree_decl_command ("global", *tok, lst); retval->mark_global (); } break; @@ -4830,16 +4668,19 @@ case PERSISTENT: if (m_curr_fcn_depth >= 0) { - retval = new tree_decl_command ("persistent", lst, l, c); + retval = new tree_decl_command ("persistent", *tok, lst); retval->mark_persistent (); } else { + filepos pos = tok->beg_pos (); + int line = pos.line (); + if (m_lexer.m_reading_script_file) warning ("ignoring persistent declaration near line %d of file '%s'", - l, m_lexer.m_fcn_file_full_name.c_str ()); + line, m_lexer.m_fcn_file_full_name.c_str ()); else - warning ("ignoring persistent declaration near line %d", l); + warning ("ignoring persistent declaration near line %d", line); } break; @@ -5032,8 +4873,6 @@ 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 ()) { interpreter& interp = m_lexer.m_interpreter; @@ -5062,17 +4901,17 @@ if (msg.empty ()) { - tree_constant *tc_retval - = new tree_constant (tmp, close_delim->line (), - close_delim->column ()); - std::ostringstream buf; tree_print_code tpc (buf); array_list->accept (tpc); - tc_retval->stash_original_text (buf.str ()); + std::string orig_text = buf.str (); + + token tok (CONSTANT, tmp, orig_text, open_delim->beg_pos (), close_delim->end_pos ()); + + tree_constant *tc_retval = new tree_constant (tmp, orig_text, tok); delete array_list; @@ -5093,10 +4932,15 @@ tree_expression * base_parser::finish_matrix (token *open_delim, tree_matrix *m, token *close_delim) { - return (m - ? finish_array_list (open_delim, m, close_delim) - : new tree_constant (octave_null_matrix::instance, - close_delim->line (), close_delim->column ())); + if (m) + return finish_array_list (open_delim, m, close_delim); + + octave_value tmp {octave_null_matrix::instance}; + std::string orig_text {"{}"}; + + token tok (CONSTANT, tmp, orig_text, open_delim->beg_pos (), close_delim->end_pos ()); + + return new tree_constant (tmp, orig_text, tok); } tree_matrix * @@ -5119,10 +4963,15 @@ tree_expression * base_parser::finish_cell (token *open_delim, tree_cell *c, token *close_delim) { - return (c - ? finish_array_list (open_delim, c, close_delim) - : new tree_constant (octave_value (Cell ()), - close_delim->line (), close_delim->column ())); + if (c) + return finish_array_list (open_delim, c, close_delim); + + octave_value tmp {Cell ()}; + std::string orig_text {"{}"}; + + token tok (CONSTANT, tmp, orig_text, open_delim->beg_pos (), close_delim->end_pos ()); + + return new tree_constant (tmp, orig_text, tok); } tree_cell * @@ -5154,10 +5003,7 @@ std::string meth = superclassref->superclass_method_name (); std::string cls = superclassref->superclass_class_name (); - int l = superclassref->line (); - int c = superclassref->column (); - - return new tree_superclass_ref (meth, cls, l, c); + return new tree_superclass_ref (meth, cls, *superclassref); } tree_metaclass_query * @@ -5165,10 +5011,7 @@ { std::string cls = metaquery->text (); - int l = metaquery->line (); - int c = metaquery->column (); - - return new tree_metaclass_query (cls, l, c); + return new tree_metaclass_query (cls, *metaquery); } tree_statement_list * diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/parse.h --- a/libinterp/parse-tree/parse.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/parse.h Thu Apr 04 01:00:08 2024 -0400 @@ -252,8 +252,7 @@ // Build an anonymous function handle. OCTINTERP_API tree_anon_fcn_handle * - make_anon_fcn_handle (tree_parameter_list *param_list, - tree_expression *expr, const filepos& at_pos); + make_anon_fcn_handle (token *at_tok, tree_parameter_list *param_list, tree_expression *expr); // Build a colon expression. OCTINTERP_API tree_expression * @@ -373,7 +372,7 @@ // Create a no-op statement for end_function. OCTINTERP_API tree_statement * - make_end (const std::string& type, bool eof, token *tok, const filepos& beg_pos, const filepos& end_pos); + make_end (const std::string& type, bool eof, token *tok); // Do most of the work for defining a function. OCTINTERP_API octave_user_function * @@ -381,7 +380,7 @@ // Finish defining a function. OCTINTERP_API tree_function_def * - finish_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, octave_user_function *fcn, int l, int c); + finish_function (token *fcn_tok, tree_parameter_list *ret_list, token *eq_tok, octave_user_function *fcn); OCTINTERP_API tree_statement_list * append_function_body (tree_statement_list *body, tree_statement_list *list); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-arg-list.cc --- a/libinterp/parse-tree/pt-arg-list.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-arg-list.cc Thu Apr 04 01:00:08 2024 -0400 @@ -143,6 +143,8 @@ tree_argument_list *new_list = new tree_argument_list (); new_list->m_simple_assign_lhs = m_simple_assign_lhs; + new_list->m_list_includes_magic_tilde = m_list_includes_magic_tilde; + new_list->m_delims = m_delims; for (const tree_expression *elt : *this) new_list->push_back (elt ? elt->dup (scope) : nullptr); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-arg-list.h --- a/libinterp/parse-tree/pt-arg-list.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-arg-list.h Thu Apr 04 01:00:08 2024 -0400 @@ -36,6 +36,7 @@ #include "str-vec.h" #include "pt-delimiter-list.h" +#include "pt-exp.h" #include "pt-walk.h" #include "token.h" @@ -54,13 +55,9 @@ typedef tree_expression *element_type; - tree_argument_list () - : m_list_includes_magic_tilde (false), m_simple_assign_lhs (false) - { } + tree_argument_list () { } - tree_argument_list (tree_expression *t) - : m_list_includes_magic_tilde (false), m_simple_assign_lhs (false) - { push_back (t); } + tree_argument_list (tree_expression *t) { push_back (t); } OCTAVE_DISABLE_COPY_MOVE (tree_argument_list) @@ -72,6 +69,34 @@ return this; } + filepos beg_pos () const + { + if (m_delims.empty ()) + { + if (empty ()) + return filepos (); + + tree_expression *elt = front (); + return elt->beg_pos (); + } + + return m_delims.beg_pos (); + } + + filepos end_pos () const + { + if (m_delims.empty ()) + { + if (empty ()) + return filepos (); + + tree_expression *elt = back (); + return elt->end_pos (); + } + + return m_delims.end_pos (); + } + bool has_magic_tilde () const { return m_list_includes_magic_tilde; @@ -113,9 +138,9 @@ private: - bool m_list_includes_magic_tilde; + bool m_list_includes_magic_tilde {false}; - bool m_simple_assign_lhs; + bool m_simple_assign_lhs {false}; tree_delimiter_list m_delims; }; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-args-block.h --- a/libinterp/parse-tree/pt-args-block.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-args-block.h Thu Apr 04 01:00:08 2024 -0400 @@ -215,8 +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) + tree_arguments_block (const token& args_tok, tree_args_block_attribute_list *attr_list, tree_args_block_validation_list *validation_list, const token& end_tok) + : m_args_tok (args_tok), m_attr_list (attr_list), m_validation_list (validation_list), m_end_tok (end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_arguments_block) @@ -227,6 +227,9 @@ delete m_validation_list; } + filepos beg_pos () const { return m_args_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_args_block_attribute_list * attribute_list () { return m_attr_list; @@ -244,9 +247,13 @@ private: + token m_args_tok; + tree_args_block_attribute_list *m_attr_list; tree_args_block_validation_list *m_validation_list; + + token m_end_tok; }; OCTAVE_END_NAMESPACE(octave) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-array-list.h --- a/libinterp/parse-tree/pt-array-list.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-array-list.h Thu Apr 04 01:00:08 2024 -0400 @@ -50,8 +50,7 @@ protected: - tree_array_list (tree_argument_list *row = nullptr, int l = -1, int c = -1) - : tree_expression (l, c), std::list () + tree_array_list (tree_argument_list *row = nullptr) { if (row) push_back (row); @@ -63,6 +62,12 @@ ~tree_array_list (); + // The delimiter list for a cell array should never be empty. But + // better safe than sorry, I guess. + + filepos beg_pos () const { return m_delims.empty () ? filepos () : m_delims.beg_pos (); } + filepos end_pos () const { return m_delims.empty () ? filepos () : m_delims.end_pos (); } + bool all_elements_are_constant () const; // FIXME: should we import the functions from the base class and diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-assign.cc --- a/libinterp/parse-tree/pt-assign.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-assign.cc Thu Apr 04 01:00:08 2024 -0400 @@ -40,12 +40,8 @@ // Simple assignment expressions. -tree_simple_assignment::tree_simple_assignment (tree_expression *le, - tree_expression *re, - bool plhs, int l, int c, - octave_value::assign_op t) - : tree_expression (l, c), m_lhs (le), m_rhs (re), m_preserve (plhs), - m_ans_assign (), m_etype (t) +tree_simple_assignment::tree_simple_assignment (tree_expression *le, tree_expression *re, bool plhs, octave_value::assign_op t) + : m_lhs (le), m_rhs (re), m_preserve (plhs), m_ans_assign (), m_etype (t) { } tree_simple_assignment::~tree_simple_assignment () @@ -153,10 +149,8 @@ // Multi-valued assignment expressions. -tree_multi_assignment::tree_multi_assignment (tree_argument_list *lst, - tree_expression *r, - bool plhs, int l, int c) - : tree_expression (l, c), m_lhs (lst), m_rhs (r), m_preserve (plhs) +tree_multi_assignment::tree_multi_assignment (tree_argument_list *lst, tree_expression *r, bool plhs) + : m_lhs (lst), m_rhs (r), m_preserve (plhs) { } tree_multi_assignment::~tree_multi_assignment () diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-assign.h --- a/libinterp/parse-tree/pt-assign.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-assign.h Thu Apr 04 01:00:08 2024 -0400 @@ -36,6 +36,7 @@ #include "comment-list.h" #include "ov.h" +#include "pt-arg-list.h" #include "pt-exp.h" #include "pt-walk.h" #include "token.h" @@ -52,15 +53,7 @@ { public: - tree_simple_assignment (bool plhs = false, int l = -1, int c = -1, - octave_value::assign_op t = octave_value::op_asn_eq) - : tree_expression (l, c), m_lhs (nullptr), m_rhs (nullptr), - m_preserve (plhs), m_ans_assign (), m_etype (t) - { } - - tree_simple_assignment (tree_expression *le, tree_expression *re, - bool plhs = false, int l = -1, int c = -1, - octave_value::assign_op t = octave_value::op_asn_eq); + tree_simple_assignment (tree_expression *le, tree_expression *re, bool plhs = false, octave_value::assign_op t = octave_value::op_asn_eq); OCTAVE_DISABLE_COPY_MOVE (tree_simple_assignment) @@ -68,6 +61,9 @@ comment_list leading_comments () const { return m_lhs->leading_comments (); } + filepos beg_pos () const { return m_lhs->beg_pos (); } + filepos end_pos () const { return m_rhs->end_pos (); } + bool rvalue_ok () const { return true; } bool is_assignment_expression () const { return true; } @@ -123,13 +119,11 @@ { public: - tree_multi_assignment (bool plhs = false, int l = -1, int c = -1) - : tree_expression (l, c), m_lhs (nullptr), m_rhs (nullptr), - m_preserve (plhs) + tree_multi_assignment (bool plhs = false) + : m_lhs (nullptr), m_rhs (nullptr), m_preserve (plhs) { } - tree_multi_assignment (tree_argument_list *lst, tree_expression *r, - bool plhs = false, int l = -1, int c = -1); + tree_multi_assignment (tree_argument_list *lst, tree_expression *r, bool plhs = false); OCTAVE_DISABLE_COPY_MOVE (tree_multi_assignment) @@ -137,6 +131,9 @@ bool is_assignment_expression () const { return true; } + filepos beg_pos () const { return m_lhs->beg_pos (); } + filepos end_pos () const { return m_rhs->end_pos (); } + bool rvalue_ok () const { return true; } std::string oper () const; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-binop.cc --- a/libinterp/parse-tree/pt-binop.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-binop.cc Thu Apr 04 01:00:08 2024 -0400 @@ -58,8 +58,9 @@ { tree_binary_expression *new_be = new tree_binary_expression (m_lhs ? m_lhs->dup (scope) : nullptr, + m_op_tok, m_rhs ? m_rhs->dup (scope) : nullptr, - line (), column (), m_etype); + m_etype); new_be->copy_base (*this); @@ -108,8 +109,9 @@ tree_braindead_shortcircuit_binary_expression *new_be = new tree_braindead_shortcircuit_binary_expression (m_lhs ? m_lhs->dup (scope) : nullptr, + m_op_tok, m_rhs ? m_rhs->dup (scope) : nullptr, - line (), column (), op_type ()); + op_type ()); new_be->copy_base (*this); @@ -117,8 +119,7 @@ } octave_value -tree_braindead_shortcircuit_binary_expression::evaluate (tree_evaluator& tw, - int) +tree_braindead_shortcircuit_binary_expression::evaluate (tree_evaluator& tw, int) { if (m_lhs) { @@ -194,8 +195,9 @@ { tree_boolean_expression *new_be = new tree_boolean_expression (m_lhs ? m_lhs->dup (scope) : nullptr, + m_op_tok, m_rhs ? m_rhs->dup (scope) : nullptr, - line (), column (), m_etype); + m_etype); new_be->copy_base (*this); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-binop.h --- a/libinterp/parse-tree/pt-binop.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-binop.h Thu Apr 04 01:00:08 2024 -0400 @@ -47,19 +47,12 @@ { public: - tree_binary_expression (int l = -1, int c = -1, - octave_value::binary_op t - = octave_value::unknown_binary_op) - : tree_expression (l, c), m_lhs (nullptr), m_rhs (nullptr), m_etype (t), - m_preserve_operands (false) + tree_binary_expression (octave_value::binary_op t = octave_value::unknown_binary_op) + : m_lhs (nullptr), m_rhs (nullptr), m_etype (t), m_preserve_operands (false) { } - tree_binary_expression (tree_expression *a, tree_expression *b, - int l = -1, int c = -1, - octave_value::binary_op t - = octave_value::unknown_binary_op) - : tree_expression (l, c), m_lhs (a), m_rhs (b), m_etype (t), - m_preserve_operands (false) + tree_binary_expression (tree_expression *a, const token& op_tok, tree_expression *b, octave_value::binary_op t = octave_value::unknown_binary_op) + : m_lhs (a), m_op_tok (op_tok), m_rhs (b), m_etype (t), m_preserve_operands (false) { } OCTAVE_DISABLE_COPY_MOVE (tree_binary_expression) @@ -73,10 +66,15 @@ } } + token operator_token () const { return m_op_tok; } + void preserve_operands () { m_preserve_operands = true; } bool is_binary_expression () const { return true; } + filepos beg_pos () const { return m_lhs->beg_pos (); } + filepos end_pos () const { return m_rhs->end_pos (); } + bool rvalue_ok () const { return true; } std::string oper () const; @@ -108,10 +106,14 @@ void matlab_style_short_circuit_warning (const char *op); virtual bool is_braindead () const { return false; } + protected: - // The operands for the expression. + // The operands and operator for the expression. tree_expression *m_lhs; + + token m_op_tok; + tree_expression *m_rhs; private: @@ -128,11 +130,8 @@ { public: - tree_braindead_shortcircuit_binary_expression (tree_expression *a, - tree_expression *b, - int l, int c, - octave_value::binary_op t) - : tree_binary_expression (a, b, l, c, t) + tree_braindead_shortcircuit_binary_expression (tree_expression *a, const token& op_tok, tree_expression *b, octave_value::binary_op t) + : tree_binary_expression (a, op_tok, b, t) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_braindead_shortcircuit_binary_expression) @@ -161,12 +160,11 @@ bool_or }; - tree_boolean_expression (int l = -1, int c = -1, type t = unknown) - : tree_binary_expression (l, c), m_etype (t) { } + tree_boolean_expression (type t = unknown) : m_etype (t) { } - tree_boolean_expression (tree_expression *a, tree_expression *b, - int l = -1, int c = -1, type t = unknown) - : tree_binary_expression (a, b, l, c), m_etype (t) { } + tree_boolean_expression (tree_expression *a, const token& op_tok, tree_expression *b, type t = unknown) + : tree_binary_expression (a, op_tok, b), m_etype (t) + { } OCTAVE_DISABLE_COPY_MOVE (tree_boolean_expression) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-cbinop.cc --- a/libinterp/parse-tree/pt-cbinop.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-cbinop.cc Thu Apr 04 01:00:08 2024 -0400 @@ -140,8 +140,7 @@ // Possibly contract and/or with negation. tree_binary_expression * -maybe_compound_binary_expression (tree_expression *a, tree_expression *b, - int l, int c, octave_value::binary_op t) +maybe_compound_binary_expression (tree_expression *a, const token& op_tok, tree_expression *b, octave_value::binary_op t) { tree_expression *ca = a; tree_expression *cb = b; @@ -164,8 +163,8 @@ tree_binary_expression *ret = (ct == octave_value::unknown_compound_binary_op - ? new tree_binary_expression (a, b, l, c, t) - : new tree_compound_binary_expression (a, b, l, c, t, ca, cb, ct)); + ? new tree_binary_expression (a, op_tok, b, t) + : new tree_compound_binary_expression (a, op_tok, b, t, ca, cb, ct)); return ret; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-cbinop.h --- a/libinterp/parse-tree/pt-cbinop.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-cbinop.h Thu Apr 04 01:00:08 2024 -0400 @@ -45,13 +45,9 @@ { public: - tree_compound_binary_expression (tree_expression *a, tree_expression *b, - int l, int c, - octave_value::binary_op t, - tree_expression *ca, tree_expression *cb, - octave_value::compound_binary_op ct) - : tree_binary_expression (a, b, l, c, t), m_lhs (ca), m_rhs (cb), - m_etype (ct) + tree_compound_binary_expression (tree_expression *a, const token& op_tok, tree_expression *b, octave_value::binary_op t, + tree_expression *ca, tree_expression *cb, octave_value::compound_binary_op ct) + : tree_binary_expression (a, op_tok, b, t), m_lhs (ca), m_rhs (cb), m_etype (ct) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_compound_binary_expression) @@ -89,10 +85,7 @@ // a "virtual constructor" tree_binary_expression * -maybe_compound_binary_expression (tree_expression *a, tree_expression *b, - int l = -1, int c = -1, - octave_value::binary_op t - = octave_value::unknown_binary_op); +maybe_compound_binary_expression (tree_expression *a, const token& op_tok, tree_expression *b, octave_value::binary_op t = octave_value::unknown_binary_op); OCTAVE_END_NAMESPACE(octave) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-cell.cc --- a/libinterp/parse-tree/pt-cell.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-cell.cc Thu Apr 04 01:00:08 2024 -0400 @@ -41,7 +41,7 @@ tree_expression * tree_cell::dup (symbol_scope& scope) const { - tree_cell *new_cell = new tree_cell (nullptr, line (), column ()); + tree_cell *new_cell = new tree_cell (nullptr); new_cell->copy_base (*this, scope); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-cell.h --- a/libinterp/parse-tree/pt-cell.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-cell.h Thu Apr 04 01:00:08 2024 -0400 @@ -47,8 +47,8 @@ { public: - tree_cell (tree_argument_list *row = nullptr, int l = -1, int c = -1) - : tree_array_list (row, l, c) + tree_cell (tree_argument_list *row = nullptr) + : tree_array_list (row) { } OCTAVE_DISABLE_COPY_MOVE (tree_cell) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-classdef.cc --- a/libinterp/parse-tree/pt-classdef.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-classdef.cc Thu Apr 04 01:00:08 2024 -0400 @@ -41,9 +41,7 @@ tree_superclass_ref * tree_superclass_ref::dup (symbol_scope&) const { - tree_superclass_ref *new_scr - = new tree_superclass_ref (m_method_name, m_class_name, - line (), column ()); + tree_superclass_ref *new_scr = new tree_superclass_ref (m_method_name, m_class_name, m_token); new_scr->copy_base (*this); @@ -53,8 +51,7 @@ octave_value_list tree_superclass_ref::evaluate_n (tree_evaluator& tw, int nargout) { - octave_value tmp - = octave_classdef::superclass_ref (m_method_name, m_class_name); + octave_value tmp = octave_classdef::superclass_ref (m_method_name, m_class_name); if (! is_postfix_indexed ()) { @@ -78,8 +75,7 @@ tree_metaclass_query * tree_metaclass_query::dup (symbol_scope&) const { - tree_metaclass_query *new_mcq - = new tree_metaclass_query (m_class_name, line (), column ()); + tree_metaclass_query *new_mcq = new tree_metaclass_query (m_class_name, m_token); new_mcq->copy_base (*this); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-classdef.h --- a/libinterp/parse-tree/pt-classdef.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-classdef.h Thu Apr 04 01:00:08 2024 -0400 @@ -49,15 +49,17 @@ { public: - tree_superclass_ref (const std::string& meth, const std::string& cls, - int l = -1, int c = -1) - : tree_expression (l, c), m_method_name (meth), m_class_name (cls) + tree_superclass_ref (const std::string& meth, const std::string& cls, const token& tok) + : m_method_name (meth), m_class_name (cls), m_token (tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_superclass_ref) ~tree_superclass_ref () = default; + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_token.end_pos (); } + std::string method_name () const { return m_method_name; @@ -90,20 +92,25 @@ // The name of the superclass. This is the text after the "@" // and may be of the form "object.method". std::string m_class_name; + + token m_token; }; class tree_metaclass_query : public tree_expression { public: - tree_metaclass_query (const std::string& cls, int l = -1, int c = -1) - : tree_expression (l, c), m_class_name (cls) + tree_metaclass_query (const std::string& cls, const token& tok) + : m_class_name (cls), m_token (tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_metaclass_query) ~tree_metaclass_query () = default; + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_token.end_pos (); } + std::string class_name () const { return m_class_name; } tree_metaclass_query * dup (symbol_scope& scope) const; @@ -123,6 +130,8 @@ private: std::string m_class_name; + + token m_token; }; class tree_classdef_attribute @@ -149,6 +158,9 @@ delete m_expr; } + filepos beg_pos () const { return m_not_tok ? m_not_tok.beg_pos () : m_id->beg_pos (); } + filepos end_pos () const { return m_expr ? m_expr->end_pos () : m_id->end_pos (); } + tree_identifier * ident () { return m_id; } tree_expression * expression () { return m_expr; } @@ -263,8 +275,8 @@ { public: - 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) + tree_base_classdef_block (const token& block_tok, tree_classdef_attribute_list *a, const token& end_tok) + : m_block_tok (block_tok), m_attr_list (a), m_end_tok (end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_base_classdef_block) @@ -280,7 +292,7 @@ void accept (tree_walker&) { } -private: +protected: token m_block_tok; @@ -295,8 +307,8 @@ { 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) + tree_classdef_block (const token& block_tok, tree_classdef_attribute_list *a, T *elt_list, const token& end_tok) + : tree_base_classdef_block (block_tok, a, end_tok), m_elt_list (elt_list) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_block) @@ -306,6 +318,9 @@ delete m_elt_list; } + filepos beg_pos () const { return m_block_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + T * element_list () { return m_elt_list; } private: @@ -374,8 +389,8 @@ { public: - 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 (block_tok, a, plist, end_tok, l, c) + tree_classdef_properties_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_property_list *plist, const token& end_tok) + : tree_classdef_block (block_tok, a, plist, end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_properties_block) @@ -415,8 +430,8 @@ { public: - 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 (block_tok, a, mlist, end_tok, l, c) + tree_classdef_methods_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_method_list *mlist, const token& end_tok) + : tree_classdef_block (block_tok, a, mlist, end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_methods_block) @@ -482,8 +497,8 @@ { public: - 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 (block_tok, a, elist, end_tok, l, c) + tree_classdef_events_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_event_list *elist, const token& end_tok) + : tree_classdef_block (block_tok, a, elist, end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_events_block) @@ -559,8 +574,8 @@ { public: - 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 (block_tok, a, elist, end_tok, l, c) + tree_classdef_enum_block (const token& block_tok, tree_classdef_attribute_list *a, tree_classdef_enum_list *elist, const token& end_tok) + : tree_classdef_block (block_tok, a, elist, end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_classdef_enum_block) @@ -681,8 +696,8 @@ { public: - 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) + 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 = "") + : 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 (); } @@ -697,6 +712,9 @@ delete m_body; } + filepos beg_pos () const { return m_cdef_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + symbol_scope scope () { return m_scope; } tree_classdef_attribute_list * @@ -772,3 +790,4 @@ OCTAVE_END_NAMESPACE(octave) #endif + diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-cmd.h --- a/libinterp/parse-tree/pt-cmd.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-cmd.h Thu Apr 04 01:00:08 2024 -0400 @@ -35,6 +35,7 @@ #include "pt.h" #include "pt-bp.h" #include "pt-walk.h" +#include "panic.h" #include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -45,12 +46,13 @@ { public: - tree_command (int l = -1, int c = -1) - : tree (l, c) { } + tree_command () = default; OCTAVE_DISABLE_COPY_MOVE (tree_command) virtual ~tree_command () = default; + + virtual void update_end_pos (const filepos&) { panic_impossible (); } }; // No-op. @@ -59,13 +61,25 @@ { public: - 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) { } + tree_no_op_command (const std::string& cmd, bool eof, const token& tok) + : m_eof (eof), m_tok (tok), m_orig_cmd (cmd) + { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_no_op_command) ~tree_no_op_command () = default; + filepos beg_pos () const { return m_tok.beg_pos (); } + filepos end_pos () const { return m_tok.end_pos (); } + + void update_end_pos (const filepos& pos) + { + if (is_end_of_fcn_or_script () || is_end_of_file ()) + m_tok.end_pos (pos); + else + panic_impossible (); + } + comment_list leading_comments () const { return m_tok.leading_comments (); } void attach_trailing_comments (const comment_list& lst) @@ -108,13 +122,24 @@ { public: - tree_function_def (octave_function *f, int l = -1, int c = -1) - : tree_command (l, c), m_fcn (f) { } + tree_function_def (octave_function *f) : m_fcn (f) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_function_def) ~tree_function_def () = default; + filepos beg_pos () const + { + octave_function *f = m_fcn.function_value (); + return f->beg_pos (); + } + + filepos end_pos () const + { + octave_function *f = m_fcn.function_value (); + return f->end_pos (); + } + void accept (tree_walker& tw) { tw.visit_function_def (*this); @@ -126,8 +151,7 @@ octave_value m_fcn; - tree_function_def (const octave_value& v, int l = -1, int c = -1) - : tree_command (l, c), m_fcn (v) { } + tree_function_def (const octave_value& v) : m_fcn (v) { } }; OCTAVE_END_NAMESPACE(octave) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-colon.cc --- a/libinterp/parse-tree/pt-colon.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-colon.cc Thu Apr 04 01:00:08 2024 -0400 @@ -44,8 +44,7 @@ m_colon_1_tok, m_increment ? m_increment->dup (scope) : nullptr, m_colon_2_tok, - m_limit ? m_limit->dup (scope) : nullptr, - line (), column ()); + m_limit ? m_limit->dup (scope) : nullptr); new_ce->copy_base (*this); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-colon.h --- a/libinterp/parse-tree/pt-colon.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-colon.h Thu Apr 04 01:00:08 2024 -0400 @@ -46,12 +46,12 @@ { public: - 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 *base, const token& colon_1_tok, tree_expression *limit) + : m_base (base), m_colon_1_tok (colon_1_tok), m_limit (limit) { } - 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) + tree_colon_expression (tree_expression *base, const token& colon_1_tok, tree_expression *increment, const token& colon_2_tok, tree_expression *limit) + : 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) @@ -65,6 +65,9 @@ delete m_increment; } + filepos beg_pos () const { return m_base->beg_pos (); } + filepos end_pos () const { return m_limit->end_pos (); } + void preserve_base () { m_save_base = true; } bool rvalue_ok () const { return true; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-const.cc --- a/libinterp/parse-tree/pt-const.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-const.cc Thu Apr 04 01:00:08 2024 -0400 @@ -63,8 +63,7 @@ tree_expression * tree_constant::dup (symbol_scope&) const { - tree_constant *new_tc - = new tree_constant (m_value, m_orig_text, line (), column ()); + tree_constant *new_tc = new tree_constant (m_value, m_orig_text, m_token); new_tc->copy_base (*this); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-const.h --- a/libinterp/parse-tree/pt-const.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-const.h Thu Apr 04 01:00:08 2024 -0400 @@ -38,6 +38,7 @@ #include "pt-bp.h" #include "pt-exp.h" #include "pt-walk.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -48,17 +49,12 @@ { public: - tree_constant (int l = -1, int c = -1) - : tree_expression (l, c), m_value (), m_orig_text () + tree_constant (const octave_value& v, const token& tok) + : m_value (v), m_token (tok) { } - tree_constant (const octave_value& v, int l = -1, int c = -1) - : tree_expression (l, c), m_value (v), m_orig_text () - { } - - tree_constant (const octave_value& v, const std::string& ot, - int l = -1, int c = -1) - : tree_expression (l, c), m_value (v), m_orig_text (ot) + tree_constant (const octave_value& v, const std::string& ot, const token& tok) + : m_value (v), m_orig_text (ot), m_token (tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_constant) @@ -69,6 +65,9 @@ bool is_constant () const { return true; } + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_token.end_pos (); } + void maybe_mutate () { m_value.maybe_mutate (); } void print (std::ostream& os, bool pr_as_read_syntax = false, @@ -115,6 +114,8 @@ // The original text form of this constant. std::string m_orig_text; + + token m_token; }; OCTAVE_END_NAMESPACE(octave) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-decl.cc --- a/libinterp/parse-tree/pt-decl.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-decl.cc Thu Apr 04 01:00:08 2024 -0400 @@ -68,9 +68,8 @@ // Declaration commands (global, static). -tree_decl_command::tree_decl_command (const std::string& n, - tree_decl_init_list *t, int l, int c) - : tree_command (l, c), m_cmd_name (n), m_init_list (t) +tree_decl_command::tree_decl_command (const std::string& n, const token& tok, tree_decl_init_list *t) + : m_cmd_name (n), m_token (tok), m_init_list (t) { if (t) { diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-decl.h --- a/libinterp/parse-tree/pt-decl.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-decl.h Thu Apr 04 01:00:08 2024 -0400 @@ -62,6 +62,9 @@ ~tree_decl_elt (); + filepos beg_pos () const { return m_id->beg_pos (); } + filepos end_pos () const { return m_expr ? m_expr->end_pos () : m_id->end_pos (); } + void mark_as_formal_parameter () { m_id->mark_as_formal_parameter (); @@ -124,6 +127,24 @@ } } + filepos beg_pos () const + { + if (empty ()) + return filepos (); + + tree_decl_elt *elt = front (); + return elt->beg_pos (); + } + + filepos end_pos () const + { + if (empty ()) + return filepos (); + + tree_decl_elt *elt = back (); + return elt->end_pos (); + } + void mark_global () { for (tree_decl_elt *elt : *this) @@ -163,16 +184,15 @@ { public: - tree_decl_command (const std::string& n, int l = -1, int c = -1) - : tree_command (l, c), m_cmd_name (n), m_init_list (nullptr) { } - - tree_decl_command (const std::string& n, tree_decl_init_list *t, - int l = -1, int c = -1); + tree_decl_command (const std::string& n, const token& tok, tree_decl_init_list *t); OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_decl_command) ~tree_decl_command (); + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_init_list->end_pos (); } + void mark_global () { if (m_init_list) @@ -199,6 +219,8 @@ // The name of this command -- global, static, etc. std::string m_cmd_name; + token m_token; + // The list of variables or initializers in this declaration command. tree_decl_init_list *m_init_list; }; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-delimiter-list.h --- a/libinterp/parse-tree/pt-delimiter-list.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-delimiter-list.h Thu Apr 04 01:00:08 2024 -0400 @@ -30,6 +30,7 @@ #include +#include "filepos.h" #include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -42,13 +43,33 @@ OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (tree_delimiter_list) - size_t count () const { return m_delimiters.size (); } + size_t count () const { return m_delimiters.size (); } + + bool empty () const { return m_delimiters.empty (); } void push (const token& open_delim, const token& close_delim) { m_delimiters.push (element_type (open_delim, close_delim)); } + filepos beg_pos () const + { + if (m_delimiters.empty ()) + return filepos (); + + const element_type& elt = m_delimiters.top (); + return elt.first.beg_pos (); + } + + filepos end_pos () const + { + if (m_delimiters.empty ()) + return filepos (); + + const element_type& elt = m_delimiters.top (); + return elt.second.end_pos (); + } + private: std::stack m_delimiters; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-eval.cc --- a/libinterp/parse-tree/pt-eval.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-eval.cc Thu Apr 04 01:00:08 2024 -0400 @@ -3462,9 +3462,7 @@ local_vars[name] = val; } - octave_user_function *af - = new octave_user_function (new_scope, param_list_dup, ret_list, - stmt_list); + octave_user_function *af = new octave_user_function (new_scope, nullptr, param_list_dup, ret_list, stmt_list); octave_function *curr_fcn = m_call_stack.current_function (); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-except.h --- a/libinterp/parse-tree/pt-except.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-except.h Thu Apr 04 01:00:08 2024 -0400 @@ -43,14 +43,17 @@ { public: - 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) + 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) + : 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) ~tree_try_catch_command (); + filepos beg_pos () const { return m_try_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_identifier * identifier () { return m_expr_id; } tree_statement_list * body () { return m_try_code; } @@ -86,14 +89,17 @@ { public: - 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) + tree_unwind_protect_command (const token& unwind_tok, tree_statement_list *tc, const token& cleanup_tok, tree_statement_list *cc, const token& end_tok) + : 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) ~tree_unwind_protect_command (); + filepos beg_pos () const { return m_unwind_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_statement_list * body () { return m_unwind_protect_code; } tree_statement_list * cleanup () { return m_cleanup_code; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-exp.h --- a/libinterp/parse-tree/pt-exp.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-exp.h Thu Apr 04 01:00:08 2024 -0400 @@ -49,8 +49,9 @@ { public: - tree_expression (int l = -1, int c = -1) - : tree (l, c), m_postfix_index_type ('\0'), m_for_cmd_expr (false), m_print_flag (false) { } + tree_expression () + : m_postfix_index_type ('\0'), m_for_cmd_expr (false), m_print_flag (false) + { } OCTAVE_DISABLE_COPY_MOVE (tree_expression) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-fcn-handle.cc --- a/libinterp/parse-tree/pt-fcn-handle.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-fcn-handle.cc Thu Apr 04 01:00:08 2024 -0400 @@ -53,7 +53,7 @@ tree_expression * tree_fcn_handle::dup (symbol_scope&) const { - tree_fcn_handle *new_fh = new tree_fcn_handle (m_name, line (), column ()); + tree_fcn_handle *new_fh = new tree_fcn_handle (m_token); new_fh->copy_base (*this); @@ -85,10 +85,10 @@ // FIXME: if new scope is nullptr, then we are in big trouble here... - tree_anon_fcn_handle *new_afh = new - tree_anon_fcn_handle (param_list ? param_list->dup (new_scope) : nullptr, - expr ? expr->dup (new_scope) : nullptr, - new_scope, af_parent_scope, line (), column ()); + tree_anon_fcn_handle *new_afh + = new tree_anon_fcn_handle (m_at_tok, param_list ? param_list->dup (new_scope) : nullptr, + expr ? expr->dup (new_scope) : nullptr, + new_scope, af_parent_scope); new_afh->copy_base (*this); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-fcn-handle.h --- a/libinterp/parse-tree/pt-fcn-handle.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-fcn-handle.h Thu Apr 04 01:00:08 2024 -0400 @@ -49,16 +49,15 @@ { public: - tree_fcn_handle (int l = -1, int c = -1) - : tree_expression (l, c), m_name () { } - - tree_fcn_handle (const std::string& n, int l = -1, int c = -1) - : tree_expression (l, c), m_name (n) { } + tree_fcn_handle (const token& tok) : m_token (tok), m_name (m_token.text ()) { } OCTAVE_DISABLE_COPY_MOVE (tree_fcn_handle) ~tree_fcn_handle () = default; + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_token.end_pos (); } + void print (std::ostream& os, bool pr_as_read_syntax = false, bool pr_orig_txt = true); @@ -85,6 +84,8 @@ private: + token m_token; + // The name of this function handle. std::string m_name; }; @@ -93,24 +94,17 @@ { public: - tree_anon_fcn_handle (int l = -1, int c = -1) - : tree_expression (l, c), m_parameter_list (nullptr), - m_expression (nullptr), m_scope (symbol_scope::anonymous ()), - m_parent_scope (symbol_scope::invalid ()), m_file_name () - { } - - tree_anon_fcn_handle (tree_parameter_list *pl, tree_expression *ex, - const symbol_scope& scope, - const symbol_scope& parent_scope, - int l = -1, int c = -1) - : tree_expression (l, c), m_parameter_list (pl), m_expression (ex), - m_scope (scope), m_parent_scope (parent_scope), m_file_name () + tree_anon_fcn_handle (const token& at_tok, tree_parameter_list *pl, tree_expression *ex, const symbol_scope& scope, const symbol_scope& parent_scope) + : m_at_tok (at_tok), m_parameter_list (pl), m_expression (ex), m_scope (scope), m_parent_scope (parent_scope) { } OCTAVE_DISABLE_COPY_MOVE (tree_anon_fcn_handle) ~tree_anon_fcn_handle (); + filepos beg_pos () const { return m_at_tok.beg_pos (); } + filepos end_pos () const { return m_expression->end_pos (); } + bool rvalue_ok () const { return true; } tree_parameter_list * parameter_list () const @@ -143,6 +137,8 @@ private: + token m_at_tok; + // Inputs parameters. tree_parameter_list *m_parameter_list; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-id.h --- a/libinterp/parse-tree/pt-id.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-id.h Thu Apr 04 01:00:08 2024 -0400 @@ -55,13 +55,10 @@ public: - tree_identifier (const token& tok) - : tree_expression (tok.line (), tok.column ()), m_sym (), m_token (tok) - { } + tree_identifier (const token& tok) : m_token (tok) { } 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_sym (scope ? scope.insert (tok.text ()) : symbol_record (tok.text ())), m_token (tok) { } @@ -75,6 +72,9 @@ comment_list leading_comments () const { return m_token.leading_comments (); } + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_token.end_pos (); } + virtual bool is_black_hole () const { return false; } void mark_as_formal_parameter () { m_sym.mark_formal (); } @@ -123,7 +123,7 @@ protected: tree_identifier (symbol_record& sym, const token& tok) - : tree_expression (tok.line (), tok.column ()), m_sym (sym), m_token (tok) + : m_sym (sym), m_token (tok) { } // The symbol record that this identifier references. diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-idx.cc --- a/libinterp/parse-tree/pt-idx.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-idx.cc Thu Apr 04 01:00:08 2024 -0400 @@ -46,35 +46,31 @@ // Index expressions. -tree_index_expression::tree_index_expression (int l, int c) - : tree_expression (l, c) -{ } - -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) +tree_index_expression::tree_index_expression (tree_expression *e, const token& open_delim, tree_argument_list *lst, const token& close_delim, char t) + : m_expr (e), m_args (0), m_type (), m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { append (open_delim, lst, close_delim, t); } -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) +tree_index_expression::tree_index_expression (tree_expression *e, const token& dot_tok, const token& struct_elt_tok) + : m_expr (e), m_args (0), m_type (), m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { append (dot_tok, struct_elt_tok); } -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) +tree_index_expression::tree_index_expression (tree_expression *e, const token& dot_tok, const token& open_paren, tree_expression *df, const token& close_paren) + : m_expr (e), m_args (0), m_type (), m_arg_nm (), m_dyn_field (), m_word_list_cmd (false) { append (dot_tok, open_paren, df, close_paren); } -// FIXME: Need to handle open_delim and close_delim. - tree_index_expression * -tree_index_expression::append (const token& /*open_delim*/, tree_argument_list *lst, const token& /*close_delim*/, char t) +tree_index_expression::append (const token& open_delim, tree_argument_list *lst, const token& close_delim, char t) { + lst->mark_in_delims (open_delim, close_delim); m_args.push_back (lst); m_type.append (1, t); + m_dot_tok.push_back (token ()); m_arg_nm.push_back (lst ? lst->get_arg_names () : string_vector ()); m_dyn_field.push_back (static_cast (nullptr)); @@ -84,27 +80,26 @@ return this; } -// FIXME: Need to handle dot_tok. - tree_index_expression * -tree_index_expression::append (const token& /*dot_tok*/, const token& struct_elt_tok) +tree_index_expression::append (const token& dot_tok, const token& struct_elt_tok) { m_args.push_back (static_cast (nullptr)); m_type += '.'; + m_dot_tok.push_back (dot_tok); m_arg_nm.push_back (struct_elt_tok.text ()); m_dyn_field.push_back (static_cast (nullptr)); return this; } -// FIXME: Need to handle dot_tok, open_paren, and close_paren. - tree_index_expression * -tree_index_expression::append (const token& /*dot_tok*/, const token& /*open_paren*/, tree_expression *df, const token& /*close_paren*/) +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 (nullptr)); m_type += '.'; + m_dot_tok.push_back (dot_tok); m_arg_nm.push_back (""); + df->mark_in_delims (open_paren, close_paren); m_dyn_field.push_back (df); return this; @@ -138,6 +133,31 @@ return m_expr->name (); } +filepos +tree_index_expression::end_pos () const +{ + int n = m_args.size (); + + if (n == 0) + return m_expr->end_pos (); + + char idx_type = m_type[n-1]; + + if (idx_type == '(' || idx_type == '{') + { + tree_argument_list *args = m_args.back (); + return args->end_pos (); + } + + if (idx_type == '.') + { + tree_expression *dyn_field = m_dyn_field.back (); + return dyn_field->end_pos (); + } + + panic_impossible (); +} + std::string tree_index_expression::get_struct_index (tree_evaluator& tw, @@ -239,8 +259,7 @@ tree_index_expression * tree_index_expression::dup (symbol_scope& scope) const { - tree_index_expression *new_idx_expr - = new tree_index_expression (line (), column ()); + tree_index_expression *new_idx_expr = new tree_index_expression (); new_idx_expr->m_expr = (m_expr ? m_expr->dup (scope) : nullptr); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-idx.h --- a/libinterp/parse-tree/pt-idx.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-idx.h Thu Apr 04 01:00:08 2024 -0400 @@ -52,11 +52,11 @@ { public: - 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 token& open_delim, tree_argument_list *lst, const token& close_delim, char t); - 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, const token& dot_tok, const token& struct_elt_tok); - 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); + tree_index_expression (tree_expression *e, const token& dot_tok, const token& open_paren, tree_expression *df, const token& close_paren); OCTAVE_DISABLE_COPY_MOVE (tree_index_expression) @@ -73,6 +73,9 @@ std::string name () const; + filepos beg_pos () const { return m_expr->beg_pos (); } + filepos end_pos () const; + tree_expression * expression () { return m_expr; } std::list arg_lists () { return m_args; } @@ -119,12 +122,18 @@ // The LHS of this index expression. tree_expression *m_expr {nullptr}; + // FIXME: maybe all the things in the list should be in a struct or + // class so we can more easily ensure that they remain synchronized. + // The indices (only valid if type == paren || type == brace). std::list m_args; // The type of this index expression. std::string m_type; + // Record dot tokens for position and possible comment info. + std::list m_dot_tok; + // The names of the arguments. Used for constant struct element // references. std::list m_arg_nm; @@ -135,7 +144,7 @@ // TRUE if this expression was parsed as a word list command. bool m_word_list_cmd {false}; - tree_index_expression (int l, int c); + tree_index_expression () = default; octave_map make_arg_struct () const; }; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-jump.h --- a/libinterp/parse-tree/pt-jump.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-jump.h Thu Apr 04 01:00:08 2024 -0400 @@ -33,14 +33,33 @@ OCTAVE_BEGIN_NAMESPACE(octave) -// Break. +// Base class for jump commands -class tree_break_command : public tree_command +class tree_jump_command : public tree_command { public: - tree_break_command (int l = -1, int c = -1) - : tree_command (l, c) { } + tree_jump_command (const token& tok) : m_token (tok) { } + + OCTAVE_DISABLE_COPY_MOVE (tree_jump_command) + + ~tree_jump_command () = default; + + filepos beg_pos () const { return m_token.beg_pos (); } + filepos end_pos () const { return m_token.end_pos (); } + +protected: + + token m_token; +}; + +// Break. + +class tree_break_command : public tree_jump_command +{ +public: + + tree_break_command (const token& tok) : tree_jump_command (tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_break_command) @@ -54,12 +73,11 @@ // Continue. -class tree_continue_command : public tree_command +class tree_continue_command : public tree_jump_command { public: - tree_continue_command (int l = -1, int c = -1) - : tree_command (l, c) { } + tree_continue_command (const token& tok) : tree_jump_command (tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_continue_command) @@ -73,12 +91,11 @@ // Return. -class tree_return_command : public tree_command +class tree_return_command : public tree_jump_command { public: - tree_return_command (int l = -1, int c = -1) - : tree_command (l, c) { } + tree_return_command (const token& tok) : tree_jump_command (tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_return_command) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-loop.h --- a/libinterp/parse-tree/pt-loop.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-loop.h Thu Apr 04 01:00:08 2024 -0400 @@ -46,14 +46,17 @@ { public: - 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) + tree_while_command (const token& while_tok, tree_expression *expr, tree_statement_list *body, const token& end_tok) + : m_while_tok (while_tok), m_expr (expr), m_body (body), m_end_tok (end_tok) { } OCTAVE_DISABLE_COPY_MOVE (tree_while_command) ~tree_while_command (); + filepos beg_pos () const { return m_while_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_expression * condition () { return m_expr; } tree_statement_list * body () { return m_body; } @@ -82,14 +85,17 @@ { public: - 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) + tree_do_until_command (const token& do_tok, tree_statement_list *body, const token& until_tok, tree_expression *expr) + : 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 (); + filepos beg_pos () const { return m_do_tok.beg_pos (); } + filepos end_pos () const { return m_expr->end_pos (); } + tree_statement_list * body () { return m_body; } tree_expression * condition () { return m_expr; } @@ -120,8 +126,8 @@ 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), + tree_statement_list *body, const token& end_tok) + : 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) { } @@ -132,6 +138,9 @@ bool in_parallel () { return m_parfor; } + filepos beg_pos () const { return m_for_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_expression * left_hand_side () { return m_lhs; } tree_expression * control_expr () { return m_expr; } @@ -181,15 +190,17 @@ public: 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) + tree_statement_list *body, const token& end_tok) + : 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) ~tree_complex_for_command (); + filepos beg_pos () const { return m_for_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_argument_list * left_hand_side () { return m_lhs; } tree_expression * control_expr () { return m_expr; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-mat.cc --- a/libinterp/parse-tree/pt-mat.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-mat.cc Thu Apr 04 01:00:08 2024 -0400 @@ -141,7 +141,7 @@ tree_expression * tree_matrix::dup (symbol_scope& scope) const { - tree_matrix *new_matrix = new tree_matrix (nullptr, line (), column ()); + tree_matrix *new_matrix = new tree_matrix (nullptr); new_matrix->copy_base (*this, scope); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-mat.h --- a/libinterp/parse-tree/pt-mat.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-mat.h Thu Apr 04 01:00:08 2024 -0400 @@ -49,8 +49,8 @@ { public: - tree_matrix (tree_argument_list *row = nullptr, int l = -1, int c = -1) - : tree_array_list (row, l, c) + tree_matrix (tree_argument_list *row = nullptr) + : tree_array_list (row) { } OCTAVE_DISABLE_COPY_MOVE (tree_matrix) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-misc.h --- a/libinterp/parse-tree/pt-misc.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-misc.h Thu Apr 04 01:00:08 2024 -0400 @@ -81,6 +81,9 @@ return this; } + filepos beg_pos () const { return m_open_delim.beg_pos (); } + filepos end_pos () const { return m_close_delim.end_pos (); } + void mark_as_formal_parameters (); void mark_varargs () { m_marked_for_varargs = 1; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-select.h --- a/libinterp/parse-tree/pt-select.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-select.h Thu Apr 04 01:00:08 2024 -0400 @@ -32,6 +32,7 @@ #include "comment-list.h" #include "pt-cmd.h" +#include "pt-stmt.h" #include "pt-walk.h" #include "token.h" @@ -47,8 +48,8 @@ { public: - 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 (const token& tok, tree_expression *e, tree_statement_list *sl) + : m_tok (tok), m_expr (e), m_list (sl) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_if_clause) @@ -59,6 +60,9 @@ bool is_else_clause () { return ! m_expr; } + filepos beg_pos () const { return m_tok.beg_pos (); } + filepos end_pos () const { return m_list->end_pos (); } + tree_expression * condition () { return m_expr; } tree_statement_list * commands () { return m_list; } @@ -101,6 +105,24 @@ } } + filepos beg_pos () const + { + if (empty ()) + return filepos (); + + tree_if_clause *elt = front (); + return elt->beg_pos (); + } + + filepos end_pos () const + { + if (empty ()) + return filepos (); + + tree_if_clause *elt = back (); + return elt->end_pos (); + } + token if_token () const { if (! empty ()) @@ -122,18 +144,21 @@ { public: - 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 (const token& if_tok, const token& end_tok) + : m_if_tok (if_tok), m_end_tok (end_tok) { } - 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) + tree_if_command (const token& if_tok, tree_if_command_list *lst, const token& end_tok) + : m_if_tok (if_tok), m_list (lst), m_end_tok (end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_if_command) ~tree_if_command (); + filepos beg_pos () const { return m_if_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_if_command_list * cmd_list () { return m_list; } comment_list leading_comments () const { return m_if_tok.leading_comments (); } @@ -159,12 +184,12 @@ { public: - 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 (const token& tok, tree_statement_list *sl) + : m_tok (tok), m_list (sl) { } - 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 (const token& tok, tree_expression *e, tree_statement_list *sl) + : m_tok (tok), m_label (e), m_list (sl) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_switch_case) @@ -173,6 +198,9 @@ bool is_default_case () { return ! m_label; } + filepos beg_pos () const { return m_tok.beg_pos (); } + filepos end_pos () const { return m_list->end_pos (); } + tree_expression * case_label () { return m_label; } tree_statement_list * commands () { return m_list; } @@ -215,6 +243,24 @@ } } + filepos beg_pos () const + { + if (empty ()) + return filepos (); + + tree_switch_case *elt = front (); + return elt->beg_pos (); + } + + filepos end_pos () const + { + if (empty ()) + return filepos (); + + tree_switch_case *elt = back (); + return elt->end_pos (); + } + void accept (tree_walker& tw) { tw.visit_switch_case_list (*this); @@ -225,14 +271,17 @@ { public: - 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 (const token& switch_tok, tree_expression *e, tree_switch_case_list *lst, const token& end_tok) + : m_switch_tok (switch_tok), m_expr (e), m_list (lst), m_end_tok (end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_switch_command) ~tree_switch_command (); + filepos beg_pos () const { return m_switch_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_expression * switch_value () { return m_expr; } tree_switch_case_list * case_list () { return m_list; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-spmd.h --- a/libinterp/parse-tree/pt-spmd.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-spmd.h Thu Apr 04 01:00:08 2024 -0400 @@ -42,14 +42,17 @@ { public: - tree_spmd_command (tree_statement_list *body, int l = -1, int c = -1) - : tree_command (l, c), m_body (body) + tree_spmd_command (const token& spmd_tok, tree_statement_list *body, const token& end_tok) + : m_spmd_tok (spmd_tok), m_body (body), m_end_tok (end_tok) { } OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (tree_spmd_command) ~tree_spmd_command (); + filepos beg_pos () const { return m_spmd_tok.beg_pos (); } + filepos end_pos () const { return m_end_tok.end_pos (); } + tree_statement_list * body () { return m_body; } void accept (tree_walker& tw) @@ -59,8 +62,12 @@ private: + token m_spmd_tok; + // List of commands. tree_statement_list *m_body; + + token m_end_tok; }; OCTAVE_END_NAMESPACE(octave) diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-stmt.cc --- a/libinterp/parse-tree/pt-stmt.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-stmt.cc Thu Apr 04 01:00:08 2024 -0400 @@ -114,6 +114,27 @@ : m_expression->leading_comments ()); } +filepos +tree_statement::beg_pos () const +{ + return (m_command ? m_command->beg_pos () : m_expression->beg_pos ()); +} + +filepos +tree_statement::end_pos () const +{ + return (m_command ? m_command->end_pos () : m_expression->end_pos ()); +} + +void +tree_statement::update_end_pos (const filepos& pos) +{ + if (m_command) + m_command->update_end_pos (pos); + else + panic_impossible (); +} + std::string tree_statement::bp_cond () const { @@ -139,15 +160,6 @@ } void -tree_statement::set_location (int l, int c) -{ - if (m_command) - m_command->set_location (l, c); - else if (m_expression) - m_expression->set_location (l, c); -} - -void tree_statement::echo_code (const std::string& prefix) { tree_print_code tpc (octave_stdout, prefix); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-stmt.h --- a/libinterp/parse-tree/pt-stmt.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-stmt.h Thu Apr 04 01:00:08 2024 -0400 @@ -87,13 +87,16 @@ comment_list leading_comments () const; + filepos beg_pos () const; + filepos end_pos () const; + + virtual void update_end_pos (const filepos& pos); + std::string bp_cond () const; int line () const; int column () const; - void set_location (int l, int c); - void echo_code (const std::string& prefix); tree_command * command () { return m_command; } @@ -159,6 +162,24 @@ } } + filepos beg_pos () const + { + if (empty ()) + return filepos (); + + tree_statement *elt = front (); + return elt->beg_pos (); + } + + filepos end_pos () const + { + if (empty ()) + return filepos (); + + tree_statement *elt = back (); + return elt->end_pos (); + } + void mark_as_function_body () { m_function_body = true; } void mark_as_anon_function_body () { m_anon_function_body = true; } diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-unop.cc --- a/libinterp/parse-tree/pt-unop.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-unop.cc Thu Apr 04 01:00:08 2024 -0400 @@ -48,8 +48,7 @@ tree_prefix_expression::dup (symbol_scope& scope) const { tree_prefix_expression *new_pe - = new tree_prefix_expression (m_op ? m_op->dup (scope) : nullptr, - line (), column (), m_etype); + = new tree_prefix_expression (m_op_tok, m_op ? m_op->dup (scope) : nullptr, m_etype); new_pe->copy_base (*this); @@ -110,8 +109,7 @@ tree_postfix_expression::dup (symbol_scope& scope) const { tree_postfix_expression *new_pe - = new tree_postfix_expression (m_op ? m_op->dup (scope) : nullptr, - line (), column (), m_etype); + = new tree_postfix_expression (m_op ? m_op->dup (scope) : nullptr, m_op_tok, m_etype); new_pe->copy_base (*this); diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt-unop.h --- a/libinterp/parse-tree/pt-unop.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt-unop.h Thu Apr 04 01:00:08 2024 -0400 @@ -36,6 +36,7 @@ #include "ov.h" #include "pt-exp.h" #include "pt-walk.h" +#include "token.h" OCTAVE_BEGIN_NAMESPACE(octave) @@ -47,15 +48,12 @@ { protected: - tree_unary_expression (int l = -1, int c = -1, - octave_value::unary_op t - = octave_value::unknown_unary_op) - : tree_expression (l, c), m_op (nullptr), m_etype (t) { } + tree_unary_expression (octave_value::unary_op t = octave_value::unknown_unary_op) + : m_op (nullptr), m_etype (t) { } - tree_unary_expression (tree_expression *e, int l = -1, int c = -1, - octave_value::unary_op t - = octave_value::unknown_unary_op) - : tree_expression (l, c), m_op (e), m_etype (t) { } + tree_unary_expression (const token& op_tok, tree_expression *e, octave_value::unary_op t = octave_value::unknown_unary_op) + : m_op_tok (op_tok), m_op (e), m_etype (t) + { } public: @@ -73,6 +71,9 @@ protected: + // The operator token. + token m_op_tok; + // The operand for the expression. tree_expression *m_op; @@ -86,18 +87,17 @@ { public: - tree_prefix_expression (int l = -1, int c = -1) - : tree_unary_expression (l, c, octave_value::unknown_unary_op) { } - - tree_prefix_expression (tree_expression *e, int l = -1, int c = -1, - octave_value::unary_op t - = octave_value::unknown_unary_op) - : tree_unary_expression (e, l, c, t) { } + tree_prefix_expression (const token& op_tok, tree_expression *e, octave_value::unary_op t = octave_value::unknown_unary_op) + : tree_unary_expression (op_tok, e, t) + { } OCTAVE_DISABLE_COPY_MOVE (tree_prefix_expression) ~tree_prefix_expression () = default; + filepos beg_pos () const { return m_op_tok.beg_pos (); } + filepos end_pos () const { return m_op->end_pos (); } + bool rvalue_ok () const { return true; } tree_expression * dup (symbol_scope& scope) const; @@ -123,18 +123,17 @@ { public: - tree_postfix_expression (int l = -1, int c = -1) - : tree_unary_expression (l, c, octave_value::unknown_unary_op) { } - - tree_postfix_expression (tree_expression *e, int l = -1, int c = -1, - octave_value::unary_op t - = octave_value::unknown_unary_op) - : tree_unary_expression (e, l, c, t) { } + tree_postfix_expression (tree_expression *e, const token& op_tok, octave_value::unary_op t = octave_value::unknown_unary_op) + : tree_unary_expression (op_tok, e, t) + { } OCTAVE_DISABLE_COPY_MOVE (tree_postfix_expression) ~tree_postfix_expression () = default; + filepos beg_pos () const { return m_op->beg_pos (); } + filepos end_pos () const { return m_op_tok.end_pos (); } + bool rvalue_ok () const { return true; } tree_expression * dup (symbol_scope& scope) const; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt.cc --- a/libinterp/parse-tree/pt.cc Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt.cc Thu Apr 04 01:00:08 2024 -0400 @@ -31,6 +31,7 @@ #include #include "comment-list.h" +#include "filepos.h" #include "interpreter.h" #include "ov-fcn.h" #include "pt.h" @@ -40,6 +41,18 @@ OCTAVE_BEGIN_NAMESPACE(octave) +int +tree::line () const +{ + return beg_pos().line (); +} + +int +tree::column () const +{ + return beg_pos().column (); +} + comment_list tree::leading_comments () const { diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/pt.h --- a/libinterp/parse-tree/pt.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/pt.h Thu Apr 04 01:00:08 2024 -0400 @@ -37,6 +37,7 @@ OCTAVE_BEGIN_NAMESPACE(octave) class comment_list; +class filepos; class tree_evaluator; class tree_walker; @@ -46,27 +47,17 @@ { public: - tree (int l = -1, int c = -1) - : m_line_num (l), m_column_num (c), m_bp_cond (nullptr) - { } + tree () : m_bp_cond (nullptr) { } OCTAVE_DISABLE_COPY_MOVE (tree) virtual ~tree () = default; - virtual int line () const { return m_line_num; } - - virtual int column () const { return m_column_num; } - - void line (int l) { m_line_num = l; } + virtual int line () const; + virtual int column () const; - void column (int c) { m_column_num = c; } - - void set_location (int l, int c) - { - m_line_num = l; - m_column_num = c; - } + virtual filepos beg_pos () const = 0; + virtual filepos end_pos () const = 0; // FIXME: maybe make this a pure virtual function? virtual comment_list leading_comments () const; @@ -111,11 +102,6 @@ private: - // The input line and column where we found the text that was - // eventually converted to this tree node. - int m_line_num; - int m_column_num; - // NULL if no breakpoint, or a breakpoint condition if there is one. std::string *m_bp_cond; }; diff -r 0b4118c91dc9 -r ac3633dd67d1 libinterp/parse-tree/token.h --- a/libinterp/parse-tree/token.h Wed Apr 03 12:30:26 2024 -0400 +++ b/libinterp/parse-tree/token.h Thu Apr 04 01:00:08 2024 -0400 @@ -115,6 +115,8 @@ void mark_trailing_space () { m_tspc = true; } bool space_follows_token () const { return m_tspc; } + operator bool () const { return m_type_tag != invalid_token; } + int token_id () const { return m_tok_id; } bool token_is (int id) const { return m_tok_id == id; }