@@ -16,7 +16,7 @@ use super::{
16
16
DeclarationSpecifierKind , DeclarationSpecifiers , Declarator , DeclaratorKind ,
17
17
EnumTypeSpecifier , Enumeration , EnumerationDefinition , EnumerationNamed , Enumerator ,
18
18
ExprStatement , ExternalDeclaration , FunctionDefinition , FunctionSpecifier , InitDeclarator ,
19
- Initializer , Label , LabelKind , Member , MemberDeclaration , MemberDeclarator ,
19
+ Initializer , JumpStatement , Label , LabelKind , Member , MemberDeclaration , MemberDeclarator ,
20
20
ParameterDeclaration , ParameterDeclarationCore , ParameterTypeList , Pointer ,
21
21
SpecifierQualifierList , StaticAssertDeclaration , StorageClassSpecifier , TypeQualifier ,
22
22
TypeQualifierKind , TypeSpecifier , TypeSpecifierKind , TypeSpecifierQualifier , TypedefName ,
@@ -1195,7 +1195,7 @@ impl<'a> Parser<'a> {
1195
1195
return todo ! ( "handle parsed primary block" ) ;
1196
1196
}
1197
1197
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 ( ) ) {
1199
1199
return todo ! ( "handle parsed jump block" ) ;
1200
1200
}
1201
1201
@@ -1211,8 +1211,66 @@ impl<'a> Parser<'a> {
1211
1211
todo ! ( "parse_primary_block" )
1212
1212
}
1213
1213
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
+ ) )
1216
1274
}
1217
1275
1218
1276
fn parse_expr_statement ( & mut self ) -> Result < ExprStatement , ParseError > {
0 commit comments