diff --git a/examples/generics.reid b/examples/generics.reid new file mode 100644 index 0000000..3c91fde --- /dev/null +++ b/examples/generics.reid @@ -0,0 +1,12 @@ +// Arithmetic, function calls and imports! + +fn test(value: T) -> T { + return value; +} + +fn main() -> u32 { + let value = 0b110; + let other = 0o17; + + return value * other + 7 * -value; +} \ No newline at end of file diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 4f265da..7cf4444 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -162,6 +162,7 @@ impl BinaryOperator { pub struct FunctionCallExpression { pub name: String, pub params: Vec, + pub generics: Vec, pub range: TokenRange, pub is_macro: bool, } @@ -192,6 +193,7 @@ pub struct FunctionDefinition(pub FunctionSignature, pub bool, pub Block, pub To #[derive(Debug, Clone)] pub struct FunctionSignature { pub name: String, + pub generics: Vec, pub documentation: Option, pub self_kind: SelfKind, pub params: Vec<(String, Type, TokenRange)>, diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 72eaf1f..06a85db 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -182,6 +182,7 @@ impl Parse for AssociatedFunctionCall { ty, FunctionCallExpression { name: String::new(), + generics: Vec::new(), params: Vec::new(), range: stream.get_range_prev_curr().unwrap(), is_macro: false, @@ -200,6 +201,7 @@ impl Parse for AssociatedFunctionCall { ty, FunctionCallExpression { name: fn_name, + generics: Vec::new(), params: Vec::new(), range: stream.get_range_prev_curr().unwrap(), is_macro: false, @@ -211,6 +213,7 @@ impl Parse for AssociatedFunctionCall { ty, FunctionCallExpression { name: String::new(), + generics: Vec::new(), params: Vec::new(), range: stream.get_range_prev_curr().unwrap(), is_macro: false, @@ -591,7 +594,8 @@ impl Parse for FunctionCallExpression { let args = stream.parse::()?; Ok(FunctionCallExpression { name, - params: args.0, + generics: args.0, + params: args.1, range: stream.get_range().unwrap(), is_macro, }) @@ -602,10 +606,23 @@ impl Parse for FunctionCallExpression { } #[derive(Debug)] -pub struct FunctionArgs(Vec); +pub struct FunctionArgs(Vec, Vec); impl Parse for FunctionArgs { fn parse(mut stream: TokenStream) -> Result { + let mut generics: Vec = Vec::new(); + if let Some(Token::LessThan) = stream.peek() { + stream.next(); + if let Ok(ty) = stream.parse() { + generics.push(ty); + while let Some(Token::Comma) = stream.peek() { + stream.next(); + generics.push(stream.parse()?); + } + } + stream.expect(Token::GreaterThan)?; + } + stream.expect(Token::ParenOpen)?; let mut params = Vec::new(); @@ -618,7 +635,7 @@ impl Parse for FunctionArgs { } stream.expect(Token::ParenClose)?; - Ok(FunctionArgs(params)) + Ok(FunctionArgs(generics, params)) } } @@ -780,6 +797,18 @@ impl Parse for SelfParam { impl Parse for FunctionSignature { fn parse(mut stream: TokenStream) -> Result { if let Some(Token::Identifier(name)) = stream.next() { + let mut generics = Vec::new(); + + if let Some(Token::LessThan) = stream.peek() { + stream.next(); + while let Some(Token::Identifier(ident)) = stream.peek() { + stream.next(); + generics.push(ident); + } + + stream.expect(Token::GreaterThan)?; + } + stream.expect(Token::ParenOpen)?; let mut params = Vec::new(); @@ -814,6 +843,7 @@ impl Parse for FunctionSignature { Ok(FunctionSignature { name, + generics, documentation: None, params, self_kind, @@ -961,7 +991,8 @@ impl Parse for DotIndexKind { if let Ok(args) = stream.parse::() { Ok(Self::FunctionCall(FunctionCallExpression { name, - params: args.0, + generics: args.0, + params: args.1, range: stream.get_range_prev().unwrap(), is_macro: false, })) diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 77a8fae..bfb6687 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -44,8 +44,7 @@ impl ast::Module { let def = mir::FunctionDefinition { name: signature.name.clone(), documentation: signature.documentation.clone(), - // TODO generics parsing - generics: Vec::new(), + generics: signature.generics.clone(), linkage_name: None, is_pub: false, is_imported: false, @@ -383,8 +382,7 @@ impl ast::Expression { ), ast::ExpressionKind::FunctionCall(fn_call_expr) => mir::ExprKind::FunctionCall(mir::FunctionCall { name: fn_call_expr.name.clone(), - // TODO generics parsing - generics: Vec::new(), + generics: fn_call_expr.generics.iter().map(|g| g.0.into_mir(module_id)).collect(), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), parameters: fn_call_expr.params.iter().map(|e| e.process(module_id)).collect(), meta: fn_call_expr.range.as_meta(module_id), @@ -474,8 +472,7 @@ impl ast::Expression { ty.0.into_mir(module_id), mir::FunctionCall { name: fn_call_expr.name.clone(), - // TODO generics parsing - generics: Vec::new(), + generics: fn_call_expr.generics.iter().map(|g| g.0.into_mir(module_id)).collect(), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), parameters: fn_call_expr.params.iter().map(|e| e.process(module_id)).collect(), meta: fn_call_expr.range.as_meta(module_id), @@ -499,8 +496,7 @@ impl ast::Expression { mir::TypeKind::Vague(mir::VagueType::Unknown), mir::FunctionCall { name: fn_call_expr.name.clone(), - // TODO generics parsing - generics: Vec::new(), + generics: fn_call_expr.generics.iter().map(|g| g.0.into_mir(module_id)).collect(), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), parameters: params, meta: fn_call_expr.range.as_meta(module_id),