Move ; parsing upper down the line

This commit is contained in:
Sofia 2026-04-28 01:34:52 +03:00
parent 2d004cc5d8
commit 52e43ea1e2
6 changed files with 65 additions and 22 deletions

View File

@ -435,11 +435,10 @@ namespace AST {
std::unique_ptr<Statement> m_loop;
public:
ForStatement(token::Metadata meta,
std::unique_ptr<Statement> init,
std::unique_ptr<Expression> cond,
std::unique_ptr<Expression> after,
std::unique_ptr<Statement> loop,
std::optional<std::unique_ptr<Statement>> else_statement)
std::optional<std::unique_ptr<Statement>> init,
std::optional<std::unique_ptr<Expression>> cond,
std::optional<std::unique_ptr<Expression>> after,
std::unique_ptr<Statement> loop)
: Statement{ meta }
, m_init{ std::move(init) }
, m_cond{ std::move(cond) }

View File

@ -557,7 +557,7 @@ namespace AST {
builder.builder->SetInsertPoint(after_block);
}
void ForStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
void ForStatement::codegen(codegen::Builder& builder, codegen::Scope&, codegen::StackAllocator&) {
if (!builder.block)
return;

View File

@ -510,8 +510,6 @@ namespace parsing {
expr = parse_expression(inner, scope).unwrap();
}
inner.expect(token::Type::Symbol, ";");
stream.m_position = inner.m_position;
auto init = new AST::InitializationStatement{ before_meta + inner.metadata(), std::move(ty), name.content, std::move(expr) };
return std::unique_ptr<AST::InitializationStatement>{ init };
@ -521,19 +519,18 @@ namespace parsing {
}
}
Result<std::unique_ptr<AST::Statement>, std::string> parse_statement(token::TokenStream& stream, Scope& scope) {
Result<std::pair<std::unique_ptr<AST::Statement>, bool>, 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, scope).unwrap();
inner.expect(token::Type::Symbol, ";");
stream.m_position = inner.m_position;
auto ret = new AST::ReturnStatement{ before_meta + stream.metadata(),std::move(expression) };
return std::unique_ptr<AST::Statement>{ ret };
return std::pair{ std::unique_ptr<AST::Statement>{ ret }, true };
}
else if (inner.peek().type == token::Type::IfKeyword) {
inner.next();
@ -541,11 +538,18 @@ namespace parsing {
auto expression = parse_expression(inner, scope).unwrap();
inner.expect(token::Type::Symbol, ")");
auto then_statement = parse_statement(inner, scope).unwrap();
auto then_res = parse_statement(inner, scope).unwrap();
if (then_res.second)
inner.expect(token::Type::Symbol, ";");
auto then_statement = std::move(then_res.first);
std::optional<std::unique_ptr<AST::Statement>> else_statement{};
if (inner.peek().type == token::Type::ElseKeyword) {
inner.next();
else_statement = parse_statement(inner, scope).unwrap();
auto else_res = parse_statement(inner, scope).unwrap();
if (else_res.second)
inner.expect(token::Type::Symbol, ";");
else_statement = std::move(else_res.first);
}
stream.m_position = inner.m_position;
@ -556,17 +560,52 @@ namespace parsing {
std::move(then_statement),
std::move(else_statement)
};
return std::unique_ptr<AST::Statement>{ statement };
return std::pair{ std::unique_ptr<AST::Statement>{ statement }, false };
}
else if (inner.peek().type == token::Type::ForKeyword) {
inner.next();
inner.expect(token::Type::Symbol, "(");
std::optional<std::unique_ptr<AST::Statement>> init;
std::optional<std::unique_ptr<AST::Expression>> cond;
std::optional<std::unique_ptr<AST::Expression>> after;
if (inner.peek().content != ";")
init = parse_statement(inner, scope).unwrap().first;
inner.expect(token::Type::Symbol, ";");
if (inner.peek().content != ";")
cond = parse_expression(inner, scope).unwrap();
inner.expect(token::Type::Symbol, ";");
if (inner.peek().content != ")")
after = parse_expression(inner, scope).unwrap();
inner.expect(token::Type::Symbol, ")");
auto loop_res = parse_statement(inner, scope).unwrap();
if (loop_res.second)
inner.expect(token::Type::Symbol, ";");
auto loop = std::move(loop_res.first);
stream.m_position = inner.m_position;
auto statement = new AST::ForStatement{
before_meta + stream.metadata(),
std::move(init),
std::move(cond),
std::move(after),
std::move(loop),
};
return std::pair{ std::unique_ptr<AST::Statement>{ statement }, false };
}
else if (auto init = parse_init_statement(inner, scope); init.ok()) {
stream.m_position = inner.m_position;
return std::unique_ptr<AST::Statement>{ init.unwrap() };
return std::pair{ std::unique_ptr<AST::Statement>{ init.unwrap() }, true };
}
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() };
return std::unique_ptr<AST::Statement>{ expr_statement };
return std::pair{ std::unique_ptr<AST::Statement>{ expr_statement }, true };
}
else {
throw std::runtime_error("Expected return-keyword");
@ -639,7 +678,10 @@ namespace parsing {
auto statement = parse_statement(inner, inner_scope);
while (statement.ok()) {
statement_list.push_back(statement.unwrap());
auto statement_res = statement.unwrap();
if (statement_res.second)
inner.expect(token::Type::Symbol, ";");
statement_list.push_back(std::move(statement_res.first));
statement = parse_statement(inner, inner_scope);
}

View File

@ -59,6 +59,8 @@ namespace token {
return "If";
case token::Type::ElseKeyword:
return "Else";
case token::Type::ForKeyword:
return "For";
case token::Type::Whitespace:
return "Whitespace";
@ -222,6 +224,9 @@ namespace token {
else if (content == "else") {
type = token::Type::ElseKeyword;
}
else if (content == "for") {
type = token::Type::ForKeyword;
}
tokens.push_back(token::Token{ type, content, meta + content.size() });
}
else if (iswhitespace(c)) {

View File

@ -16,6 +16,7 @@ namespace token {
ReturnKeyword,
IfKeyword,
ElseKeyword,
ForKeyword,
Whitespace,

4
test.c
View File

@ -51,9 +51,5 @@ int main() {
twod_array[0][0] = 50;
printf("2d array: %d!\n", twod_array[0][0]);
for (int counter = 0; counter < 10; counter++) {
printf("counter: %d\n", counter);
}
return 0;
}