Support failure tests
This commit is contained in:
@ -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));
|
||||
}
|
||||
|
Reference in New Issue
Block a user