diff --git a/parser/src/ast/expr.rs b/parser/src/ast/expr.rs index 6695f99..257448d 100644 --- a/parser/src/ast/expr.rs +++ b/parser/src/ast/expr.rs @@ -65,7 +65,7 @@ pub enum Pattern { #[derive(Debug, Clone, Serialize)] pub enum Postfix { - FieldAccess(Identifier, Option), + FieldAccess(Identifier, Option), Call(Vec), MacroCall(String), StructCall(Vec<(Identifier, Expression)>), @@ -79,7 +79,7 @@ pub enum Prefix { Ref, RefMut, Deref, - New(Option), + New(Option), Not, Neg, } @@ -87,8 +87,17 @@ pub enum Prefix { #[derive(Debug, Clone, Serialize)] pub struct ExprPathSegment { pub ident: Identifier, - pub generics: Option, + pub generics: Option, } #[derive(Debug, Clone, Serialize)] pub struct ExprPath(pub Vec); + +#[derive(Debug, Clone, Serialize)] +pub struct Generics(pub Vec); + +#[derive(Debug, Clone, Serialize)] +pub enum Generic { + Lifetime(Identifier), + Type(TypeExpr), +} diff --git a/parser/src/ast/top_level.rs b/parser/src/ast/top_level.rs index 518b368..04644ca 100644 --- a/parser/src/ast/top_level.rs +++ b/parser/src/ast/top_level.rs @@ -74,6 +74,7 @@ pub enum GenericDecl { Lifetime(Identifier), Type(Identifier, Vec), } + #[derive(Debug, Clone, Serialize)] pub enum EnumItem { Named(Identifier), diff --git a/parser/src/parser/common/expr.rs b/parser/src/parser/common/expr.rs index e1c94cc..312a406 100644 --- a/parser/src/parser/common/expr.rs +++ b/parser/src/parser/common/expr.rs @@ -159,7 +159,7 @@ impl<'a> TryFrom> for Postfix { Rule::field_px => { ast_expr!(Postfix::FieldAccess( inner.next().unwrap().try_into(), - inner.next().map(GenericsDecl::try_from).transpose() + inner.next().map(Generics::try_from).transpose() )) } @@ -209,7 +209,7 @@ impl<'a> TryFrom> for ExprPathSegment { ast_ensure!(pair, Rule::expr_path_segment => { ast_expr!(ExprPathSegment { ident: Identifier::try_from(inner.next().unwrap()), - generics: inner.next().map(GenericsDecl::try_from).transpose(), + generics: inner.next().map(Generics::try_from).transpose(), }) }) } diff --git a/parser/src/parser/common/types.rs b/parser/src/parser/common/types.rs index 2757c8e..840ae4d 100644 --- a/parser/src/parser/common/types.rs +++ b/parser/src/parser/common/types.rs @@ -119,3 +119,35 @@ impl<'a> TryFrom> for GenericDecl { }) } } + +impl<'a> TryFrom> for Generics { + type Error = AstError<'a, Self>; + + fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { + let inner = pair.clone().into_inner(); + + ast_ensure!(pair, Rule::generics => { + ast_expr!(Generics(collect_recovered(inner))) + }) + } +} + +impl<'a> TryFrom> for Generic { + type Error = AstError<'a, Self>; + + fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { + let mut inner = pair.clone().into_inner(); + + ast_ensure!(pair, Rule::generic => { + if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) { + ast_expr!(Generic::Lifetime( + pair.into_inner().next().unwrap().try_into(), + )) + } else { + ast_expr!(Generic::Type( + inner.next().unwrap().try_into() + )) + } + }) + } +} diff --git a/src/codegen.rs b/src/codegen.rs index 62f17cd..0f1c7e4 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,8 +1,8 @@ use mist_parser::ast::{ Attribute, BinaryOp, Block, ClassItem, EnumItem, ExprPath, ExprPathSegment, Expression, - FieldDecl, FunctionDecl, GenericDecl, GenericsDecl, Identifier, ImplDecl, Literal, Path, - Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, TypeExpr, - TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, + FieldDecl, FunctionDecl, Generic, GenericDecl, Generics, GenericsDecl, Identifier, ImplDecl, + Literal, Path, Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, + TypeExpr, TypeExprKind, TypePostfix, VarDecl, VarDeclStmt, Visibility, }; // --------------------------------------------------------------------------- @@ -923,6 +923,32 @@ impl GetRust for (bool, &GenericDecl) { } } +impl GetRust for Generics { + fn get_rust(&self) -> String { + if self.0.len() == 0 { + String::new() + } else { + format!( + "<{}>", + self.0 + .iter() + .map(Generic::get_rust) + .collect::>() + .join(", ") + ) + } + } +} + +impl GetRust for Generic { + fn get_rust(&self) -> String { + match &self { + Self::Lifetime(name) => format!("'{}", name.get_rust()), + Self::Type(ty) => ty.get_rust(), + } + } +} + impl GetRust for FieldDecl { fn get_rust(&self) -> String { format!(