diff --git a/schala-lang/language/src/parsing/new.rs b/schala-lang/language/src/parsing/new.rs index e149b46..bb89645 100644 --- a/schala-lang/language/src/parsing/new.rs +++ b/schala-lang/language/src/parsing/new.rs @@ -6,6 +6,12 @@ fn rc_string(s: &str) -> Rc { Rc::new(s.to_string()) } +enum ExtendedPart<'a> { + Index(Vec), + Accessor(&'a str), + Call(Vec), +} + peg::parser! { pub grammar schala_parser() for str { @@ -207,52 +213,33 @@ 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") } } + primary:primary(struct_ok) parts:(extended_expr_part()*) { + let mut expression = Expression::new(Default::default(), primary); + for part in parts.into_iter() { + let kind = match part { + ExtendedPart::Index(indexers) => { + ExpressionKind::Index { indexee: Box::new(expression), indexers } + }, + ExtendedPart::Accessor(name) => { + let name = rc_string(name); + ExpressionKind::Access { name, expr: Box::new(expression) } + }, + ExtendedPart::Call(arguments) => { + ExpressionKind::Call { f: Box::new(expression), arguments } + } + }; - #[cache_left_rec] - 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_ok_struct() arguments:call_part() { - ExpressionKind::Call { - f: Box::new(Expression::new(Default::default(), f)), - arguments, + expression = Expression::new(Default::default(), kind); } - } / - expr:extended_expr_ok_struct() "." name:identifier() { ExpressionKind::Access { - name: Rc::new(name.to_string()), - expr: Box::new(Expression::new(Default::default(),expr)), - } } / - primary(true) + expression.kind + } - #[cache_left_rec] - rule extended_expr_no_struct() -> ExpressionKind = - indexee:extended_expr_no_struct() indexers:index_part() { - ExpressionKind::Index { - indexee: Box::new(Expression::new(Default::default(), indexee)), - indexers, - } - } / - f:extended_expr_no_struct() arguments:call_part() { - ExpressionKind::Call { - f: Box::new(Expression::new(Default::default(), f)), - arguments, - } - - } / - expr:extended_expr_no_struct() "." name:identifier() { ExpressionKind::Access { - name: Rc::new(name.to_string()), - expr: Box::new(Expression::new(Default::default(),expr)), - } } / - primary(false) + rule extended_expr_part() -> ExtendedPart<'input> = + indexers:index_part() { ExtendedPart::Index(indexers) } / + arguments:call_part() { ExtendedPart::Call(arguments) } / + "." name:identifier() { ExtendedPart::Accessor(name) } rule index_part() -> Vec = "[" indexers:(expression() ++ ",") "]" { indexers }