diff --git a/schala-lang/language/src/parsing/new.rs b/schala-lang/language/src/parsing/new.rs index ac31b1c..7c02a03 100644 --- a/schala-lang/language/src/parsing/new.rs +++ b/schala-lang/language/src/parsing/new.rs @@ -25,31 +25,22 @@ peg::parser! { _ kind:expression_kind() { Expression { id: Default::default(), type_anno: None, kind: kind } } rule expression_kind() -> ExpressionKind = - precedence_expr() + precedence_expr(true) rule expression_kind_no_struct() -> ExpressionKind = - precedence_expr_no_struct() + precedence_expr(false) - rule precedence_expr() -> ExpressionKind = - first:prefix_expr() _ next:(precedence_continuation())* { + rule precedence_expr(struct_ok: bool) -> ExpressionKind = + first:prefix_expr(struct_ok) _ next:(precedence_continuation(struct_ok))* { let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect(); BinopSequence { first, next }.do_precedence() } - rule precedence_continuation() -> (&'input str, ExpressionKind) = - op:operator() _ expr:prefix_expr() _ { (op, expr) } + rule precedence_continuation(struct_ok: bool) -> (&'input str, ExpressionKind) = + op:operator() _ expr:prefix_expr(struct_ok) _ { (op, expr) } - rule precedence_expr_no_struct() -> ExpressionKind = - first:prefix_expr() _ next:(precedence_continuation_no_struct())* { - let next = next.into_iter().map(|(sigil, expr)| (BinOp::from_sigil(sigil), expr)).collect(); - BinopSequence { first, next }.do_precedence() - } - - rule precedence_continuation_no_struct() -> (&'input str, ExpressionKind) = - op:operator() _ expr:prefix_expr_no_struct() _ { (op, expr) } - - rule prefix_expr() -> ExpressionKind = - prefix:prefix()? expr:extended_expr() { + rule prefix_expr(struct_ok: bool) -> ExpressionKind = + prefix:prefix()? expr:extended_expr(struct_ok) { if let Some(p) = prefix { let expr = Expression::new(Default::default(), expr); let prefix = PrefixOp::from_sigil(p); @@ -59,16 +50,6 @@ peg::parser! { } } - rule prefix_expr_no_struct() -> ExpressionKind = - prefix:prefix()? expr:extended_expr_no_struct() { - if let Some(p) = prefix { - let expr = Expression::new(Default::default(), expr); - let prefix = PrefixOp::from_sigil(p); - ExpressionKind::PrefixExp(prefix, Box::new(expr)) - } else { - expr - } - } rule prefix() -> &'input str = $(['+' | '-' | '!' ]) @@ -78,47 +59,52 @@ peg::parser! { quiet!{$( ['+' | '-' | '*' | '/' | '%' | '<' | '>' | '=' | '!' | '$' | '&' | '|' | '?' | '^' | '`']+ )} / expected!("operator") + + rule extended_expr(struct_ok: bool) -> ExpressionKind = + item:extended_expr_ok_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } / + item:extended_expr_no_struct() {? if !struct_ok { Ok(item) } else { Err("!no-struct-allowed") } } + #[cache_left_rec] - rule extended_expr() -> ExpressionKind = - indexee:extended_expr() indexers:index_part() { + rule extended_expr_ok_struct() -> ExpressionKind = + indexee:extended_expr_ok_struct() indexers:index_part() { ExpressionKind::Index { indexee: Box::new(Expression::new(Default::default(), indexee)), indexers, } } / - f:extended_expr() arguments:call_part() { + f:extended_expr_ok_struct() arguments:call_part() { ExpressionKind::Call { f: Box::new(Expression::new(Default::default(), f)), arguments, } } / - expr:extended_expr() "." name:identifier() { ExpressionKind::Access { + expr:extended_expr_ok_struct() "." name:identifier() { ExpressionKind::Access { name: Rc::new(name.to_string()), expr: Box::new(Expression::new(Default::default(),expr)), } } / - primary() + primary(true) #[cache_left_rec] rule extended_expr_no_struct() -> ExpressionKind = - indexee:extended_expr() indexers:index_part() { + indexee:extended_expr_no_struct() indexers:index_part() { ExpressionKind::Index { indexee: Box::new(Expression::new(Default::default(), indexee)), indexers, } } / - f:extended_expr() arguments:call_part() { + f:extended_expr_no_struct() arguments:call_part() { ExpressionKind::Call { f: Box::new(Expression::new(Default::default(), f)), arguments, } } / - expr:extended_expr() "." name:identifier() { ExpressionKind::Access { + expr:extended_expr_no_struct() "." name:identifier() { ExpressionKind::Access { name: Rc::new(name.to_string()), expr: Box::new(Expression::new(Default::default(),expr)), } } / - primary_no_struct() + primary(false) rule index_part() -> Vec = "[" indexers:(expression() ++ ",") "]" { indexers } @@ -136,13 +122,11 @@ peg::parser! { _ expr:expression() _ { InvocationArgument::Positional(expr) } - rule primary_no_struct() -> ExpressionKind = + rule primary(struct_ok: bool) -> ExpressionKind = while_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() / - list_expr() / if_expr() / identifier_expr() - - rule primary() -> ExpressionKind = - while_expr() / float_literal() / nat_literal() / bool_literal() / string_literal() / paren_expr() / - list_expr() / if_expr() / named_struct() / identifier_expr() + list_expr() / if_expr() / + item:named_struct() {? if struct_ok { Ok(item) } else { Err("no-struct-allowed") } } / + identifier_expr() rule while_expr() -> ExpressionKind = "while" _ cond:expression_kind_no_struct()? _ body:block() {