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