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