elna/source/parser.cpp

882 lines
23 KiB
C++
Raw Normal View History

#include "elna/source/parser.hpp"
2024-03-01 10:13:55 +01:00
#include <stdexcept>
2024-03-07 09:15:11 +01:00
namespace elna::source
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
void empty_visitor::visit(declaration *declaration)
{
}
2024-03-20 17:56:38 +01:00
void empty_visitor::visit(constant_definition *definition)
2024-03-14 08:52:45 +01:00
{
definition->body().accept(this);
}
2024-03-20 17:56:38 +01:00
void empty_visitor::visit(procedure_definition *definition)
2024-03-14 08:52:45 +01:00
{
2024-03-29 11:01:19 +01:00
for (auto& parameter : definition->parameters())
{
parameter->accept(this);
}
2024-03-20 17:56:38 +01:00
definition->body().accept(this);
2024-03-14 08:52:45 +01:00
}
2024-03-20 17:56:38 +01:00
void empty_visitor::visit(call_statement *statement)
2024-03-17 01:00:44 +01:00
{
for (auto& argument : statement->arguments())
{
argument->accept(this);
}
2024-03-17 01:00:44 +01:00
}
2024-03-14 08:52:45 +01:00
void empty_visitor::visit(compound_statement *statement)
{
for (auto& nested_statement : statement->statements())
{
nested_statement->accept(this);
}
}
void empty_visitor::visit(assign_statement *statement)
{
statement->rvalue().accept(this);
}
2024-03-17 01:00:44 +01:00
void empty_visitor::visit(if_statement *statement)
{
statement->prerequisite().accept(this);
statement->body().accept(this);
}
void empty_visitor::visit(while_statement *statement)
{
statement->prerequisite().accept(this);
statement->body().accept(this);
}
2024-03-14 08:52:45 +01:00
void empty_visitor::visit(block *block)
{
2024-03-23 14:53:26 +01:00
for (const auto& constant : block->definitions())
2024-03-14 08:52:45 +01:00
{
2024-03-23 14:53:26 +01:00
constant->accept(this);
2024-03-14 08:52:45 +01:00
}
for (const auto& block_declaration : block->declarations())
{
block_declaration->accept(this);
}
block->body().accept(this);
}
void empty_visitor::visit(program *program)
{
visit(dynamic_cast<block *>(program));
}
2024-03-14 08:52:45 +01:00
void empty_visitor::visit(binary_expression *expression)
{
expression->lhs().accept(this);
expression->rhs().accept(this);
}
void empty_visitor::visit(variable_expression *variable)
{
}
void empty_visitor::visit(integer_literal *number)
{
}
2024-03-17 01:00:44 +01:00
void empty_visitor::visit(boolean_literal *boolean)
{
}
2024-03-09 08:36:07 +01:00
void node::accept(parser_visitor *)
2024-03-01 10:13:55 +01:00
{
}
declaration::declaration(const std::string& identifier, const std::string& type)
: m_identifier(identifier), m_type(type)
2024-03-10 08:50:55 +01:00
{
}
2024-03-20 17:56:38 +01:00
void declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2024-03-10 08:50:55 +01:00
std::string& declaration::identifier() noexcept
{
return m_identifier;
}
std::string& declaration::type() noexcept
{
return m_type;
}
2024-03-20 17:56:38 +01:00
definition::definition(const std::string& identifier)
: m_identifier(identifier)
2024-03-01 10:13:55 +01:00
{
}
2024-03-20 17:56:38 +01:00
std::string& definition::identifier() noexcept
2024-03-10 08:50:55 +01:00
{
2024-03-20 17:56:38 +01:00
return m_identifier;
2024-03-10 08:50:55 +01:00
}
2024-03-20 17:56:38 +01:00
constant_definition::constant_definition(const std::string& identifier, std::unique_ptr<integer_literal>&& body)
: definition(identifier), m_body(std::move(body))
{
}
void constant_definition::accept(parser_visitor *visitor)
2024-03-01 10:13:55 +01:00
{
visitor->visit(this);
}
2024-03-20 17:56:38 +01:00
integer_literal& constant_definition::body()
{
return *m_body;
}
procedure_definition::procedure_definition(const std::string& identifier, std::unique_ptr<block>&& body)
: definition(identifier), m_body(std::move(body))
{
}
2024-03-20 17:56:38 +01:00
void procedure_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
block& procedure_definition::body()
{
return *m_body;
}
std::vector<std::unique_ptr<declaration>>& procedure_definition::parameters() noexcept
{
return m_parameters;
}
2024-03-10 08:50:55 +01:00
block::block(std::vector<std::unique_ptr<definition>>&& definitions,
std::vector<std::unique_ptr<declaration>>&& declarations,
std::unique_ptr<statement>&& body)
2024-03-14 08:52:45 +01:00
: m_definitions(std::move(definitions)),
m_declarations(std::move(declarations)), m_body(std::move(body))
{
}
2024-03-09 08:36:07 +01:00
void block::accept(parser_visitor *visitor)
2024-03-01 10:13:55 +01:00
{
visitor->visit(this);
}
statement& block::body()
{
return *m_body;
}
std::vector<std::unique_ptr<definition>>& block::definitions() noexcept
{
return m_definitions;
}
2024-03-10 08:50:55 +01:00
std::vector<std::unique_ptr<declaration>>& block::declarations() noexcept
{
return m_declarations;
}
program::program(std::vector<std::unique_ptr<definition>>&& definitions,
std::vector<std::unique_ptr<declaration>>&& declarations,
std::unique_ptr<statement>&& body)
: block(std::move(definitions), std::move(declarations), std::move(body))
{
}
void program::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
integer_literal::integer_literal(const std::int32_t value)
: m_number(value)
{
}
2024-03-09 08:36:07 +01:00
void integer_literal::accept(parser_visitor *visitor)
2024-03-01 10:13:55 +01:00
{
visitor->visit(this);
}
std::int32_t integer_literal::number() const noexcept
{
return m_number;
}
2024-03-17 01:00:44 +01:00
boolean_literal::boolean_literal(const bool value)
: m_boolean(value)
{
}
void boolean_literal::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
bool boolean_literal::boolean() const noexcept
{
return m_boolean;
}
2024-03-07 09:15:11 +01:00
variable_expression::variable_expression(const std::string& name)
: m_name(name)
{
}
2024-03-09 08:36:07 +01:00
void variable_expression::accept(parser_visitor *visitor)
2024-03-01 10:13:55 +01:00
{
visitor->visit(this);
}
2024-03-07 09:15:11 +01:00
const std::string& variable_expression::name() const noexcept
2024-03-01 10:13:55 +01:00
{
return m_name;
}
2024-03-01 10:13:55 +01:00
binary_expression::binary_expression(std::unique_ptr<expression>&& lhs,
std::unique_ptr<expression>&& rhs, const unsigned char operation)
: m_lhs(std::move(lhs)), m_rhs(std::move(rhs))
{
switch (operation)
2024-03-01 10:13:55 +01:00
{
2024-03-03 13:11:39 +01:00
case '+':
this->m_operator = binary_operator::sum;
2024-03-03 13:11:39 +01:00
break;
case '-':
this->m_operator = binary_operator::subtraction;
2024-03-03 13:11:39 +01:00
break;
case '*':
this->m_operator = binary_operator::multiplication;
2024-03-03 13:11:39 +01:00
break;
case '/':
this->m_operator = binary_operator::division;
2024-03-03 13:11:39 +01:00
break;
2024-04-02 09:07:13 +02:00
case '=':
this->m_operator = binary_operator::equals;
break;
case 'n':
this->m_operator = binary_operator::not_equals;
break;
case '<':
this->m_operator = binary_operator::less;
break;
case 'l':
this->m_operator = binary_operator::less_equal;
break;
case '>':
this->m_operator = binary_operator::greater;
break;
case 'g':
this->m_operator = binary_operator::greater_equal;
break;
2024-03-03 13:11:39 +01:00
default:
throw std::logic_error("Invalid binary operator");
2024-03-01 10:13:55 +01:00
}
}
2024-03-09 08:36:07 +01:00
void binary_expression::accept(parser_visitor *visitor)
2024-03-01 10:13:55 +01:00
{
visitor->visit(this);
}
expression& binary_expression::lhs()
{
return *m_lhs;
}
expression& binary_expression::rhs()
{
return *m_rhs;
}
binary_operator binary_expression::operation() const noexcept
{
return m_operator;
}
call_statement::call_statement(const std::string& name)
: m_name(name)
{
}
2024-03-19 09:35:50 +01:00
void call_statement::accept(parser_visitor *visitor)
2024-03-01 10:13:55 +01:00
{
visitor->visit(this);
}
2024-03-19 09:35:50 +01:00
std::string& call_statement::name() noexcept
{
return m_name;
}
std::vector<std::unique_ptr<expression>>& call_statement::arguments() noexcept
{
return m_arguments;
}
2024-03-10 08:50:55 +01:00
compound_statement::compound_statement(std::vector<std::unique_ptr<statement>>&& statements)
: m_statements(std::move(statements))
{
}
void compound_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
std::vector<std::unique_ptr<statement>>& compound_statement::statements()
{
return m_statements;
}
2024-03-14 08:52:45 +01:00
void assign_statement::accept(parser_visitor *visitor)
2024-03-11 10:43:26 +01:00
{
visitor->visit(this);
}
2024-03-14 08:52:45 +01:00
assign_statement::assign_statement(const std::string& lvalue, std::unique_ptr<expression>&& rvalue)
: m_lvalue(lvalue), m_rvalue(std::move(rvalue))
{
}
std::string& assign_statement::lvalue() noexcept
{
return m_lvalue;
}
expression& assign_statement::rvalue()
{
return *m_rvalue;
}
2024-03-20 17:56:38 +01:00
if_statement::if_statement(std::unique_ptr<expression>&& prerequisite, std::unique_ptr<statement>&& body)
2024-03-17 01:00:44 +01:00
: m_prerequisite(std::move(prerequisite)), m_body(std::move(body))
{
}
void if_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2024-03-20 17:56:38 +01:00
expression& if_statement::prerequisite()
2024-03-17 01:00:44 +01:00
{
return *m_prerequisite;
}
statement& if_statement::body()
{
return *m_body;
}
2024-03-20 17:56:38 +01:00
while_statement::while_statement(std::unique_ptr<expression>&& prerequisite, std::unique_ptr<statement>&& body)
2024-03-17 01:00:44 +01:00
: m_prerequisite(std::move(prerequisite)), m_body(std::move(body))
{
}
void while_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
2024-03-20 17:56:38 +01:00
expression& while_statement::prerequisite()
2024-03-17 01:00:44 +01:00
{
return *m_prerequisite;
}
statement& while_statement::body()
{
return *m_body;
}
2024-03-14 08:52:45 +01:00
parser::parser(lexer&& tokens)
: iterator(std::move(tokens))
{
}
std::unique_ptr<program> parser::parse()
2024-03-01 10:13:55 +01:00
{
2024-03-23 14:53:26 +01:00
auto constants = parse_constant_definitions();
auto declarations = parse_declarations();
2024-03-23 14:53:26 +01:00
auto procedures = parse_procedure_definitions();
auto parsed_statement = parse_statement();
if (parsed_statement == nullptr)
{
return nullptr;
}
2024-03-23 14:53:26 +01:00
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));
2024-03-01 10:13:55 +01:00
}
2024-03-14 08:52:45 +01:00
const std::list<std::unique_ptr<error>>& parser::errors() const noexcept
{
return iterator.errors();
}
std::unique_ptr<expression> parser::parse_factor()
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
if (iterator->of() == source::token::type::identifier)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
auto result = std::make_unique<variable_expression>(iterator->identifier());
++iterator;
return result;
2024-03-01 10:13:55 +01:00
}
2024-03-14 08:52:45 +01:00
else if (iterator->of() == source::token::token::type::number)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
auto result = std::make_unique<integer_literal>(iterator->number());
++iterator;
return result;
2024-03-01 10:13:55 +01:00
}
2024-03-20 17:56:38 +01:00
else if (iterator->of() == source::token::token::type::boolean)
{
auto result = std::make_unique<boolean_literal>(iterator->number());
++iterator;
return result;
}
2024-03-14 08:52:45 +01:00
else if (iterator->of() == source::token::type::left_paren)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-01 10:13:55 +01:00
2024-04-02 09:07:13 +02:00
auto expression = parse_condition();
2024-03-01 10:13:55 +01:00
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-01 10:13:55 +01:00
return expression;
}
return nullptr;
}
std::unique_ptr<expression> parser::parse_term()
2024-03-01 10:13:55 +01:00
{
auto lhs = parse_factor();
2024-03-14 08:52:45 +01:00
if (lhs == nullptr || iterator.current().of() != source::token::type::factor_operator)
2024-03-03 13:11:39 +01:00
{
return lhs;
}
2024-03-14 08:52:45 +01:00
while (iterator->of() == source::token::type::factor_operator)
2024-03-03 13:11:39 +01:00
{
2024-03-14 08:52:45 +01:00
auto _operator = iterator->identifier()[0];
++iterator;
2024-03-09 08:36:07 +01:00
auto rhs = parse_factor();
lhs = std::make_unique<binary_expression>(std::move(lhs),
std::move(rhs), _operator);
2024-03-03 13:11:39 +01:00
}
2024-03-09 08:36:07 +01:00
return lhs;
2024-03-01 10:13:55 +01:00
}
std::unique_ptr<expression> parser::parse_expression()
2024-03-01 10:13:55 +01:00
{
auto term = parse_term();
2024-03-14 08:52:45 +01:00
if (term == nullptr || iterator.current().of() != source::token::type::term_operator)
2024-03-01 10:13:55 +01:00
{
return term;
}
2024-03-14 08:52:45 +01:00
while (iterator->of() == source::token::type::term_operator)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
auto _operator = iterator->identifier()[0];
++iterator;
2024-03-09 08:36:07 +01:00
auto rhs = parse_term();
term = std::make_unique<binary_expression>(std::move(term),
std::move(rhs), _operator);
2024-03-01 10:13:55 +01:00
}
2024-03-09 08:36:07 +01:00
return term;
2024-03-01 10:13:55 +01:00
}
2024-04-02 09:07:13 +02:00
std::unique_ptr<expression> parser::parse_condition()
{
std::unique_ptr<expression> lhs;
if ((lhs = parse_expression()) == nullptr)
{
return lhs;
}
unsigned char _operator{ 0 };
if (iterator.current().of() == source::token::type::equals)
{
_operator = '=';
}
else if (iterator.current().of() == source::token::type::comparison_operator)
{
_operator = iterator->identifier()[0];
}
else
{
return lhs;
}
++iterator;
auto rhs = parse_expression();
if (rhs == nullptr)
{
return nullptr;
}
return std::make_unique<binary_expression>(std::move(lhs), std::move(rhs), _operator);
}
2024-03-20 17:56:38 +01:00
std::unique_ptr<constant_definition> parser::parse_constant_definition()
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
auto definition_identifier = iterator.advance(token::type::identifier);
2024-03-01 10:13:55 +01:00
2024-03-10 08:50:55 +01:00
if (!definition_identifier.has_value())
{
return nullptr;
}
2024-03-14 08:52:45 +01:00
if (!iterator.skip(token::type::equals))
2024-03-10 08:50:55 +01:00
{
return nullptr;
}
2024-03-01 10:13:55 +01:00
2024-03-14 08:52:45 +01:00
if (iterator->of() == source::token::type::number)
2024-03-01 10:13:55 +01:00
{
2024-03-20 17:56:38 +01:00
auto result = std::make_unique<constant_definition>(definition_identifier.value().get().identifier(),
2024-03-14 08:52:45 +01:00
std::make_unique<integer_literal>(iterator->number()));
++iterator;
return result;
2024-03-01 10:13:55 +01:00
}
return nullptr;
}
2024-03-23 14:53:26 +01:00
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);
2024-03-28 00:55:13 +01:00
if (!definition_identifier.has_value() || !iterator.skip(token::type::left_paren))
2024-03-23 14:53:26 +01:00
{
return nullptr;
}
2024-03-28 00:55:13 +01:00
std::vector<std::unique_ptr<declaration>> declarations;
while (!iterator.current(token::type::right_paren))
{
std::unique_ptr<declaration> parsed_declaration = parse_declaration();
if (parsed_declaration == nullptr)
{
return nullptr;
}
declarations.push_back(std::move(parsed_declaration));
if (iterator->of() == token::type::comma)
{
++iterator;
continue;
}
else if (iterator->of() != token::type::right_paren)
{
iterator.add_error(*iterator);
return nullptr;
}
}
iterator.skip(token::type::right_paren);
2024-03-23 14:53:26 +01:00
auto definition_body = parse_block();
if (definition_body == nullptr || !iterator.skip(token::type::semicolon))
{
return nullptr;
}
2024-03-28 00:55:13 +01:00
auto procedure = std::make_unique<procedure_definition>(definition_identifier->get().identifier(),
2024-03-23 14:53:26 +01:00
std::move(definition_body));
2024-03-28 00:55:13 +01:00
procedure->parameters() = std::move(declarations);
return procedure;
2024-03-23 14:53:26 +01:00
}
2024-03-10 08:50:55 +01:00
std::unique_ptr<declaration> parser::parse_declaration()
{
2024-03-14 08:52:45 +01:00
auto declaration_identifier = iterator.advance(token::type::identifier);
2024-03-10 08:50:55 +01:00
2024-03-17 01:00:44 +01:00
if (!declaration_identifier.has_value() || !iterator.skip(token::type::colon))
{
return nullptr;
}
auto type_identifier = iterator.advance(token::type::identifier);
if (!type_identifier.has_value())
2024-03-10 08:50:55 +01:00
{
return nullptr;
}
return std::make_unique<declaration>(declaration_identifier.value().get().identifier(),
type_identifier.value().get().identifier());
2024-03-10 08:50:55 +01:00
}
std::unique_ptr<statement> parser::parse_statement()
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
if (iterator.look_ahead(token::type::assignment))
{
return parse_assign_statement();
}
2024-03-19 09:35:50 +01:00
else if (iterator.current(token::type::identifier) && iterator.look_ahead(token::type::left_paren))
2024-03-01 10:13:55 +01:00
{
2024-03-19 09:35:50 +01:00
return parse_call_statement();
2024-03-01 10:13:55 +01:00
}
2024-03-14 08:52:45 +01:00
else if (iterator.current(token::type::begin))
2024-03-10 08:50:55 +01:00
{
return parse_compound_statement();
}
2024-03-17 01:00:44 +01:00
else if (iterator.current(token::type::when))
{
return parse_if_statement();
}
2024-04-02 09:07:13 +02:00
else if (iterator.current(token::type::loop))
2024-03-17 01:00:44 +01:00
{
return parse_while_statement();
}
2024-03-14 08:52:45 +01:00
iterator.add_error(*iterator);
2024-03-01 10:13:55 +01:00
return nullptr;
}
2024-03-19 09:35:50 +01:00
std::unique_ptr<call_statement> parser::parse_call_statement()
2024-03-01 10:13:55 +01:00
{
2024-03-19 09:35:50 +01:00
auto function_name = iterator.advance(token::type::identifier);
if (function_name.has_value() && !iterator.skip(token::type::left_paren))
2024-03-10 08:50:55 +01:00
{
return nullptr;
}
auto call = std::make_unique<call_statement>(function_name->get().identifier());
std::unique_ptr<expression> argument_expression;
2024-03-01 10:13:55 +01:00
if (iterator.current(token::type::right_paren))
2024-03-10 08:50:55 +01:00
{
++iterator;
return call;
}
2024-04-02 09:07:13 +02:00
while ((argument_expression = parse_condition()) != nullptr)
{
call->arguments().push_back(std::move(argument_expression));
if (iterator.current(token::type::right_paren))
{
++iterator;
return call;
}
if (!iterator.skip(token::type::comma))
{
break;
}
2024-03-10 08:50:55 +01:00
}
2024-03-17 01:00:44 +01:00
return nullptr;
}
2024-03-10 08:50:55 +01:00
std::unique_ptr<compound_statement> parser::parse_compound_statement()
{
2024-03-14 08:52:45 +01:00
if (!iterator.advance(token::type::begin))
2024-03-10 08:50:55 +01:00
{
return nullptr;
}
auto result = std::make_unique<compound_statement>();
std::unique_ptr<statement> next_statement;
2024-03-01 10:13:55 +01:00
2024-03-11 10:43:26 +01:00
while ((next_statement = parse_statement()) != nullptr)
2024-03-01 10:13:55 +01:00
{
2024-03-11 10:43:26 +01:00
result->statements().push_back(std::move(next_statement));
2024-03-14 08:52:45 +01:00
if (iterator->of() == token::type::semicolon)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-11 10:43:26 +01:00
}
2024-03-14 08:52:45 +01:00
else if (iterator->of() == token::type::end)
2024-03-11 10:43:26 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-11 10:43:26 +01:00
break;
}
else
{
2024-03-14 08:52:45 +01:00
iterator.add_error(*iterator);
2024-03-11 10:43:26 +01:00
break;
2024-03-01 10:13:55 +01:00
}
2024-03-10 08:50:55 +01:00
}
return result;
}
2024-03-14 08:52:45 +01:00
std::unique_ptr<assign_statement> parser::parse_assign_statement()
{
auto name = iterator.advance(token::type::identifier);
if (!name.has_value() || !iterator.skip(token::type::assignment))
{
return nullptr;
}
2024-04-02 09:07:13 +02:00
auto rvalue = parse_condition();
2024-03-14 08:52:45 +01:00
if (rvalue == nullptr)
{
return nullptr;
}
return std::make_unique<assign_statement>(name.value().get().identifier(), std::move(rvalue));
}
2024-03-17 01:00:44 +01:00
std::unique_ptr<if_statement> parser::parse_if_statement()
{
if (!iterator.skip(token::type::when))
{
return nullptr;
}
2024-04-02 09:07:13 +02:00
auto condition = parse_condition();
2024-03-17 01:00:44 +01:00
if (condition == nullptr || !iterator.skip(token::type::then))
{
return nullptr;
}
auto body = parse_statement();
if (body == nullptr)
{
return nullptr;
}
return std::make_unique<if_statement>(std::move(condition), std::move(body));
}
std::unique_ptr<while_statement> parser::parse_while_statement()
{
2024-04-02 09:07:13 +02:00
if (!iterator.skip(token::type::loop))
2024-03-17 01:00:44 +01:00
{
return nullptr;
}
2024-04-02 09:07:13 +02:00
auto condition = parse_condition();
2024-03-17 01:00:44 +01:00
if (condition == nullptr || !iterator.skip(token::type::_do))
{
return nullptr;
}
auto body = parse_statement();
if (body == nullptr)
{
return nullptr;
}
return std::make_unique<while_statement>(std::move(condition), std::move(body));
}
2024-03-23 14:53:26 +01:00
std::vector<std::unique_ptr<constant_definition>> parser::parse_constant_definitions()
2024-03-10 08:50:55 +01:00
{
2024-03-23 14:53:26 +01:00
std::vector<std::unique_ptr<constant_definition>> definitions;
2024-03-10 08:50:55 +01:00
2024-03-14 08:52:45 +01:00
if (iterator->of() != token::type::let)
2024-03-10 08:50:55 +01:00
{
return definitions;
}
2024-03-14 08:52:45 +01:00
++iterator; // Skip const.
2024-03-10 08:50:55 +01:00
2024-03-23 14:53:26 +01:00
std::unique_ptr<constant_definition> parsed_definition;
2024-03-20 17:56:38 +01:00
while ((parsed_definition = parse_constant_definition()) != nullptr)
2024-03-10 08:50:55 +01:00
{
definitions.push_back(std::move(parsed_definition));
2024-03-01 10:13:55 +01:00
2024-03-14 08:52:45 +01:00
if (iterator->of() == source::token::type::comma)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-01 10:13:55 +01:00
}
2024-03-14 08:52:45 +01:00
else if (iterator->of() == source::token::type::semicolon)
2024-03-01 10:13:55 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-10 08:50:55 +01:00
break;
}
else
{
2024-03-14 08:52:45 +01:00
iterator.add_error(*iterator);
2024-03-10 08:50:55 +01:00
break;
2024-03-01 10:13:55 +01:00
}
}
return definitions;
}
2024-03-23 14:53:26 +01:00
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;
}
2024-03-10 08:50:55 +01:00
std::vector<std::unique_ptr<declaration>> parser::parse_declarations()
2024-03-01 10:13:55 +01:00
{
2024-03-10 08:50:55 +01:00
std::vector<std::unique_ptr<declaration>> declarations;
2024-03-14 08:52:45 +01:00
if (iterator->of() != token::type::var)
2024-03-01 10:13:55 +01:00
{
2024-03-10 08:50:55 +01:00
return declarations;
}
2024-03-14 08:52:45 +01:00
++iterator; // Skip var.
2024-03-10 08:50:55 +01:00
std::unique_ptr<declaration> parsed_declaration;
while ((parsed_declaration = parse_declaration()) != nullptr)
{
declarations.push_back(std::move(parsed_declaration));
2024-03-14 08:52:45 +01:00
if (iterator->of() == token::type::comma)
2024-03-10 08:50:55 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-10 08:50:55 +01:00
}
2024-03-14 08:52:45 +01:00
else if (iterator->of() == token::type::semicolon)
2024-03-10 08:50:55 +01:00
{
2024-03-14 08:52:45 +01:00
++iterator;
2024-03-10 08:50:55 +01:00
break;
}
else
{
2024-03-14 08:52:45 +01:00
iterator.add_error(*iterator);
2024-03-10 08:50:55 +01:00
break;
}
2024-03-01 10:13:55 +01:00
}
2024-03-10 08:50:55 +01:00
return declarations;
}
std::unique_ptr<block> parser::parse_block()
{
2024-03-23 14:53:26 +01:00
auto constants = parse_constant_definitions();
2024-03-10 08:50:55 +01:00
auto declarations = parse_declarations();
auto parsed_statement = parse_statement();
if (parsed_statement == nullptr)
2024-03-01 10:13:55 +01:00
{
return nullptr;
}
2024-03-23 14:53:26 +01:00
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);
}
2024-03-10 08:50:55 +01:00
return std::make_unique<block>(std::move(definitions),
std::move(declarations), std::move(parsed_statement));
}
2024-03-01 10:13:55 +01:00
}