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;
|
std::unique_ptr<Statement> m_loop;
|
||||||
public:
|
public:
|
||||||
ForStatement(token::Metadata meta,
|
ForStatement(token::Metadata meta,
|
||||||
std::unique_ptr<Statement> init,
|
std::optional<std::unique_ptr<Statement>> init,
|
||||||
std::unique_ptr<Expression> cond,
|
std::optional<std::unique_ptr<Expression>> cond,
|
||||||
std::unique_ptr<Expression> after,
|
std::optional<std::unique_ptr<Expression>> after,
|
||||||
std::unique_ptr<Statement> loop,
|
std::unique_ptr<Statement> loop)
|
||||||
std::optional<std::unique_ptr<Statement>> else_statement)
|
|
||||||
: Statement{ meta }
|
: Statement{ meta }
|
||||||
, m_init{ std::move(init) }
|
, m_init{ std::move(init) }
|
||||||
, m_cond{ std::move(cond) }
|
, m_cond{ std::move(cond) }
|
||||||
|
|||||||
@ -557,7 +557,7 @@ namespace AST {
|
|||||||
builder.builder->SetInsertPoint(after_block);
|
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)
|
if (!builder.block)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@ -510,8 +510,6 @@ namespace parsing {
|
|||||||
expr = parse_expression(inner, scope).unwrap();
|
expr = parse_expression(inner, scope).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.expect(token::Type::Symbol, ";");
|
|
||||||
|
|
||||||
stream.m_position = inner.m_position;
|
stream.m_position = inner.m_position;
|
||||||
auto init = new AST::InitializationStatement{ before_meta + inner.metadata(), std::move(ty), name.content, std::move(expr) };
|
auto init = new AST::InitializationStatement{ before_meta + inner.metadata(), std::move(ty), name.content, std::move(expr) };
|
||||||
return std::unique_ptr<AST::InitializationStatement>{ init };
|
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 };
|
token::TokenStream inner{ stream };
|
||||||
auto before_meta = inner.metadata();
|
auto before_meta = inner.metadata();
|
||||||
try {
|
try {
|
||||||
if (inner.peek().type == token::Type::ReturnKeyword) {
|
if (inner.peek().type == token::Type::ReturnKeyword) {
|
||||||
inner.next();
|
inner.next();
|
||||||
auto expression = parse_expression(inner, scope).unwrap();
|
auto expression = parse_expression(inner, scope).unwrap();
|
||||||
inner.expect(token::Type::Symbol, ";");
|
|
||||||
|
|
||||||
stream.m_position = inner.m_position;
|
stream.m_position = inner.m_position;
|
||||||
|
|
||||||
auto ret = new AST::ReturnStatement{ before_meta + stream.metadata(),std::move(expression) };
|
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) {
|
else if (inner.peek().type == token::Type::IfKeyword) {
|
||||||
inner.next();
|
inner.next();
|
||||||
@ -541,11 +538,18 @@ namespace parsing {
|
|||||||
auto expression = parse_expression(inner, scope).unwrap();
|
auto expression = parse_expression(inner, scope).unwrap();
|
||||||
inner.expect(token::Type::Symbol, ")");
|
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{};
|
std::optional<std::unique_ptr<AST::Statement>> else_statement{};
|
||||||
if (inner.peek().type == token::Type::ElseKeyword) {
|
if (inner.peek().type == token::Type::ElseKeyword) {
|
||||||
inner.next();
|
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;
|
stream.m_position = inner.m_position;
|
||||||
@ -556,17 +560,52 @@ namespace parsing {
|
|||||||
std::move(then_statement),
|
std::move(then_statement),
|
||||||
std::move(else_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()) {
|
else if (auto init = parse_init_statement(inner, scope); init.ok()) {
|
||||||
stream.m_position = inner.m_position;
|
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()) {
|
else if (auto expr = parse_expression(inner, scope); expr.ok()) {
|
||||||
stream.m_position = inner.m_position;
|
stream.m_position = inner.m_position;
|
||||||
stream.expect(token::Type::Symbol, ";");
|
|
||||||
auto expr_statement = new AST::ExpressionStatement{ before_meta + stream.metadata(), expr.unwrap() };
|
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 {
|
else {
|
||||||
throw std::runtime_error("Expected return-keyword");
|
throw std::runtime_error("Expected return-keyword");
|
||||||
@ -639,7 +678,10 @@ namespace parsing {
|
|||||||
|
|
||||||
auto statement = parse_statement(inner, inner_scope);
|
auto statement = parse_statement(inner, inner_scope);
|
||||||
while (statement.ok()) {
|
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);
|
statement = parse_statement(inner, inner_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,8 @@ namespace token {
|
|||||||
return "If";
|
return "If";
|
||||||
case token::Type::ElseKeyword:
|
case token::Type::ElseKeyword:
|
||||||
return "Else";
|
return "Else";
|
||||||
|
case token::Type::ForKeyword:
|
||||||
|
return "For";
|
||||||
|
|
||||||
case token::Type::Whitespace:
|
case token::Type::Whitespace:
|
||||||
return "Whitespace";
|
return "Whitespace";
|
||||||
@ -222,6 +224,9 @@ namespace token {
|
|||||||
else if (content == "else") {
|
else if (content == "else") {
|
||||||
type = token::Type::ElseKeyword;
|
type = token::Type::ElseKeyword;
|
||||||
}
|
}
|
||||||
|
else if (content == "for") {
|
||||||
|
type = token::Type::ForKeyword;
|
||||||
|
}
|
||||||
tokens.push_back(token::Token{ type, content, meta + content.size() });
|
tokens.push_back(token::Token{ type, content, meta + content.size() });
|
||||||
}
|
}
|
||||||
else if (iswhitespace(c)) {
|
else if (iswhitespace(c)) {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ namespace token {
|
|||||||
ReturnKeyword,
|
ReturnKeyword,
|
||||||
IfKeyword,
|
IfKeyword,
|
||||||
ElseKeyword,
|
ElseKeyword,
|
||||||
|
ForKeyword,
|
||||||
|
|
||||||
Whitespace,
|
Whitespace,
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user