#include "parsing.h" namespace parsing { namespace { Result, std::string> parse_type(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { auto token = inner.expect(token::Type::Ident); stream.m_position = inner.m_position; auto ty = new AST::FundamentalType{ AST::FundamentalTypeKind::Int }; return new std::unique_ptr{ ty }; } catch (std::runtime_error error) { return new std::string{ error.what() }; } } Result, std::string> parse_expression(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { auto token = inner.next(); if (token.type == token::Type::LiteralInt) { stream.m_position = inner.m_position; auto expr = new AST::IntLiteralExpression{ std::stoi(token.content) }; return new std::unique_ptr{ expr }; } else if (token.type == token::Type::Ident) { stream.m_position = inner.m_position; auto expr = new AST::ValueReferenceExpression{ token.content }; return new std::unique_ptr{ expr }; } else { throw std::runtime_error("Expected expression"); } } catch (std::runtime_error error) { return new std::string{ error.what() }; } } Result, std::string> parse_init_statement(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { auto ty = parse_type(inner).unwrap(); auto name = inner.expect(token::Type::Ident); std::optional> expr = {}; if (inner.peek().type == token::Type::Symbol && inner.peek().content == "=") { inner.expect(token::Type::Symbol, "="); expr = parse_expression(inner).unwrap(); } inner.expect(token::Type::Symbol, ";"); stream.m_position = inner.m_position; auto init = new AST::InitializationStatement{ std::move(ty), name.content, std::move(expr) }; return new std::unique_ptr{ init }; } catch (std::runtime_error error) { return new std::string{ error.what() }; } } Result, std::string> parse_statement(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { if (inner.peek().type == token::Type::ReturnKeyword) { inner.next(); auto expression = parse_expression(inner).unwrap(); inner.expect(token::Type::Symbol, ";"); stream.m_position = inner.m_position; auto ret = new AST::ReturnStatement{ std::move(expression) }; return new std::unique_ptr{ ret }; } else if (inner.peek().type == token::Type::Ident) { if (auto init = parse_init_statement(inner); init.ok()) { stream.m_position = inner.m_position; return new std::unique_ptr{ init.unwrap() }; } else if (auto expr = parse_expression(inner); expr.ok()) { stream.m_position = inner.m_position; stream.expect(token::Type::Symbol, ";"); auto expr_statement = new AST::ExpressionStatement{ expr.unwrap() }; return new std::unique_ptr{ expr_statement }; } else { throw std::runtime_error("Expected initialization statement"); } } else { throw std::runtime_error("Expected return-keyword"); } } catch (std::runtime_error error) { return new std::string{ error.what() }; } } } Result, std::string> parse_top_level_statement(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { auto type = parse_type(inner).unwrap(); auto name_token = inner.expect(token::Type::Ident); inner.expect(token::Type::Symbol, "("); inner.expect(token::Type::Symbol, ")"); inner.expect(token::Type::Symbol, "{"); std::vector> statements{}; auto statement = parse_statement(inner); while (statement.ok()) { statements.push_back(statement.unwrap()); statement = parse_statement(inner); } inner.expect(token::Type::Symbol, "}"); stream.m_position = inner.m_position; auto fun = new AST::Function{ std::move(type), {}, name_token.content, std::move(statements) }; return new std::unique_ptr{ fun }; } catch (std::runtime_error error) { return new std::string(error.what()); } } }