diff --git a/schala-lang/src/parsing/combinator.rs b/schala-lang/src/parsing/combinator.rs index c8deb5a..4f76873 100644 --- a/schala-lang/src/parsing/combinator.rs +++ b/schala-lang/src/parsing/combinator.rs @@ -86,7 +86,7 @@ pub fn program(input: Span) -> ParseResult { map( tuple(( many0(statement_delimiter), - separated_list0(statement_delimiter, statement), + separated_list0(many1(statement_delimiter), statement), many0(statement_delimiter), )), |(_, items, _)| items.into(), @@ -105,7 +105,7 @@ fn block_template<'a, O>( tok(char('{')), tuple(( many0(statement_delimiter), - separated_list0(statement_delimiter, input_parser), + separated_list0(many1(statement_delimiter), input_parser), many0(statement_delimiter), )), tok(char('}')), @@ -124,11 +124,23 @@ fn statement(input: Span) -> ParseResult { let id = fresh_id(&input); let (rest, kind) = context( "Parsing-statement", - alt((map(declaration, StatementKind::Declaration), map(expression, StatementKind::Expression))), + alt(( + map(flow, StatementKind::Flow), + map(declaration, StatementKind::Declaration), + map(expression, StatementKind::Expression), + )), )(input)?; Ok((rest, Statement { id, location, kind })) } +fn flow(input: Span) -> ParseResult { + alt(( + map(kw("continue"), |_| FlowControl::Continue), + map(kw("break"), |_| FlowControl::Break), + map(preceded(kw("return"), opt(expression)), FlowControl::Return), + ))(input) +} + fn declaration(input: Span) -> ParseResult { alt((binding, type_decl, func, annotation, module, interface, implementation))(input) } @@ -489,10 +501,14 @@ fn record_block(input: Span) -> ParseResult, Expression)>> { fn lambda_expr(input: Span) -> ParseResult { alt(( - map(preceded(tok(char('\\')), tuple((formal_params, opt(type_anno), block))), - |(params, type_anno, body)| ExpressionKind::Lambda { params, type_anno, body }), - map(preceded(tok(char('\\')), tuple((formal_param, opt(type_anno), block))), - |(param, type_anno, body)| ExpressionKind::Lambda { params: vec![param], type_anno, body }), + map( + preceded(tok(char('\\')), tuple((formal_params, opt(type_anno), block))), + |(params, type_anno, body)| ExpressionKind::Lambda { params, type_anno, body }, + ), + map( + preceded(tok(char('\\')), tuple((formal_param, opt(type_anno), block))), + |(param, type_anno, body)| ExpressionKind::Lambda { params: vec![param], type_anno, body }, + ), ))(input) } diff --git a/schala-lang/src/parsing/test.rs b/schala-lang/src/parsing/test.rs index 76519ca..3ab2b6c 100644 --- a/schala-lang/src/parsing/test.rs +++ b/schala-lang/src/parsing/test.rs @@ -1289,7 +1289,7 @@ if (45, "panda", false, 2.2) { fn flow_control() { use ExpressionKind::*; - // This is an incorrect program, but shoudl parse correctly. + // This is an incorrect program, but should parse correctly. let source = r#" fn test() { let a = 10; @@ -1299,7 +1299,7 @@ fn flow_control() { return 10; }"#; - assert_ast!( + assert_ast_comb!( source, vec![fn_decl( Signature { name: rc("test"), operator: false, type_anno: None, params: vec![] }, @@ -1337,7 +1337,7 @@ fn blocks() { fn foo() { } } }"#; - let block = parser.block(source); + let block = parser.block_comb(source); assert_eq!( block.unwrap(), vec![decl(Declaration::FuncDecl(