Account for intrinsic associated functions with autocomplete
This commit is contained in:
		
							parent
							
								
									a6844b919b
								
							
						
					
					
						commit
						101ee2d8e5
					
				| @ -2,6 +2,7 @@ use std::{collections::HashMap, fmt::format, path::PathBuf}; | |||||||
| 
 | 
 | ||||||
| use reid::{ | use reid::{ | ||||||
|     ast::{self, FunctionDefinition, lexer::FullToken, token_stream::TokenRange}, |     ast::{self, FunctionDefinition, lexer::FullToken, token_stream::TokenRange}, | ||||||
|  |     codegen::intrinsics::get_intrinsic_assoc_functions, | ||||||
|     compile_module, |     compile_module, | ||||||
|     error_raporting::{ErrorModules, ReidError}, |     error_raporting::{ErrorModules, ReidError}, | ||||||
|     mir::{ |     mir::{ | ||||||
| @ -306,7 +307,7 @@ pub fn analyze_expr( | |||||||
|                 _ => {} |                 _ => {} | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             set_autocomplete(map, meta.range.end - 1, autocompletes); |             set_autocomplete(map, meta.range.end, autocompletes); | ||||||
|         } |         } | ||||||
|         mir::ExprKind::Array(expressions) => { |         mir::ExprKind::Array(expressions) => { | ||||||
|             for expr in expressions { |             for expr in expressions { | ||||||
| @ -337,7 +338,7 @@ pub fn analyze_expr( | |||||||
|             for expr in parameters { |             for expr in parameters { | ||||||
|                 analyze_expr(context, source_module, expr, map); |                 analyze_expr(context, source_module, expr, map); | ||||||
|             } |             } | ||||||
|             let function_autocomplete = source_module |             let mut function_autocomplete = source_module | ||||||
|                 .associated_functions |                 .associated_functions | ||||||
|                 .iter() |                 .iter() | ||||||
|                 .filter(|(t, fun)| t == ty && fun.name.starts_with(name)) |                 .filter(|(t, fun)| t == ty && fun.name.starts_with(name)) | ||||||
| @ -346,7 +347,20 @@ pub fn analyze_expr( | |||||||
|                     kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()), |                     kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()), | ||||||
|                 }) |                 }) | ||||||
|                 .collect::<Vec<_>>(); |                 .collect::<Vec<_>>(); | ||||||
|             set_autocomplete(map, meta.range.end, function_autocomplete); |             function_autocomplete.extend( | ||||||
|  |                 get_intrinsic_assoc_functions(ty) | ||||||
|  |                     .iter() | ||||||
|  |                     .filter_map(|(s, f)| f.as_ref().map(|f| (s, f))) | ||||||
|  |                     .filter(|(_, fun)| fun.name.starts_with(name)) | ||||||
|  |                     .map(|(_, fun)| Autocomplete { | ||||||
|  |                         text: fun.name.clone(), | ||||||
|  |                         kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()), | ||||||
|  |                     }) | ||||||
|  |                     .collect::<Vec<_>>(), | ||||||
|  |             ); | ||||||
|  |             dbg!(ty); | ||||||
|  |             dbg!(&source_module.associated_functions); | ||||||
|  |             set_autocomplete(map, meta.range.end, function_autocomplete.clone()); | ||||||
|         } |         } | ||||||
|         mir::ExprKind::If(IfExpression(cond, then_e, else_e)) => { |         mir::ExprKind::If(IfExpression(cond, then_e, else_e)) => { | ||||||
|             analyze_expr(context, source_module, &cond, map); |             analyze_expr(context, source_module, &cond, map); | ||||||
|  | |||||||
| @ -937,7 +937,8 @@ pub enum DotIndexKind { | |||||||
| impl Parse for DotIndexKind { | impl Parse for DotIndexKind { | ||||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { |     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||||
|         stream.expect(Token::Dot)?; |         stream.expect(Token::Dot)?; | ||||||
|         if let Some(Token::Identifier(name)) = stream.next() { |         if let Some(Token::Identifier(name)) = stream.peek() { | ||||||
|  |             stream.next(); // Consume identifer
 | ||||||
|             if let Ok(args) = stream.parse::<FunctionArgs>() { |             if let Ok(args) = stream.parse::<FunctionArgs>() { | ||||||
|                 Ok(Self::FunctionCall(FunctionCallExpression { |                 Ok(Self::FunctionCall(FunctionCallExpression { | ||||||
|                     name, |                     name, | ||||||
| @ -946,10 +947,18 @@ impl Parse for DotIndexKind { | |||||||
|                     is_macro: false, |                     is_macro: false, | ||||||
|                 })) |                 })) | ||||||
|             } else { |             } else { | ||||||
|                 Ok(Self::StructValueIndex(name, stream.get_range().unwrap())) |                 Ok(Self::StructValueIndex(name, stream.get_range_prev().unwrap())) | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             return Err(stream.expected_err("struct index (number)")?); |             if stream.next_is_whitespace() { | ||||||
|  |                 stream.expecting_err_nonfatal("struct index"); | ||||||
|  |                 Ok(Self::StructValueIndex( | ||||||
|  |                     String::new(), | ||||||
|  |                     stream.get_range_prev_single().unwrap(), | ||||||
|  |                 )) | ||||||
|  |             } else { | ||||||
|  |                 Err(stream.expecting_err("struct index")?) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -249,6 +249,18 @@ impl<'a, 'b> TokenStream<'a, 'b> { | |||||||
|     pub fn errors(&self) -> Vec<Error> { |     pub fn errors(&self) -> Vec<Error> { | ||||||
|         self.errors.borrow().clone().clone() |         self.errors.borrow().clone().clone() | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn next_is_whitespace(&self) -> bool { | ||||||
|  |         if let Some(token) = self.tokens.get(self.position) { | ||||||
|  |             if let Token::Whitespace(_) = token.token { | ||||||
|  |                 true | ||||||
|  |             } else { | ||||||
|  |                 false | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             true | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Drop for TokenStream<'_, '_> { | impl Drop for TokenStream<'_, '_> { | ||||||
|  | |||||||
| @ -1,3 +1,5 @@ | |||||||
|  | use std::{collections::HashMap, hash::Hash}; | ||||||
|  | 
 | ||||||
| use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; | use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
| @ -57,6 +59,15 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> { | |||||||
|     intrinsics |     intrinsics | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> HashMap<String, Option<FunctionDefinition>> { | ||||||
|  |     let mut map = HashMap::new(); | ||||||
|  |     map.insert("length".to_owned(), get_intrinsic_assoc_func(ty, "length")); | ||||||
|  |     map.insert("sizeof".to_owned(), get_intrinsic_assoc_func(ty, "sizeof")); | ||||||
|  |     map.insert("malloc".to_owned(), get_intrinsic_assoc_func(ty, "malloc")); | ||||||
|  |     map.insert("null".to_owned(), get_intrinsic_assoc_func(ty, "null")); | ||||||
|  |     map | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDefinition> { | pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDefinition> { | ||||||
|     if let TypeKind::Array(_, len) = ty { |     if let TypeKind::Array(_, len) = ty { | ||||||
|         match name { |         match name { | ||||||
|  | |||||||
| @ -73,7 +73,7 @@ use crate::{ | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| pub mod ast; | pub mod ast; | ||||||
| mod codegen; | pub mod codegen; | ||||||
| pub mod error_raporting; | pub mod error_raporting; | ||||||
| pub mod ld; | pub mod ld; | ||||||
| pub mod mir; | pub mod mir; | ||||||
|  | |||||||
| @ -727,7 +727,10 @@ impl Expression { | |||||||
|                         type_kind.clone(), |                         type_kind.clone(), | ||||||
|                         function_call.name.clone(), |                         function_call.name.clone(), | ||||||
|                     )) |                     )) | ||||||
|                     .ok_or(ErrorKind::FunctionNotDefined(function_call.name.clone())); |                     .ok_or(ErrorKind::AssocFunctionNotDefined( | ||||||
|  |                         function_call.name.clone(), | ||||||
|  |                         type_kind.clone(), | ||||||
|  |                     )); | ||||||
| 
 | 
 | ||||||
|                 if let Some(f) = state.ok(true_function, self.1) { |                 if let Some(f) = state.ok(true_function, self.1) { | ||||||
|                     let param_len_given = function_call.parameters.len(); |                     let param_len_given = function_call.parameters.len(); | ||||||
|  | |||||||
| @ -655,9 +655,13 @@ impl Expression { | |||||||
|                     .ok_or(ErrorKind::AssocFunctionNotDefined( |                     .ok_or(ErrorKind::AssocFunctionNotDefined( | ||||||
|                         function_call.name.clone(), |                         function_call.name.clone(), | ||||||
|                         type_kind.clone(), |                         type_kind.clone(), | ||||||
|                     ))? |                     )) | ||||||
|                     .clone(); |                     .clone(); | ||||||
| 
 | 
 | ||||||
|  |                 let Ok(fn_call) = fn_call else { | ||||||
|  |                     return Ok(type_refs.from_type(&Vague(Unknown)).unwrap()); | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|                 // Infer param expression types and narrow them to the
 |                 // Infer param expression types and narrow them to the
 | ||||||
|                 // expected function parameters (or Unknown types if too
 |                 // expected function parameters (or Unknown types if too
 | ||||||
|                 // many were provided)
 |                 // many were provided)
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user