From c7f1b81c9dee1d2194d70b997b3dd92598c6a3a8 Mon Sep 17 00:00:00 2001 From: sofia Date: Sun, 3 Aug 2025 01:33:52 +0300 Subject: [PATCH] Improve associated functions so you can now call them on numbers too --- reid-lsp/src/analysis.rs | 1 + reid/src/ast/parse.rs | 24 +++++++++++++++++++----- reid/src/ast/token_stream.rs | 4 ++-- reid/src/mir/typecheck/typecheck.rs | 3 ++- reid/src/mir/typecheck/typeinference.rs | 10 ++++++---- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/reid-lsp/src/analysis.rs b/reid-lsp/src/analysis.rs index 6f90eec..6f1d9c3 100644 --- a/reid-lsp/src/analysis.rs +++ b/reid-lsp/src/analysis.rs @@ -358,6 +358,7 @@ pub fn analyze_expr( }) .collect::>(), ); + set_autocomplete(map, meta.range.start, function_autocomplete.clone()); set_autocomplete(map, meta.range.end, function_autocomplete.clone()); } mir::ExprKind::If(IfExpression(cond, then_e, else_e)) => { diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index a0e5073..324282d 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -175,6 +175,20 @@ impl Parse for AssociatedFunctionCall { let ty = stream.parse()?; stream.expect(Token::Colon)?; stream.expect(Token::Colon)?; + + if stream.next_is_whitespace() { + stream.expecting_err_nonfatal("associated function name"); + return Ok(AssociatedFunctionCall( + ty, + FunctionCallExpression { + name: String::new(), + params: Vec::new(), + range: stream.get_range_prev_curr().unwrap(), + is_macro: false, + }, + )); + } + match stream.parse() { Ok(fn_call) => Ok(AssociatedFunctionCall(ty, fn_call)), _ => { @@ -187,7 +201,7 @@ impl Parse for AssociatedFunctionCall { FunctionCallExpression { name: fn_name, params: Vec::new(), - range: stream.get_range_prev_single().unwrap(), + range: stream.get_range_prev_curr().unwrap(), is_macro: false, }, )) @@ -198,7 +212,7 @@ impl Parse for AssociatedFunctionCall { FunctionCallExpression { name: String::new(), params: Vec::new(), - range: stream.get_range_prev_single().unwrap(), + range: stream.get_range_prev_curr().unwrap(), is_macro: false, }, )) @@ -660,11 +674,11 @@ impl Parse for ImportStatement { let mut import_list = Vec::new(); if let Some(Token::Identifier(name)) = stream.next() { - import_list.push((name, stream.get_range_prev_single().unwrap())); + import_list.push((name, stream.get_range_prev_curr().unwrap())); while stream.expect(Token::Colon).is_ok() && stream.expect(Token::Colon).is_ok() { if let Some(Token::Identifier(name)) = stream.peek() { stream.next(); // Consume identifier - import_list.push((name, stream.get_range_prev_single().unwrap())); + import_list.push((name, stream.get_range_prev_curr().unwrap())); } else { stream.expected_err_nonfatal("identifier"); break; @@ -954,7 +968,7 @@ impl Parse for DotIndexKind { stream.expecting_err_nonfatal("struct index"); Ok(Self::StructValueIndex( String::new(), - stream.get_range_prev_single().unwrap(), + stream.get_range_prev_curr().unwrap(), )) } else { Err(stream.expecting_err("struct index")?) diff --git a/reid/src/ast/token_stream.rs b/reid/src/ast/token_stream.rs index f043459..a139398 100644 --- a/reid/src/ast/token_stream.rs +++ b/reid/src/ast/token_stream.rs @@ -216,8 +216,8 @@ impl<'a, 'b> TokenStream<'a, 'b> { } /// Gets range of the previous token only. - pub fn get_range_prev_single(&self) -> Option { - self.ref_position.as_ref().map(|ref_pos| TokenRange { + pub fn get_range_prev_curr(&self) -> Option { + Some(TokenRange { start: self.previous_token(self.position).0, end: self.previous_token(self.position).0, }) diff --git a/reid/src/mir/typecheck/typecheck.rs b/reid/src/mir/typecheck/typecheck.rs index 45a4748..036dba0 100644 --- a/reid/src/mir/typecheck/typecheck.rs +++ b/reid/src/mir/typecheck/typecheck.rs @@ -721,6 +721,7 @@ impl Expression { expr.resolve_ref(typerefs).cast_into(type_kind) } ExprKind::AssociatedFunctionCall(type_kind, function_call) => { + *type_kind = type_kind.or_default().unwrap(); let true_function = state .scope .get_associated_function(&pass::AssociatedFunctionKey( @@ -732,7 +733,7 @@ impl Expression { type_kind.clone(), )); - if let Some(f) = state.ok(true_function, self.1) { + if let Some(f) = state.ok(true_function, function_call.meta) { let param_len_given = function_call.parameters.len(); let param_len_expected = f.params.len(); diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index 4f2d10b..2827540 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -636,10 +636,12 @@ impl Expression { } } } else { - let ExprKind::Borrow(val, _) = &first_param.0 else { - panic!() - }; - *first_param = *val.clone(); + if let ExprKind::Borrow(val, _) = &first_param.0 { + *first_param = *val.clone(); + } + if let TypeKind::Borrow(inner_ty, _) = type_kind { + *type_kind = *inner_ty.clone(); + } } if !is_mutable {