151 lines
3.7 KiB
C++
151 lines
3.7 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <elna/source/lexer.hpp>
|
|
|
|
namespace elna::source
|
|
{
|
|
enum class binary_operator
|
|
{
|
|
sum,
|
|
subtraction,
|
|
multiplication,
|
|
division
|
|
};
|
|
|
|
class definition;
|
|
class bang_statement;
|
|
class block;
|
|
class binary_expression;
|
|
class variable_expression;
|
|
class integer_literal;
|
|
|
|
struct ParserVisitor
|
|
{
|
|
virtual void visit(definition *) = 0;
|
|
virtual void visit(bang_statement *) = 0;
|
|
virtual void visit(block *) = 0;
|
|
virtual void visit(binary_expression *) = 0;
|
|
virtual void visit(variable_expression *) = 0;
|
|
virtual void visit(integer_literal *) = 0;
|
|
};
|
|
|
|
/**
|
|
* AST node.
|
|
*/
|
|
class node
|
|
{
|
|
public:
|
|
virtual void accept(ParserVisitor *) = 0;
|
|
};
|
|
|
|
class statement : public node
|
|
{
|
|
};
|
|
|
|
class expression : public node
|
|
{
|
|
};
|
|
|
|
/**
|
|
* Constant definition.
|
|
*/
|
|
class definition : public node
|
|
{
|
|
std::string m_identifier;
|
|
std::unique_ptr<integer_literal> m_body;
|
|
|
|
public:
|
|
definition(std::string&& identifier, std::unique_ptr<integer_literal>&& body);
|
|
virtual void accept(ParserVisitor *visitor) override;
|
|
|
|
std::string& identifier() noexcept;
|
|
integer_literal& body();
|
|
};
|
|
|
|
class bang_statement : public statement
|
|
{
|
|
std::unique_ptr<expression> m_body;
|
|
|
|
public:
|
|
bang_statement(std::unique_ptr<expression>&& body);
|
|
virtual void accept(ParserVisitor *visitor) override;
|
|
|
|
expression& body();
|
|
};
|
|
|
|
/**
|
|
* Block.
|
|
*/
|
|
class block : public node
|
|
{
|
|
std::unique_ptr<statement> m_body;
|
|
std::vector<std::unique_ptr<definition>> m_definitions;
|
|
|
|
public:
|
|
block(std::vector<std::unique_ptr<definition>>&& definitions, std::unique_ptr<statement>&& body);
|
|
virtual void accept(ParserVisitor *visitor) override;
|
|
|
|
statement& body();
|
|
std::vector<std::unique_ptr<definition>>& definitions() noexcept;
|
|
};
|
|
|
|
class integer_literal : public expression
|
|
{
|
|
std::int32_t m_number;
|
|
|
|
public:
|
|
integer_literal(const std::int32_t value);
|
|
virtual void accept(ParserVisitor *visitor) override;
|
|
|
|
std::int32_t number() const noexcept;
|
|
};
|
|
|
|
class variable_expression : public expression
|
|
{
|
|
std::string m_name;
|
|
|
|
public:
|
|
variable_expression(const std::string& name);
|
|
virtual void accept(ParserVisitor *visitor) override;
|
|
|
|
const std::string& name() const noexcept;
|
|
};
|
|
|
|
class binary_expression : public expression
|
|
{
|
|
std::unique_ptr<expression> m_lhs;
|
|
std::unique_ptr<expression> m_rhs;
|
|
binary_operator m_operator;
|
|
|
|
public:
|
|
binary_expression(std::unique_ptr<expression>&& lhs,
|
|
std::unique_ptr<expression>&& rhs, const unsigned char operation);
|
|
|
|
virtual void accept(ParserVisitor *visitor) override;
|
|
expression& lhs();
|
|
expression& rhs();
|
|
binary_operator operation() const noexcept;
|
|
};
|
|
|
|
struct parser
|
|
{
|
|
parser(const std::vector<token>& tokens);
|
|
|
|
std::unique_ptr<block> parse();
|
|
|
|
private:
|
|
std::unique_ptr<expression> parse_factor();
|
|
std::unique_ptr<expression> parse_term();
|
|
std::unique_ptr<expression> parse_expression();
|
|
std::unique_ptr<definition> parse_definition();
|
|
std::unique_ptr<statement> parse_bang_statement();
|
|
std::vector<std::unique_ptr<definition>> parse_definitions();
|
|
std::unique_ptr<block> parse_block();
|
|
|
|
std::vector<token>::const_iterator tokens;
|
|
std::vector<token>::const_iterator end;
|
|
};
|
|
}
|