Skip to content

Commit 6a6613b

Browse files
committed
Implemented parsing for C jump statements
1 parent 8601a62 commit 6a6613b

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

Diff for: src/c/parser/mod.rs

+62-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use super::{
1616
DeclarationSpecifierKind, DeclarationSpecifiers, Declarator, DeclaratorKind,
1717
EnumTypeSpecifier, Enumeration, EnumerationDefinition, EnumerationNamed, Enumerator,
1818
ExprStatement, ExternalDeclaration, FunctionDefinition, FunctionSpecifier, InitDeclarator,
19-
Initializer, Label, LabelKind, Member, MemberDeclaration, MemberDeclarator,
19+
Initializer, JumpStatement, Label, LabelKind, Member, MemberDeclaration, MemberDeclarator,
2020
ParameterDeclaration, ParameterDeclarationCore, ParameterTypeList, Pointer,
2121
SpecifierQualifierList, StaticAssertDeclaration, StorageClassSpecifier, TypeQualifier,
2222
TypeQualifierKind, TypeSpecifier, TypeSpecifierKind, TypeSpecifierQualifier, TypedefName,
@@ -1195,7 +1195,7 @@ impl<'a> Parser<'a> {
11951195
return todo!("handle parsed primary block");
11961196
}
11971197

1198-
if let Ok(_primary_block) = speculate!(self.input, self.parse_jump_block()) {
1198+
if let Ok(_jump_block) = speculate!(self.input, self.parse_jump_statement()) {
11991199
return todo!("handle parsed jump block");
12001200
}
12011201

@@ -1211,8 +1211,66 @@ impl<'a> Parser<'a> {
12111211
todo!("parse_primary_block")
12121212
}
12131213

1214-
fn parse_jump_block(&mut self) -> Result<(), ParseError> {
1215-
todo!("parse_jump_block")
1214+
fn parse_jump_statement(&mut self) -> Result<JumpStatement, ParseError> {
1215+
if self.eat(CTokenKind::GotoKeyword) {
1216+
let Some(label) = self.eat_identifier() else {
1217+
return Err(ParseError::message(
1218+
"Expected label to goto",
1219+
self.input.peek().source,
1220+
));
1221+
};
1222+
1223+
if !self.eat_punctuator(Punctuator::Semicolon) {
1224+
return Err(ParseError::message(
1225+
"Expected ';' after goto statement",
1226+
self.input.peek().source,
1227+
));
1228+
}
1229+
1230+
return Ok(JumpStatement::Goto(label));
1231+
}
1232+
1233+
if self.eat(CTokenKind::ContinueKeyword) {
1234+
if !self.eat_punctuator(Punctuator::Semicolon) {
1235+
return Err(ParseError::message(
1236+
"Expected ';' after continue statement",
1237+
self.input.peek().source,
1238+
));
1239+
}
1240+
1241+
return Ok(JumpStatement::Continue);
1242+
}
1243+
1244+
if self.eat(CTokenKind::BreakKeyword) {
1245+
if !self.eat_punctuator(Punctuator::Semicolon) {
1246+
return Err(ParseError::message(
1247+
"Expected ';' after break statement",
1248+
self.input.peek().source,
1249+
));
1250+
}
1251+
1252+
return Ok(JumpStatement::Break);
1253+
}
1254+
1255+
if self.eat(CTokenKind::ReturnKeyword) {
1256+
let result = (!self.eat_punctuator(Punctuator::Semicolon))
1257+
.then(|| self.parse_expr_multiple())
1258+
.transpose()?;
1259+
1260+
if !self.eat_punctuator(Punctuator::Semicolon) {
1261+
return Err(ParseError::message(
1262+
"Expected ';' after return statement",
1263+
self.input.peek().source,
1264+
));
1265+
}
1266+
1267+
return Ok(JumpStatement::Return(result));
1268+
}
1269+
1270+
Err(ParseError::message(
1271+
"Expected jump statement",
1272+
self.input.peek().source,
1273+
))
12161274
}
12171275

12181276
fn parse_expr_statement(&mut self) -> Result<ExprStatement, ParseError> {

0 commit comments

Comments
 (0)