Mercurial > octave
changeset 33157:899647fde914 bytecode-interpreter
maint: merge default to bytecode-interpreter
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 06 Mar 2024 13:02:42 -0500 |
parents | 4035a1f71e07 (current diff) c23152b00d5f (diff) |
children | 5108f56fc8fc |
files | |
diffstat | 4 files changed, 136 insertions(+), 147 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-magic-int.cc Wed Mar 06 11:34:10 2024 -0500 +++ b/libinterp/octave-value/ov-magic-int.cc Wed Mar 06 13:02:42 2024 -0500 @@ -216,7 +216,7 @@ } template <typename T> -OCTAVE_NORETURN bool +bool octave_base_magic_int<T>::load_ascii (std::istream&) { error ("octave_base_magic_int<T>::load_ascii: internal error"); @@ -232,7 +232,7 @@ } template <typename T> -OCTAVE_NORETURN bool +bool octave_base_magic_int<T>::load_binary (std::istream&, bool, octave::mach_info::float_format) {
--- a/libinterp/parse-tree/lex.h Wed Mar 06 11:34:10 2024 -0500 +++ b/libinterp/parse-tree/lex.h Wed Mar 06 13:02:42 2024 -0500 @@ -669,9 +669,9 @@ int handle_superclass_identifier (); - token * make_meta_identifier_token (); + token * make_meta_identifier_token (const std::string& cls); - token * make_fq_identifier_token (); + token * make_fq_identifier_token (const std::string& ident); int handle_identifier (); @@ -689,6 +689,10 @@ void warn_deprecated_syntax (const std::string& msg); + int syntax_error (const std::string& msg); + int syntax_error (const std::string& msg, const filepos& pos); + int syntax_error (const std::string& msg, const filepos& beg_pos, const filepos& end_pos); + void push_token (token *); token * current_token (); @@ -742,11 +746,9 @@ int finish_command_arg (); - int handle_token (int tok_id, token *tok = nullptr); + int handle_token (int tok_id); int handle_token (token *tok); - int count_token (int tok_id); - int count_token_internal (int tok_id); int show_token (int tok_id);
--- a/libinterp/parse-tree/lex.ll Wed Mar 06 11:34:10 2024 -0500 +++ b/libinterp/parse-tree/lex.ll Wed Mar 06 13:02:42 2024 -0500 @@ -688,7 +688,7 @@ curr_lexer->push_start_state (MATRIX_START); - return curr_lexer->count_token ('['); + return curr_lexer->handle_token ('['); } } @@ -1011,9 +1011,7 @@ { // Use location of octal digits for error token. std::string msg {"invalid octal escape sequence in character string"}; - octave::token *tok = new octave::token (LEXICAL_ERROR, msg, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); - - return curr_lexer->handle_token (tok); + return curr_lexer->syntax_error (msg); } else curr_lexer->m_string_text += static_cast<unsigned char> (result); @@ -1115,11 +1113,7 @@ // Use current file position for error token. std::string msg {"unterminated character string constant"}; - octave::token *tok = new octave::token (LEXICAL_ERROR, msg, curr_lexer->m_filepos, curr_lexer->m_filepos); - - curr_lexer->m_filepos.next_line (); - - return curr_lexer->handle_token (tok); + return curr_lexer->syntax_error (msg, curr_lexer->m_filepos); } %{ @@ -1167,11 +1161,7 @@ // Use current file position for error token. std::string msg {"unterminated character string constant"}; - octave::token *tok = new octave::token (LEXICAL_ERROR, msg, curr_lexer->m_filepos, curr_lexer->m_filepos); - - curr_lexer->m_filepos.next_line (); - - return curr_lexer->handle_token (tok); + return curr_lexer->syntax_error (msg, curr_lexer->m_filepos); } %{ @@ -1185,7 +1175,14 @@ curr_lexer->update_token_positions (yyleng); - octave::token *tok = curr_lexer->make_fq_identifier_token (); + std::string ident = yytext; + + ident.erase (std::remove_if (ident.begin (), ident.end (), is_space_or_tab), ident.end ()); + + if (curr_lexer->fq_identifier_contains_keyword (ident)) + return curr_lexer->syntax_error ("function, method, class, and package names may not be keywords"); + + octave::token *tok = curr_lexer->make_fq_identifier_token (ident); return curr_lexer->handle_token (tok); } @@ -1341,7 +1338,17 @@ { curr_lexer->update_token_positions (yyleng); - octave::token *tok = curr_lexer->make_meta_identifier_token (); + std::string txt = yytext; + + txt.erase (std::remove_if (txt.begin (), txt.end (), is_space_or_tab), txt.end ()); + + // Eliminate leading '?' + std::string cls = txt.substr (1); + + if (curr_lexer->fq_identifier_contains_keyword (cls)) + return curr_lexer->syntax_error ("class and package names may not be keywords"); + + octave::token *tok = curr_lexer->make_meta_identifier_token (cls); return curr_lexer->handle_token (tok); } @@ -1382,7 +1389,7 @@ curr_lexer->m_looking_at_function_handle++; curr_lexer->m_looking_for_object_index = false; - return curr_lexer->count_token ('@'); + return curr_lexer->handle_token ('@'); } else { @@ -1395,14 +1402,12 @@ if (octave::iskeyword (ident)) { std::string msg {"function handles may not refer to keywords"}; - tok = new octave::token (LEXICAL_ERROR, msg, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); + return curr_lexer->syntax_error (msg); } - else - { - curr_lexer->m_looking_for_object_index = true; - - tok = new octave::token (FCN_HANDLE, ident, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); - } + + curr_lexer->m_looking_for_object_index = true; + + tok = new octave::token (FCN_HANDLE, ident, curr_lexer->m_tok_beg, curr_lexer->m_tok_end); return curr_lexer->handle_token (tok); } @@ -1435,7 +1440,7 @@ curr_lexer->m_at_beginning_of_statement = true; - return curr_lexer->count_token ('\n'); + return curr_lexer->handle_token ('\n'); } else if (curr_lexer->m_nesting_level.is_bracket_or_brace ()) { @@ -1444,9 +1449,7 @@ // Use current file position for error token. std::string msg {"unexpected internal lexer error"}; - octave::token *tok = new octave::token (LEXICAL_ERROR, msg, curr_lexer->m_filepos, curr_lexer->m_filepos); - - return curr_lexer->handle_token (tok); + return curr_lexer->syntax_error (msg, curr_lexer->m_filepos); } } @@ -1502,7 +1505,7 @@ else { curr_lexer->m_filepos.increment_column (); - return curr_lexer->count_token (HERMITIAN); + return curr_lexer->handle_token (HERMITIAN); } } } @@ -1518,7 +1521,7 @@ else { curr_lexer->m_filepos.increment_column (); - return curr_lexer->count_token (HERMITIAN); + return curr_lexer->handle_token (HERMITIAN); } } } @@ -1708,7 +1711,7 @@ curr_lexer->m_nesting_level.anon_fcn_body (); } - return curr_lexer->count_token (')'); + return curr_lexer->handle_token (')'); } "." { @@ -1793,7 +1796,7 @@ curr_lexer->push_start_state (MATRIX_START); - return curr_lexer->count_token ('{'); + return curr_lexer->handle_token ('{'); } } @@ -1844,13 +1847,9 @@ << octave::undo_string_escape (static_cast<char> (c)) << "' (ASCII " << c << ")"; - // Use current file position for error token. - std::string msg {"unexpected internal lexer error"}; - octave::token *tok = new octave::token (LEXICAL_ERROR, buf.str (), msg, curr_lexer->m_filepos, curr_lexer->m_filepos); - - curr_lexer->m_filepos.increment_column (); - - return curr_lexer->handle_token (tok); + curr_lexer->update_token_positions (yyleng); + + return curr_lexer->syntax_error (buf.str ()); } } @@ -2471,14 +2470,13 @@ if (m_block_comment_nesting_level != 0) { + std::string msg {"block comment unterminated at end of input"}; if ((m_reading_fcn_file || m_reading_script_file || m_reading_classdef_file) && ! m_fcn_file_name.empty ()) - error ("block comment unterminated at end of input\n" - "near line %d of file '%s.m'", - m_filepos.line () - 1, m_fcn_file_name.c_str ()); - else - error ("block comment unterminated at end of input"); + msg += " near line " + std::to_string (m_filepos.line () - 1) + " of file '" + m_fcn_file_name + ".m'"; + + syntax_error (msg); } token *tok = new token (END_OF_INPUT, m_tok_beg, m_tok_end); @@ -3010,9 +3008,7 @@ if (bytes < 0) { std::string msg {"too many digits for binary constant"}; - token *tok = new token (LEXICAL_ERROR, msg, m_tok_beg, m_tok_end); - - return handle_token (tok); + return syntax_error (msg); } // FIXME: is there a better way? Can uintmax_t be anything other @@ -3214,9 +3210,7 @@ if (bytes < 0) { std::string msg {"too many digits for hexadecimal constant"}; - token *tok = new token (LEXICAL_ERROR, msg, m_tok_beg, m_tok_end); - - return handle_token (tok); + return syntax_error (msg); } // Assert here because if yytext doesn't contain a valid number, we @@ -3341,7 +3335,7 @@ pop_start_state (); - return count_token (bracket_type); + return handle_token (bracket_type); } bool @@ -3375,9 +3369,7 @@ if (iskeyword (meth) || fq_identifier_contains_keyword (cls)) { std::string msg {"method, class, and package names may not be keywords"}; - token *tok = new token (LEXICAL_ERROR, msg, m_tok_beg, m_tok_end); - - return handle_token (tok); + return syntax_error (msg); } token *tok = new token (SUPERCLASSREF, meth, cls, m_tok_beg, m_tok_end); @@ -3388,64 +3380,31 @@ } token * - base_lexer::make_meta_identifier_token () + base_lexer::make_meta_identifier_token (const std::string& cls) { - std::string txt = flex_yytext (); - - txt.erase (std::remove_if (txt.begin (), txt.end (), is_space_or_tab), - txt.end ()); - - // Eliminate leading '?' - std::string cls = txt.substr (1); - // Token positions should have already been updated before this // function is called. - token *tok; - - if (fq_identifier_contains_keyword (cls)) - { - std::string msg {"class and package names may not be keywords"}; - tok = new token (LEXICAL_ERROR, msg, m_tok_beg, m_tok_end); - } - else - { - m_looking_for_object_index = true; - - tok = new token (METAQUERY, cls, m_tok_beg, m_tok_end); - - m_filepos.increment_column (flex_yyleng ()); - } + m_looking_for_object_index = true; + + token *tok = new token (METAQUERY, cls, m_tok_beg, m_tok_end); + + m_filepos.increment_column (flex_yyleng ()); return tok; } token * - base_lexer::make_fq_identifier_token () + base_lexer::make_fq_identifier_token (const std::string& ident) { - std::string txt = flex_yytext (); - - txt.erase (std::remove_if (txt.begin (), txt.end (), is_space_or_tab), - txt.end ()); - // Token positions should have already been updated before this // function is called. - token *tok; - - if (fq_identifier_contains_keyword (txt)) - { - std::string msg {"function, method, class, and package names may not be keywords"}; - tok = new token (LEXICAL_ERROR, msg, m_tok_beg, m_tok_end); - } - else - { - m_looking_for_object_index = true; - - tok = new token (FQ_IDENT, txt, m_tok_beg, m_tok_end); - - m_filepos.increment_column (flex_yyleng ()); - } + m_looking_for_object_index = true; + + token *tok = new token (FQ_IDENT, ident, m_tok_beg, m_tok_end); + + m_filepos.increment_column (flex_yyleng ()); return tok; } @@ -3598,6 +3557,28 @@ m_filepos.line (), m_fcn_file_full_name.c_str ()); } + int + base_lexer::syntax_error (const std::string& msg) + { + return syntax_error (msg, m_tok_beg, m_tok_end); + } + + int + base_lexer::syntax_error (const std::string& msg, const filepos& pos) + { + return syntax_error (msg, pos, pos); + } + + int + base_lexer::syntax_error (const std::string& msg, const filepos& beg_pos, const filepos& end_pos) + { + token *tok = new token (LEXICAL_ERROR, msg, beg_pos, end_pos); + + push_token (tok); + + return count_token_internal (tok->token_id ()); + } + void base_lexer::push_token (token *tok) { @@ -3750,7 +3731,7 @@ void base_lexer::fatal_error (const char *msg) { - error ("fatal lexer error: %s", msg); + ::error ("fatal lexer error: %s", msg); } bool @@ -3950,12 +3931,9 @@ } int - base_lexer::handle_token (int tok_id, token *tok) + base_lexer::handle_token (int tok_id) { - if (! tok) - tok = new token (tok_id, m_tok_beg, m_tok_end); - - return handle_token (tok); + return handle_token (new token (tok_id, m_tok_beg, m_tok_end)); } int @@ -3967,12 +3945,6 @@ } int - base_lexer::count_token (int tok_id) - { - return handle_token (new token (tok_id, m_tok_beg, m_tok_end)); - } - - int base_lexer::count_token_internal (int tok_id) { if (tok_id != '\n')
--- a/oct-conf-post-public.in.h Wed Mar 06 11:34:10 2024 -0500 +++ b/oct-conf-post-public.in.h Wed Mar 06 13:02:42 2024 -0500 @@ -32,32 +32,54 @@ #define OCTAVE_BEGIN_NAMESPACE(name) namespace name { #define OCTAVE_END_NAMESPACE(name) } -/* The C++ standard is evolving to allow attribute hints in a - compiler-independent manner. In C++ 2011 support for noreturn was - added. In C++ 2014 support for deprecated was added. The Octave - code base has been future-proofed by using macros of the form - OCTAVE_ATTRIBUTE_NAME in place of vendor specific attribute - mechanisms. As compilers evolve, the underlying implementation can - be changed with the macro definitions below. FIXME: Update macros - to use C++ standard attribute syntax when Octave moves to C++ 2014 - standard. */ +/* We require C++17 now so it should be possible to use + [[deprecated(message)]], [[noreturn]], and [[unused]] unconditionally + but for now we'll keep the macros in case there is an issue. Even if + we decide to use the C++ standard attributes directly in the Octave + sources without the macros, OCTAVE_DEPRECATED will still be useful to + provide consistent formatting of the version number. */ #if defined (__GNUC__) - /* The following attributes are used with gcc and clang compilers. */ -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -# define OCTAVE_DEPRECATED(ver, msg) __attribute__ ((__deprecated__ ("[" #ver "]: " msg))) -# else -# define OCTAVE_DEPRECATED(ver, msg) __attribute__ ((__deprecated__)) + +# if !defined (OCTAVE_DEPRECATED) +# if defined (__cplusplus) +# define OCTAVE_DEPRECATED(ver, msg) [[deprecated ("[" #ver "]: " msg)]] +# else +# define OCTAVE_DEPRECATED(ver, msg) __attribute__ ((__deprecated__ ("[" #ver "]: " msg))) +# endif # endif # define HAVE_OCTAVE_DEPRECATED_ATTR 1 -# define OCTAVE_NORETURN __attribute__ ((__noreturn__)) -# define HAVE_OCTAVE_NORETURN_ATTR 1 +# if !defined (OCTAVE_FALLTHROUGH) +# if defined (__cplusplus) +# define OCTAVE_FALLTHROUGH [[fallthrough]] +# else +# define OCTAVE_FALLTHROUGH __attribute__ ((__fallthrough__)) +# endif +# define HAVE_OCTAVE_FALLTHROUGH_ATTR 1 +# endif -# define OCTAVE_UNUSED __attribute__ ((__unused__)) -# define HAVE_OCTAVE_UNUSED_ATTR 1 +# if !defined (OCTAVE_NORETURN) +# if defined (__cplusplus) +# define OCTAVE_NORETURN [[noreturn]] +# else +# define OCTAVE_NORETURN __attribute__ ((__noreturn__)) +# endif +# define HAVE_OCTAVE_NORETURN_ATTR 1 +# endif + +# if !defined (OCTAVE_UNUSED) +# if defined (__cplusplus) +# define OCTAVE_UNUSED [[maybe_unused]] +# else +# define OCTAVE_UNUSED __attribute__ ((__unused__)) +# endif +# define HAVE_OCTAVE_UNUSED_ATTR 1 +# endif + #else # define OCTAVE_DEPRECATED(ver, msg) +# define OCTAVE_FALLTHROUGH ((void) 0) # define OCTAVE_NORETURN # define OCTAVE_UNUSED @@ -67,7 +89,10 @@ #endif /* Branch hint macros for use in if condititions. - Returns logical value of x. */ + Returns logical value of x. + + FIXME: With C++20, can we use [[likely]] and [[unlikely]]? If so, + what is the purpose of the argument X in the macros below? */ #if defined (__GNUC__) # define OCTAVE_LIKELY(x) __builtin_expect (!!(x), 1) # define OCTAVE_UNLIKELY(x) __builtin_expect (!!(x), 0) @@ -104,16 +129,6 @@ /* # undef HAVE_OCTAVE_FORMAT_PRINTF_ATTR */ #endif -#if ! defined (OCTAVE_FALLTHROUGH) -# if defined (__cplusplus) && __cplusplus > 201402L -# define OCTAVE_FALLTHROUGH [[fallthrough]] -# elif defined (__GNUC__) && __GNUC__ < 7 -# define OCTAVE_FALLTHROUGH ((void) 0) -# else -# define OCTAVE_FALLTHROUGH __attribute__ ((__fallthrough__)) -# endif -#endif - #if defined (__cplusplus) template <typename T> static inline void