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::{ | ||||
|     ast::{self, FunctionDefinition, lexer::FullToken, token_stream::TokenRange}, | ||||
|     codegen::intrinsics::get_intrinsic_assoc_functions, | ||||
|     compile_module, | ||||
|     error_raporting::{ErrorModules, ReidError}, | ||||
|     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) => { | ||||
|             for expr in expressions { | ||||
| @ -337,7 +338,7 @@ pub fn analyze_expr( | ||||
|             for expr in parameters { | ||||
|                 analyze_expr(context, source_module, expr, map); | ||||
|             } | ||||
|             let function_autocomplete = source_module | ||||
|             let mut function_autocomplete = source_module | ||||
|                 .associated_functions | ||||
|                 .iter() | ||||
|                 .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()), | ||||
|                 }) | ||||
|                 .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)) => { | ||||
|             analyze_expr(context, source_module, &cond, map); | ||||
|  | ||||
| @ -937,7 +937,8 @@ pub enum DotIndexKind { | ||||
| impl Parse for DotIndexKind { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Self, Error> { | ||||
|         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>() { | ||||
|                 Ok(Self::FunctionCall(FunctionCallExpression { | ||||
|                     name, | ||||
| @ -946,10 +947,18 @@ impl Parse for DotIndexKind { | ||||
|                     is_macro: false, | ||||
|                 })) | ||||
|             } else { | ||||
|                 Ok(Self::StructValueIndex(name, stream.get_range().unwrap())) | ||||
|                 Ok(Self::StructValueIndex(name, stream.get_range_prev().unwrap())) | ||||
|             } | ||||
|         } 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> { | ||||
|         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<'_, '_> { | ||||
|  | ||||
| @ -1,3 +1,5 @@ | ||||
| use std::{collections::HashMap, hash::Hash}; | ||||
| 
 | ||||
| use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; | ||||
| 
 | ||||
| use crate::{ | ||||
| @ -57,6 +59,15 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> { | ||||
|     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> { | ||||
|     if let TypeKind::Array(_, len) = ty { | ||||
|         match name { | ||||
|  | ||||
| @ -73,7 +73,7 @@ use crate::{ | ||||
| }; | ||||
| 
 | ||||
| pub mod ast; | ||||
| mod codegen; | ||||
| pub mod codegen; | ||||
| pub mod error_raporting; | ||||
| pub mod ld; | ||||
| pub mod mir; | ||||
|  | ||||
| @ -727,7 +727,10 @@ impl Expression { | ||||
|                         type_kind.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) { | ||||
|                     let param_len_given = function_call.parameters.len(); | ||||
|  | ||||
| @ -655,9 +655,13 @@ impl Expression { | ||||
|                     .ok_or(ErrorKind::AssocFunctionNotDefined( | ||||
|                         function_call.name.clone(), | ||||
|                         type_kind.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
 | ||||
|                 // expected function parameters (or Unknown types if too
 | ||||
|                 // many were provided)
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user