Move ; parsing upper down the line
This commit is contained in:
parent
2d004cc5d8
commit
52e43ea1e2
@ -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) }
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -16,6 +16,7 @@ namespace token {
|
||||
ReturnKeyword,
|
||||
IfKeyword,
|
||||
ElseKeyword,
|
||||
ForKeyword,
|
||||
|
||||
Whitespace,
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user