diff --git a/src/main.cpp b/src/main.cpp index afdaa2c..9dd13f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -70,12 +70,14 @@ std::optional compile(std::string_view in_filename) { } // Parse tokens + parsing::Scope parse_scope{}; + auto stream = token::TokenStream{ tokens }; std::vector> statements; - auto statement = parsing::parse_top_level_statement(stream); + auto statement = parsing::parse_top_level_statement(stream, parse_scope); while (statement.ok()) { statements.push_back(statement.unwrap()); - statement = parsing::parse_top_level_statement(stream); + statement = parsing::parse_top_level_statement(stream, parse_scope); } if (stream.peek().type != token::Type::Eof) { std::cerr << statement.unwrap_err() << std::endl; diff --git a/src/parsing.cpp b/src/parsing.cpp index 8e39dd1..8c78300 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -5,9 +5,9 @@ namespace parsing { namespace { - Result, std::string> parse_expression(token::TokenStream& stream); + Result, std::string> parse_expression(token::TokenStream& stream, Scope& scope); - Result, std::string> parse_type(token::TokenStream& stream) { + Result, std::string> parse_type(token::TokenStream& stream, Scope&) { token::TokenStream inner{ stream }; try { auto token = inner.expect(token::Type::Ident); @@ -49,7 +49,7 @@ namespace parsing { } } - Result, std::string> parse_array_postfix(token::TokenStream& stream, bool allow_empty) { + Result, std::string> parse_array_postfix(token::TokenStream& stream, bool allow_empty, Scope&) { token::TokenStream inner{ stream }; try { std::optional returned{}; @@ -71,7 +71,7 @@ namespace parsing { } } - Result, std::string> parse_list_initializer(token::TokenStream& stream) { + Result, std::string> parse_list_initializer(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; try { auto before_meta = inner.metadata(); @@ -85,7 +85,7 @@ namespace parsing { if (counter++ > 0) { inner.expect(token::Type::Symbol, ","); } - expressions.push_back(parse_expression(inner).unwrap()); + expressions.push_back(parse_expression(inner, scope).unwrap()); } inner.expect(token::Type::Symbol, "}"); @@ -105,10 +105,10 @@ namespace parsing { } } - Result, std::string> parse_plain_expression(token::TokenStream& stream) { + Result, std::string> parse_plain_expression(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; try { - if (auto list_init = parse_list_initializer(inner); list_init.ok()) { + if (auto list_init = parse_list_initializer(inner, scope); list_init.ok()) { stream.m_position = inner.m_position; return std::unique_ptr { list_init.unwrap() }; @@ -142,11 +142,11 @@ namespace parsing { } } - Result, std::string> parse_cast(token::TokenStream& stream) { + Result, std::string> parse_cast(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; try { inner.expect(token::Type::Symbol, "("); - auto ty = parse_type(inner).unwrap(); + auto ty = parse_type(inner, scope).unwrap(); inner.expect(token::Type::Symbol, ")"); stream.m_position = inner.m_position; @@ -158,14 +158,14 @@ namespace parsing { } } - Result, std::string> parse_primary_expression(token::TokenStream& stream) { + Result, std::string> parse_primary_expression(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; try { auto before_meta = inner.metadata(); - if (auto cast = parse_cast(inner); cast.ok()) { - auto expr = parse_primary_expression(inner).unwrap(); + if (auto cast = parse_cast(inner, scope); cast.ok()) { + auto expr = parse_primary_expression(inner, scope).unwrap(); stream.m_position = inner.m_position; return std::unique_ptr{ new AST::CastExpression{ @@ -177,14 +177,14 @@ namespace parsing { } else if (inner.peek().content == "(") { inner.next(); - auto expr = parse_expression(inner).unwrap(); + auto expr = parse_expression(inner, scope).unwrap(); inner.expect(token::Type::Symbol, ")"); stream.m_position = inner.m_position; return expr; } else if (inner.peek().content == "&") { inner.next(); - auto expr = parse_primary_expression(inner).unwrap(); + auto expr = parse_primary_expression(inner, scope).unwrap(); stream.m_position = inner.m_position; return std::unique_ptr { new AST::RefExpression(before_meta + inner.metadata(), std::move(expr)) @@ -192,14 +192,14 @@ namespace parsing { } else if (inner.peek().content == "*") { inner.next(); - auto expr = parse_primary_expression(inner).unwrap(); + auto expr = parse_primary_expression(inner, scope).unwrap(); stream.m_position = inner.m_position; return std::unique_ptr { new AST::DerefExpression(before_meta + inner.metadata(), std::move(expr)) }; } - auto plain_expr = parse_plain_expression(inner); + auto plain_expr = parse_plain_expression(inner, scope); while (inner.peek().content == "(" || inner.peek().content == "[") { if (inner.peek().content == "(") { inner.next(); @@ -210,7 +210,7 @@ namespace parsing { while (inner.peek().content != ")") { if (counter++ > 0) inner.expect(token::Type::Symbol, ","); - args.push_back(parse_expression(inner).unwrap()); + args.push_back(parse_expression(inner, scope).unwrap()); } inner.expect(token::Type::Symbol, ")"); @@ -218,7 +218,7 @@ namespace parsing { auto fn_call = new AST::FunctionCallExpression{ before_meta + inner.metadata(), plain_expr.unwrap(), std::move(args) }; plain_expr = std::unique_ptr{ fn_call }; } - else if (auto postfix = parse_array_postfix(inner, false); postfix.ok()) { + else if (auto postfix = parse_array_postfix(inner, false, scope); postfix.ok()) { auto idx_expr = new AST::IndexAccessExpression{ before_meta + inner.metadata(), plain_expr.unwrap(), *postfix.unwrap() }; plain_expr = std::unique_ptr{ idx_expr }; @@ -234,7 +234,7 @@ namespace parsing { } } - Result parse_binop(token::TokenStream& stream) { + Result parse_binop(token::TokenStream& stream, Scope&) { token::TokenStream inner{ stream }; try { auto token = inner.next(); @@ -270,32 +270,32 @@ namespace parsing { } std::unique_ptr parse_rhs( - token::TokenStream& stream, std::unique_ptr lhs, int prev_precedence) { + token::TokenStream& stream, std::unique_ptr lhs, int prev_precedence, Scope& scope) { auto before = stream.metadata(); - auto binop_res = parse_binop(stream); + auto binop_res = parse_binop(stream, scope); while (binop_res.ok()) { auto binop = binop_res.unwrap(); - auto rhs = parse_primary_expression(stream).unwrap(); + auto rhs = parse_primary_expression(stream, scope).unwrap(); if (types::operator_precedence(binop) > prev_precedence) { - rhs = parse_rhs(stream, std::move(rhs), types::operator_precedence(binop)); + rhs = parse_rhs(stream, std::move(rhs), types::operator_precedence(binop), scope); } auto binop_expr = new AST::BinaryOperationExpression{ before + stream.metadata(), std::move(lhs), binop, std::move(rhs) }; lhs = std::unique_ptr{ binop_expr }; - binop_res = parse_binop(stream); + binop_res = parse_binop(stream, scope); } return lhs; } - Result, std::string> parse_expression(token::TokenStream& stream) { + Result, std::string> parse_expression(token::TokenStream& stream, Scope& scope) { try { - auto lhs = parse_primary_expression(stream).unwrap(); - return std::unique_ptr{ parse_rhs(stream, std::move(lhs), 0) }; + auto lhs = parse_primary_expression(stream, scope).unwrap(); + return std::unique_ptr{ parse_rhs(stream, std::move(lhs), 0, scope) }; } catch (std::runtime_error& error) { return std::string{ error.what() }; @@ -304,16 +304,16 @@ namespace parsing { - Result, std::string> parse_init_statement(token::TokenStream& stream) { + Result, std::string> parse_init_statement(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; auto before_meta = inner.metadata(); try { - auto ty = parse_type(inner).unwrap(); + auto ty = parse_type(inner, scope).unwrap(); auto name = inner.expect(token::Type::Ident); - auto array_postfix = parse_array_postfix(inner, false); + auto array_postfix = parse_array_postfix(inner, false, scope); while (array_postfix.ok()) { auto postfix = array_postfix.unwrap(); if (postfix) { @@ -326,13 +326,13 @@ namespace parsing { new types::PointerType(ty) }; } - array_postfix = parse_array_postfix(inner, false); + array_postfix = parse_array_postfix(inner, false, scope); } std::optional> expr = {}; if (inner.peek().type == token::Type::Symbol && inner.peek().content == "=") { inner.expect(token::Type::Symbol, "="); - expr = parse_expression(inner).unwrap(); + expr = parse_expression(inner, scope).unwrap(); } inner.expect(token::Type::Symbol, ";"); @@ -346,13 +346,13 @@ namespace parsing { } } - Result, std::string> parse_statement(token::TokenStream& stream) { + Result, std::string> parse_statement(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; auto before_meta = inner.metadata(); try { if (inner.peek().type == token::Type::ReturnKeyword) { inner.next(); - auto expression = parse_expression(inner).unwrap(); + auto expression = parse_expression(inner, scope).unwrap(); inner.expect(token::Type::Symbol, ";"); stream.m_position = inner.m_position; @@ -363,14 +363,14 @@ namespace parsing { else if (inner.peek().type == token::Type::IfKeyword) { inner.next(); inner.expect(token::Type::Symbol, "("); - auto expression = parse_expression(inner).unwrap(); + auto expression = parse_expression(inner, scope).unwrap(); inner.expect(token::Type::Symbol, ")"); - auto then_statement = parse_statement(inner).unwrap(); + auto then_statement = parse_statement(inner, scope).unwrap(); std::optional> else_statement{}; if (inner.peek().type == token::Type::ElseKeyword) { inner.next(); - else_statement = parse_statement(inner).unwrap(); + else_statement = parse_statement(inner, scope).unwrap(); } stream.m_position = inner.m_position; @@ -383,11 +383,11 @@ namespace parsing { }; return std::unique_ptr{ statement }; } - else if (auto init = parse_init_statement(inner); init.ok()) { + else if (auto init = parse_init_statement(inner, scope); init.ok()) { stream.m_position = inner.m_position; return std::unique_ptr{ init.unwrap() }; } - else if (auto expr = parse_expression(inner); expr.ok()) { + else if (auto expr = parse_expression(inner, scope); expr.ok()) { stream.m_position = inner.m_position; stream.expect(token::Type::Symbol, ";"); auto expr_statement = new AST::ExpressionStatement{ before_meta + stream.metadata(), expr.unwrap() }; @@ -404,11 +404,11 @@ namespace parsing { } } - Result, std::string> parse_top_level_statement(token::TokenStream& stream) { + Result, std::string> parse_top_level_statement(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; auto before_meta = inner.metadata(); try { - auto type = parse_type(inner).unwrap(); + auto type = parse_type(inner, scope).unwrap(); auto name_token = inner.expect(token::Type::Ident); inner.expect(token::Type::Symbol, "("); @@ -427,13 +427,13 @@ namespace parsing { break; } - auto param_ty = parse_type(inner).unwrap(); + auto param_ty = parse_type(inner, scope).unwrap(); std::optional param_name{}; if (inner.peek().type == token::Type::Ident) { param_name = inner.expect(token::Type::Ident).content; std::cout << inner.peek().formatted() << std::endl; - auto postfix = parse_array_postfix(inner, true); + auto postfix = parse_array_postfix(inner, true, scope); while (postfix.ok()) { auto array_postfix = postfix.unwrap(); if (array_postfix) { @@ -446,7 +446,7 @@ namespace parsing { new types::PointerType(param_ty) }; } - postfix = parse_array_postfix(inner, true); + postfix = parse_array_postfix(inner, true, scope); } } @@ -455,16 +455,18 @@ namespace parsing { inner.expect(token::Type::Symbol, ")"); + auto inner_scope = parsing::Scope{ scope }; + std::optional>> statements{}; if (inner.peek().content == "{") { inner.expect(token::Type::Symbol, "{"); std::vector> statement_list{}; - auto statement = parse_statement(inner); + auto statement = parse_statement(inner, inner_scope); while (statement.ok()) { statement_list.push_back(statement.unwrap()); - statement = parse_statement(inner); + statement = parse_statement(inner, inner_scope); } statements = std::optional{ std::move(statement_list) }; diff --git a/src/parsing.h b/src/parsing.h index 0722f6d..c274344 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -1,12 +1,19 @@ #ifndef PARSING_H #define PARSING_H +#include + #include "ast.h" #include "result.h" #include "tokens.h" namespace parsing { - Result, std::string> parse_top_level_statement(token::TokenStream& stream); + struct Scope { + std::map> structs; + }; + + Result, std::string> parse_top_level_statement( + token::TokenStream& stream, Scope& scope); } #endif \ No newline at end of file