diff --git a/source/cppfront.cpp b/source/cppfront.cpp index 459e9aabe..2c11a2c2a 100644 --- a/source/cppfront.cpp +++ b/source/cppfront.cpp @@ -1655,14 +1655,30 @@ class cppfront if (n.expr.index() == primary_expression_node::declaration) { + // This must be an anonymous declaration auto& decl = std::get(n.expr); + assert(decl && !decl->identifier); - // The usual non-null assertion, plus it should be an anonymous function - assert(decl && !decl->identifier && decl->is(declaration_node::function)); + // Handle an anonymous function + if (decl->is(declaration_node::function)) { + auto lambda_intro = build_capture_lambda_intro_for(decl->captures, n.position()); + emit(*decl, lambda_intro); + } + // Else an anonymous object as 'typeid { initializer }' + else { + assert(decl->is(declaration_node::object)); + auto& type_id = std::get(decl->type); + + printer.add_pad_in_this_line( -5 ); - auto lambda_intro = build_capture_lambda_intro_for(decl->captures, n.position()); + emit(*type_id); + printer.print_cpp2("{", decl->position()); - emit(*decl, lambda_intro); + assert(decl->initializer); + emit(*decl->initializer, false); + + printer.print_cpp2("}", decl->position()); + } } } diff --git a/source/parse.h b/source/parse.h index 7e33a771b..f2cc0b0f9 100644 --- a/source/parse.h +++ b/source/parse.h @@ -1063,7 +1063,7 @@ struct declaration_node source_position pos; std::unique_ptr identifier; - enum active : std::uint8_t { function, object }; + enum active : std::uint8_t { function, object, udt_type }; std::variant< std::unique_ptr, std::unique_ptr @@ -1563,7 +1563,7 @@ class parser } if (curr().type() == lexeme::LeftParen - // If in the future (not now) we want to experiment with braced-expressions + // If in the future (not now) we decide to allow braced-expressions // || curr().type() == lexeme::LeftBrace ) { @@ -1589,25 +1589,25 @@ class parser return n; } - if (auto decl = unnamed_declaration(curr().position(), true, true)) // captures are allowed + if (auto decl = unnamed_declaration(curr().position(), false, true)) // captures are allowed { assert (!decl->identifier && "ICE: declaration should have been unnamed"); - if (!decl->is(declaration_node::function)) { - error("an unnamed declaration at expression scope must be a function"); + if (decl->is(declaration_node::udt_type)) { + error("(temporary alpha limitation) an unnamed declaration at expression scope must be a function or an object"); next(); return {}; } - auto& func = std::get(decl->type); - assert(func); - if (func->returns.index() == function_type_node::list) { - error("an unnamed function at expression scope currently cannot return multiple values"); - next(); - return {}; - } - if (!func->contracts.empty()) { - error("an unnamed function at expression scope currently cannot have contracts"); - next(); - return {}; + if (auto func = std::get_if(&decl->type)) { + if ((*func)->returns.index() == function_type_node::list) { + error("an unnamed function at expression scope currently cannot return multiple values"); + next(); + return {}; + } + if (!(*func)->contracts.empty()) { + error("an unnamed function at expression scope currently cannot have contracts"); + next(); + return {}; + } } n->expr = std::move(decl);