#pragma once #include #include #include 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 parser_visitor { 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(parser_visitor *) = 0; }; class statement : public node { }; class expression : public node { }; /** * Constant definition. */ class definition : public node { std::string m_identifier; std::unique_ptr m_body; public: definition(std::string&& identifier, std::unique_ptr&& body); virtual void accept(parser_visitor *visitor) override; std::string& identifier() noexcept; integer_literal& body(); }; class bang_statement : public statement { std::unique_ptr m_body; public: bang_statement(std::unique_ptr&& body); virtual void accept(parser_visitor *visitor) override; expression& body(); }; /** * Block. */ class block : public node { std::unique_ptr m_body; std::vector> m_definitions; public: block(std::vector>&& definitions, std::unique_ptr&& body); virtual void accept(parser_visitor *visitor) override; statement& body(); std::vector>& definitions() noexcept; }; class integer_literal : public expression { std::int32_t m_number; public: integer_literal(const std::int32_t value); virtual void accept(parser_visitor *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(parser_visitor *visitor) override; const std::string& name() const noexcept; }; class binary_expression : public expression { std::unique_ptr m_lhs; std::unique_ptr m_rhs; binary_operator m_operator; public: binary_expression(std::unique_ptr&& lhs, std::unique_ptr&& rhs, const unsigned char operation); virtual void accept(parser_visitor *visitor) override; expression& lhs(); expression& rhs(); binary_operator operation() const noexcept; }; struct parser { parser(const std::vector& tokens); std::unique_ptr parse(); private: std::unique_ptr parse_factor(); std::unique_ptr parse_term(); std::unique_ptr parse_expression(); std::unique_ptr parse_definition(); std::unique_ptr parse_bang_statement(); std::vector> parse_definitions(); std::unique_ptr parse_block(); std::vector::const_iterator tokens; std::vector::const_iterator end; }; }