From e3cf39070364a5642461d9fd2763f1fe10407d2d Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Sat, 29 Apr 2023 12:11:27 -0700 Subject: [PATCH] Support writing `operator()` and `operator[]`, fixes #315 comment thread issue --- regression-tests/test-results/version | 4 ++-- source/common.h | 4 ++-- source/lex.h | 23 ++++++++++++++++++++++- source/parse.h | 14 +++++++------- source/reflect.h | 8 ++++---- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/regression-tests/test-results/version b/regression-tests/test-results/version index 3426fb6548..fc59e20edf 100644 --- a/regression-tests/test-results/version +++ b/regression-tests/test-results/version @@ -1,6 +1,6 @@ -cppfront compiler - v0.2.1, build 8428:0755 -Copyright(c) Herb Sutter, all rights reserved +cppfront compiler v0.2.1 Build 8429:1203 +Copyright(c) Herb Sutter All rights reserved SPDX-License-Identifier: CC-BY-NC-ND-4.0 No commercial use diff --git a/source/common.h b/source/common.h index 0277eda3c9..0b7442534d 100644 --- a/source/common.h +++ b/source/common.h @@ -762,8 +762,8 @@ class cmdline_processor }; help_requested = true; - print("\ncppfront compiler - v0.2.1, build " + stamp()); - print("\nCopyright(c) Herb Sutter, all rights reserved\n"); + print("\ncppfront compiler v0.2.1 Build " + stamp()); + print("\nCopyright(c) Herb Sutter All rights reserved\n"); print("\nSPDX-License-Identifier: CC-BY-NC-ND-4.0"); print("\n No commercial use"); print("\n No forks/derivatives\n"); diff --git a/source/lex.h b/source/lex.h index e3bd5a98a7..465c69703e 100644 --- a/source/lex.h +++ b/source/lex.h @@ -709,7 +709,7 @@ auto lex_line( }); } - // Else if token after "operator" is an operator symbol + // Else if token after "operator" is a single-token operator symbol else if (is_operator(tokens[i-1].type())) { // Merge just "operator" + the symbol into an identifier, @@ -730,6 +730,27 @@ auto lex_line( tokens.push_back(last_token); } + // Else if token after "operator" is a two-token operator symbol + else if ( + (tokens[i-1].type() == lexeme::LeftParen && tokens[i].type() == lexeme::RightParen) + || (tokens[i-1].type() == lexeme::LeftBracket && tokens[i].type() == lexeme::RightBracket) + ) + { + // Merge just "operator" + the symbols into an identifier, + generated_text.push_back( "operator" + tokens[i-1].to_string(true) + tokens[i].to_string(true) ); + + tokens.pop_back(); + tokens.pop_back(); + auto pos = tokens.back().position(); + tokens.pop_back(); + tokens.push_back({ + &generated_text.back()[0], + std::ssize(generated_text.back()), + pos, + lexeme::Identifier + }); + } + } }; diff --git a/source/parse.h b/source/parse.h index b6dadc8e6c..f7169251f3 100644 --- a/source/parse.h +++ b/source/parse.h @@ -5856,12 +5856,12 @@ class parser } next(); - // Next is an optional meta functions clause + // Next is an optional metafunctions clause while (curr() == "@") { next(); auto idx = id_expression(); if (!idx) { - error("'@' must be followed by a a meta function name", false); + error("'@' must be followed by a a metafunction name", false); return {}; } n->meta_functions.push_back( std::move(idx) ); @@ -5925,7 +5925,7 @@ class parser if (!n->meta_functions.empty()) { errors.emplace_back( n->meta_functions.front()->position(), - "(temporary alpha limitation) meta functions are currently not supported on functions, only on types" + "(temporary alpha limitation) metafunctions are currently not supported on functions, only on types" ); return {}; } @@ -5941,7 +5941,7 @@ class parser if (!n->meta_functions.empty()) { errors.emplace_back( n->meta_functions.front()->position(), - "(temporary alpha limitation) meta functions are currently not supported on namespaces, only on types" + "(temporary alpha limitation) metafunctions are currently not supported on namespaces, only on types" ); return {}; } @@ -5972,7 +5972,7 @@ class parser if (!n->meta_functions.empty()) { errors.emplace_back( n->meta_functions.front()->position(), - "(temporary alpha limitation) meta functions are currently not supported on objects, only on types" + "(temporary alpha limitation) metafunctions are currently not supported on objects, only on types" ); return {}; } @@ -6102,11 +6102,11 @@ class parser } } - // If this is a type with meta functions, apply those + // If this is a type with metafunctions, apply those if (n->is_type()) { if (!apply_type_meta_functions(*n)) { error( - "error encountered while applying type's meta functions", + "error encountered while applying type metafunctions", false, {}, true ); return {}; diff --git a/source/reflect.h b/source/reflect.h index ee68ad4609..3aae1b84ba 100644 --- a/source/reflect.h +++ b/source/reflect.h @@ -410,14 +410,14 @@ auto declaration::as_type() const //----------------------------------------------------------------------- // -// Meta functions - these are hardwired for now until we get to the +// Metafunctions - these are hardwired for now until we get to the // step of writing a Cpp2 interpreter to run inside the compiler // //----------------------------------------------------------------------- // //----------------------------------------------------------------------- -// Some common meta function helpers (meta functions are just functions, +// Some common metafunction helpers (metafunctions are just functions, // so they can be factored as usual) // auto add_virtual_destructor(meta::type_declaration& t) @@ -742,7 +742,7 @@ auto parser::apply_type_meta_functions( declaration_node& n ) auto cs = meta::compiler_services{ &errors, generated_tokens }; auto rtype = meta::type_declaration{ &n, cs }; - // For each meta function, apply it + // For each metafunction, apply it for (auto& meta : n.meta_functions) { rtype.set_meta_function_name( meta->to_string() ); @@ -775,7 +775,7 @@ auto parser::apply_type_meta_functions( declaration_node& n ) struct_( rtype ); } else { - error( "(temporary alpha limitation) unrecognized meta function name '" + meta->to_string() + "' - currently the supported names are: interface, polymorphic_base, ordered, weakly_ordered, partially_ordered, value, weakly_ordered_value, partially_ordered_value, struct" ); + error( "(temporary alpha limitation) unrecognized metafunction name '" + meta->to_string() + "' - currently the supported names are: interface, polymorphic_base, ordered, weakly_ordered, partially_ordered, value, weakly_ordered_value, partially_ordered_value, struct" ); return false; } }