diff --git a/parser/src/ast.rs b/parser/src/ast.rs index ac6b1f0..8ecb25e 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -98,7 +98,13 @@ pub enum TopLevelKind { } #[derive(Debug, Clone, Serialize, Default)] -pub struct Generics(pub Vec<(Identifier, Vec)>); +pub struct Generics(pub Vec); + +#[derive(Debug, Clone, Serialize)] +pub enum Generic { + Lifetime(Identifier), + Type(Identifier, Vec), +} #[derive(Debug, Clone, Serialize)] pub enum Pattern { diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index c557e5d..5a31967 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -55,7 +55,7 @@ var = { "var" } // ====================================================== // GENERICS // ====================================================== -generic = { identifier ~ (":" ~ static_path ~ ("+" ~ static_path)*)? } +generic = { lifetime | (identifier ~ (":" ~ type_expr_param ~ ("+" ~ type_expr_param)*)?) } generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" } // ====================================================== @@ -67,7 +67,7 @@ tuple_type = { } path_type = { - static_path ~ ("<" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ">")? + static_path ~ ("<" ~ (type_expr_param ~ ("," ~ type_expr_param)*)? ~ ">")? } ref_type = { @@ -78,6 +78,15 @@ type_expr = { (path_type | tuple_type) ~ ref_type* } +lifetime = { + "'" ~ identifier +} + +type_expr_param = { + type_expr + | lifetime +} + // ====================================================== // LITERALS // ====================================================== diff --git a/parser/src/lib.rs b/parser/src/lib.rs index fa01570..1996de7 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -238,10 +238,14 @@ impl From> for Generics { inner .map(|pair| { let mut inner = pair.into_inner(); - ( - Identifier::from(inner.next().unwrap()), - inner.map(Path::from).collect(), - ) + if let Some(pair) = consume_rule(&mut inner, Rule::lifetime) { + Generic::Lifetime(Identifier::from(pair.into_inner().next().unwrap())) + } else { + Generic::Type( + Identifier::from(inner.next().unwrap()), + inner.map(TypeExpr::from).collect(), + ) + } }) .collect(), ), diff --git a/src/codegen.rs b/src/codegen.rs index 78299c7..a107cc2 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -721,20 +721,24 @@ impl GetRust for Generics { "<{}>", self.0 .iter() - .map(|generic| generic.0.get_rust() - + &(if generic.1.len() == 0 { - String::new() - } else { - format!( - ": {}", - generic - .1 - .iter() - .map(Path::get_rust) - .collect::>() - .join("+") - ) - })) + .map(|generic| match generic { + parser::ast::Generic::Lifetime(name) => format!("'{}", name.get_rust()), + parser::ast::Generic::Type(name, requirements) => { + name.get_rust() + + &(if requirements.len() == 0 { + String::new() + } else { + format!( + ": {}", + requirements + .iter() + .map(TypeExpr::get_rust) + .collect::>() + .join("+") + ) + }) + } + }) .collect::>() .join(", ") ) diff --git a/test/src/main.mist b/test/src/main.mist index 602dd59..f7e1a08 100644 --- a/test/src/main.mist +++ b/test/src/main.mist @@ -2,6 +2,8 @@ mod my_class; use ; use ; +struct Test<'a> {} + void main() { var my_class = new MyClass("World"); my_class.greet();