Parse break and continue

This commit is contained in:
Sofia 2026-04-30 20:06:15 +03:00
parent 2b8d55b004
commit 9f3f64e6bd
4 changed files with 32 additions and 3 deletions

View File

@ -523,6 +523,18 @@ namespace parsing {
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::BreakKeyword) {
inner.next();
stream.m_position = inner.m_position;
auto ret = new AST::BreakStatement{ before_meta + stream.metadata() };
return std::pair{ std::unique_ptr<AST::Statement>{ret}, true };
}
if (inner.peek().type == token::Type::ContinueKeyword) {
inner.next();
stream.m_position = inner.m_position;
auto ret = new AST::ContinueStatement{ before_meta + stream.metadata() };
return std::pair{ std::unique_ptr<AST::Statement>{ret}, true };
}
if (inner.peek().type == token::Type::Symbol && inner.peek().content == "{") { if (inner.peek().type == token::Type::Symbol && inner.peek().content == "{") {
inner.expect(token::Type::Symbol, "{"); inner.expect(token::Type::Symbol, "{");
std::vector<std::unique_ptr<AST::Statement>> statements{}; std::vector<std::unique_ptr<AST::Statement>> statements{};
@ -534,10 +546,10 @@ namespace parsing {
statements.push_back(std::move(res.first)); statements.push_back(std::move(res.first));
} }
inner.expect(token::Type::Symbol, "}"); inner.expect(token::Type::Symbol, "}");
auto ret = new AST::CompoundStatement{ before_meta + stream.metadata(),std::move(statements) };
stream.m_position = inner.m_position; stream.m_position = inner.m_position;
auto ret = new AST::CompoundStatement{ before_meta + stream.metadata(),std::move(statements) };
return std::pair{ std::unique_ptr<AST::Statement>{ret}, false }; return std::pair{ std::unique_ptr<AST::Statement>{ret}, false };
} }
if (inner.peek().type == token::Type::ReturnKeyword) { if (inner.peek().type == token::Type::ReturnKeyword) {

View File

@ -63,6 +63,10 @@ namespace token {
return "For"; return "For";
case token::Type::WhileKeyword: case token::Type::WhileKeyword:
return "While"; return "While";
case token::Type::BreakKeyword:
return "Break";
case token::Type::ContinueKeyword:
return "Continue";
case token::Type::Whitespace: case token::Type::Whitespace:
return "Whitespace"; return "Whitespace";
@ -257,6 +261,12 @@ namespace token {
else if (content == "while") { else if (content == "while") {
type = token::Type::WhileKeyword; type = token::Type::WhileKeyword;
} }
else if (content == "break") {
type = token::Type::BreakKeyword;
}
else if (content == "continue") {
type = token::Type::ContinueKeyword;
}
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)) {

View File

@ -18,6 +18,8 @@ namespace token {
ElseKeyword, ElseKeyword,
ForKeyword, ForKeyword,
WhileKeyword, WhileKeyword,
BreakKeyword,
ContinueKeyword,
Whitespace, Whitespace,
Comment, Comment,

9
test.c
View File

@ -57,12 +57,17 @@ int main() {
printf("2d array: %d!\n", twod_array[0][0]); printf("2d array: %d!\n", twod_array[0][0]);
// Test for-loops // Test for-loops
for (int counter = 0; counter < 10; counter++) for (int counter = 0; counter < 10; counter++) {
if (counter < 5)
continue;
printf("for-counter: %d\n", counter); printf("for-counter: %d\n", counter);
}
// Test while-loops // Test while-loops
int counter = 0; int counter = 0;
while (counter < 10) { while (1) {
if (counter > 10)
break;
printf("while-counter: %d\n", counter++); printf("while-counter: %d\n", counter++);
} }