Support failure tests

This commit is contained in:
2024-03-23 14:53:26 +01:00
parent a78e08521e
commit 30f80bcb88
14 changed files with 241 additions and 53 deletions

View File

@ -49,9 +49,9 @@ namespace elna::source
void empty_visitor::visit(block *block)
{
for (const auto& block_definition : block->definitions())
for (const auto& constant : block->definitions())
{
block_definition->accept(this);
constant->accept(this);
}
for (const auto& block_declaration : block->declarations())
{
@ -83,9 +83,6 @@ namespace elna::source
{
}
/**
* AST node.
*/
void node::accept(parser_visitor *)
{
}
@ -381,14 +378,26 @@ namespace elna::source
std::unique_ptr<program> parser::parse()
{
auto definitions = parse_definitions();
auto constants = parse_constant_definitions();
auto declarations = parse_declarations();
auto procedures = parse_procedure_definitions();
auto parsed_statement = parse_statement();
if (parsed_statement == nullptr)
{
return nullptr;
}
std::vector<std::unique_ptr<definition>> definitions(constants.size() + procedures.size());
std::vector<std::unique_ptr<definition>>::iterator definition = definitions.begin();
for (auto& constant : constants)
{
*definition++ = std::move(constant);
}
for (auto& procedure : procedures)
{
*definition++ = std::move(procedure);
}
return std::make_unique<program>(std::move(definitions),
std::move(declarations), std::move(parsed_statement));
}
@ -492,6 +501,28 @@ namespace elna::source
return nullptr;
}
std::unique_ptr<procedure_definition> parser::parse_procedure_definition()
{
if (!iterator.skip(token::type::procedure))
{
return nullptr;
}
auto definition_identifier = iterator.advance(token::type::identifier);
if (!definition_identifier.has_value() || !iterator.skip(token::type::semicolon))
{
return nullptr;
}
auto definition_body = parse_block();
if (definition_body == nullptr || !iterator.skip(token::type::semicolon))
{
return nullptr;
}
return std::make_unique<procedure_definition>(definition_identifier->get().identifier(),
std::move(definition_body));
}
std::unique_ptr<declaration> parser::parse_declaration()
{
auto declaration_identifier = iterator.advance(token::type::identifier);
@ -641,9 +672,9 @@ namespace elna::source
return std::make_unique<while_statement>(std::move(condition), std::move(body));
}
std::vector<std::unique_ptr<definition>> parser::parse_definitions()
std::vector<std::unique_ptr<constant_definition>> parser::parse_constant_definitions()
{
std::vector<std::unique_ptr<definition>> definitions;
std::vector<std::unique_ptr<constant_definition>> definitions;
if (iterator->of() != token::type::let)
{
@ -651,7 +682,7 @@ namespace elna::source
}
++iterator; // Skip const.
std::unique_ptr<definition> parsed_definition;
std::unique_ptr<constant_definition> parsed_definition;
while ((parsed_definition = parse_constant_definition()) != nullptr)
{
definitions.push_back(std::move(parsed_definition));
@ -674,6 +705,23 @@ namespace elna::source
return definitions;
}
std::vector<std::unique_ptr<procedure_definition>> parser::parse_procedure_definitions()
{
std::vector<std::unique_ptr<procedure_definition>> definitions;
while (iterator.current(token::type::procedure))
{
auto parsed_definition = parse_procedure_definition();
if (parsed_definition == nullptr)
{
break;
}
definitions.push_back(std::move(parsed_definition));
}
return definitions;
}
std::vector<std::unique_ptr<declaration>> parser::parse_declarations()
{
std::vector<std::unique_ptr<declaration>> declarations;
@ -709,7 +757,7 @@ namespace elna::source
std::unique_ptr<block> parser::parse_block()
{
auto definitions = parse_definitions();
auto constants = parse_constant_definitions();
auto declarations = parse_declarations();
auto parsed_statement = parse_statement();
@ -717,6 +765,13 @@ namespace elna::source
{
return nullptr;
}
std::vector<std::unique_ptr<definition>> definitions(constants.size());
std::vector<std::unique_ptr<definition>>::iterator definition = definitions.begin();
for (auto& constant : constants)
{
*definition++ = std::move(constant);
}
return std::make_unique<block>(std::move(definitions),
std::move(declarations), std::move(parsed_statement));
}