diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 561c979..57ff0bd 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -82,7 +82,7 @@ module_program = { visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } mutable = { "mut" } -unsafe_kw = { "unsafe" } +unsafe_kw = { "unsafe" } // ====================================================== // GENERICS @@ -108,7 +108,7 @@ path_type = { ref_lifetime = { lifetime | unsafe_kw } ref_type = { - "*" ~ ref_lifetime? ~ mutable? ~ type_expr + mutable? ~ ref_lifetime? ~ "&" } dyn_type = { @@ -116,7 +116,7 @@ dyn_type = { } type_expr = { - (path_type | tuple_type | ref_type | dyn_type) + (path_type | tuple_type | dyn_type) ~ ref_type* } lifetime = { @@ -200,15 +200,16 @@ attributes = { // DECLARATION HELPERS // ====================================================== var_decl = { - "let" ~ pattern ~ type_expr? + ("let" | type_expr) ~ pattern } field = { - visibility? ~ identifier ~ type_expr + visibility? ~ type_expr ~ identifier } param = { - pattern ~ type_expr? + (type_expr ~ pattern) + | pattern } field_list = { @@ -286,7 +287,7 @@ class_field = { } self_param = { - (deref_px ~ lifetime?)? ~ mutable? ~ "self" + (ref_px ~ lifetime?)? ~ mutable? ~ "self" } method_args = _{ @@ -333,7 +334,7 @@ trait_decl = { override_kw = { "override" ~ ("(" ~ expr_path ~ ")")? } function_decl = { - visibility? ~ "fn" ~ ("void" | type_expr) ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ override_kw? ~ (block | semicolon) + visibility? ~ ("void" | type_expr) ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ override_kw? ~ (block | semicolon) } // ====================================================== diff --git a/crates/parser/src/parser/common/decl.rs b/crates/parser/src/parser/common/decl.rs index 7a07fb9..acf076d 100644 --- a/crates/parser/src/parser/common/decl.rs +++ b/crates/parser/src/parser/common/decl.rs @@ -3,6 +3,7 @@ use crate::{ ast::*, ast_expr, error::{AstError, IntoErr, collect_recovered}, + parser::consume_rule, }; impl<'a> TryFrom> for VarDeclStmt { @@ -52,8 +53,10 @@ impl<'a> TryFrom> for VarDecl { let mut inner = pair.into_inner(); ast_expr!(VarDecl { + type_: consume_rule(&mut inner, Rule::type_expr) + .map(TypeExpr::try_from) + .transpose(), name: Pattern::try_from(inner.next().unwrap()), - type_: inner.next().map(TypeExpr::try_from).transpose(), }) } @@ -72,8 +75,8 @@ impl<'a> TryFrom> for FieldDecl { ast_expr!(FieldDecl { visibility: Visibility::try_from(&mut inner), - name: Identifier::try_from(inner.next().unwrap()), type_: TypeExpr::try_from(inner.next().unwrap()), + name: Identifier::try_from(inner.next().unwrap()), }) } diff --git a/crates/parser/src/parser/common/types.rs b/crates/parser/src/parser/common/types.rs index 3d2fa2b..54d749d 100644 --- a/crates/parser/src/parser/common/types.rs +++ b/crates/parser/src/parser/common/types.rs @@ -2,7 +2,7 @@ use crate::{ Rule, ast::*, ast_ensure, ast_expr, - error::{AstError, AstResult, IntoErr, collect_recovered}, + error::{AstError, IntoErr, collect_recovered}, parser::{consume_rule, listen_rule}, }; @@ -15,7 +15,27 @@ impl<'a> TryFrom> for TypeExpr { match rule { Rule::generic => Self::try_from(inner.next().unwrap()), - Rule::type_expr => inner.next().unwrap().try_into(), + Rule::type_expr => { + let mut inner = inner; + + let mut ty = TypeExpr::try_from(inner.next().unwrap())?; + + for ref_pair in inner { + let mut ref_inner = ref_pair.into_inner(); + + ty = TypeExpr::Ref { + lifetime: consume_rule(&mut ref_inner, Rule::ref_lifetime) + .map(|v| v.into_inner().next().map(Lifetime::try_from)) + .unwrap_or_default() + .transpose() + .get()?, + mutable: listen_rule(&mut ref_inner, Rule::mutable), + ty: Box::new(ty), + }; + } + + Ok(ty) + } Rule::lifetime => ast_expr!(TypeExpr::Lifetime(inner.next().unwrap().try_into())), Rule::tuple_type => ast_expr!(TypeExpr::Tuple(collect_recovered(inner))), @@ -26,16 +46,6 @@ impl<'a> TryFrom> for TypeExpr { )) } - Rule::ref_type => { - ast_expr!(TypeExpr::Ref { - lifetime: consume_rule(&mut inner, Rule::ref_lifetime) - .map(|v| v.into_inner().next().map(Lifetime::try_from)) - .unwrap_or_default() - .transpose(), - mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult, - ty: TypeExpr::try_from(inner.next().unwrap()).map(Box::new), - }) - } Rule::dyn_type => { ast_expr!(TypeExpr::Dyn( TypeExpr::try_from(inner.next().unwrap()).map(Box::new), diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 10b519e..2bac071 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -27,7 +27,7 @@ impl<'a> TryFrom> for FunctionDecl { let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| { let mut param_inner = param.into_inner(); - let is_ref = listen_rule(&mut param_inner, Rule::deref_px); + let is_ref = listen_rule(&mut param_inner, Rule::ref_px); let lifetime = consume_rule(&mut param_inner, Rule::lifetime); let mutable = listen_rule(&mut param_inner, Rule::mutable); let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));