Skip to content

Commit

Permalink
Added simple namespace inference during function resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacShelton committed Sep 20, 2024
1 parent 77fda01 commit 7be20b7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 27 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/remoteBuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ jobs:
run: |
cargo build --release --target x86_64-pc-windows-gnu
env:
CFLAGS: -static-libstdc++
CXXFLAGS: -static-libstdc++
CFLAGS: -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread
CXXFLAGS: -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread
LLVM_SYS_181_PREFIX: C:\msys64\mingw64
zstd_DIR: C:\msys64\mingw64
zstd_LIBRARY: C:\msys64\mingw64\lib\libzstd.a
Expand Down
11 changes: 8 additions & 3 deletions src/resolve/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::function_search_ctx::FindFunctionError;
use crate::{
show::Show,
source_files::{Source, SourceFiles},
Expand Down Expand Up @@ -30,6 +31,7 @@ pub enum ResolveErrorKind {
},
FailedToFindFunction {
name: String,
reason: FindFunctionError,
},
UndeclaredVariable {
name: String,
Expand Down Expand Up @@ -197,9 +199,12 @@ impl Display for ResolveErrorKind {
value
)?;
}
ResolveErrorKind::FailedToFindFunction { name } => {
write!(f, "Failed to find function '{}'", name)?;
}
ResolveErrorKind::FailedToFindFunction { name, reason } => match reason {
FindFunctionError::NotDefined => write!(f, "Failed to find function '{}'", name)?,
FindFunctionError::Ambiguous => {
write!(f, "Multiple possibilities for function '{}'", name)?
}
},
ResolveErrorKind::UndeclaredVariable { name } => {
write!(f, "Undeclared variable '{}'", name)?;
}
Expand Down
26 changes: 8 additions & 18 deletions src/resolve/expr/call.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::{resolve_expr, PreferredType, ResolveExprCtx};
use crate::{
ast::{self, ConformBehavior},
name::ResolvedName,
resolve::{
conform::{conform_expr, to_default::conform_expr_to_default, ConformMode},
error::{ResolveError, ResolveErrorKind},
Expand All @@ -23,24 +22,15 @@ pub fn resolve_call_expr(
.at(source));
}

eprintln!("warning: function call name resolution not fully implemented yet");
let resolved_name = if !call.function_name.namespace.is_empty() {
ResolvedName::Project(
format!(
"{}{}",
call.function_name.namespace, call.function_name.basename
)
.into_boxed_str(),
)
} else {
ResolvedName::Project(call.function_name.basename.clone().into_boxed_str())
};

let Some(function_ref) = ctx.function_search_ctx.find_function(&resolved_name) else {
return Err(ResolveErrorKind::FailedToFindFunction {
name: call.function_name.to_string(),
let function_ref = match ctx.function_search_ctx.find_function(&call.function_name) {
Ok(function_ref) => function_ref,
Err(reason) => {
return Err(ResolveErrorKind::FailedToFindFunction {
name: call.function_name.to_string(),
reason,
}
.at(source));
}
.at(source));
};

let function = ctx.resolved_ast.functions.get(function_ref).unwrap();
Expand Down
53 changes: 49 additions & 4 deletions src/resolve/function_search_ctx.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,67 @@
use crate::{name::ResolvedName, resolved};
use crate::{
name::{Name, ResolvedName},
resolved,
};
use std::collections::HashMap;

#[derive(Clone, Debug)]
pub struct FunctionSearchCtx {
pub available: HashMap<ResolvedName, Vec<resolved::FunctionRef>>,
pub imported_namespaces: Vec<Box<str>>,
}

#[derive(Clone, Debug)]
pub enum FindFunctionError {
NotDefined,
Ambiguous,
}

impl FunctionSearchCtx {
pub fn new() -> Self {
Self {
available: Default::default(),
// TODO: Make this value user-specified
imported_namespaces: vec!["io".to_string().into_boxed_str()],
}
}

pub fn find_function(&self, name: &ResolvedName) -> Option<resolved::FunctionRef> {
self.available
.get(name)
pub fn find_function(&self, name: &Name) -> Result<resolved::FunctionRef, FindFunctionError> {
eprintln!("warning: function call name resolution not fully implemented yet");

let resolved_name = if !name.namespace.is_empty() {
ResolvedName::Project(format!("{}{}", name.namespace, name.basename).into_boxed_str())
} else {
ResolvedName::Project(name.basename.clone().into_boxed_str())
};

if let Some(found) = self
.available
.get(&resolved_name)
.and_then(|list| list.first())
.copied()
{
return Ok(found);
}

if name.namespace.is_empty() {
let mut matches = self.imported_namespaces.iter().filter_map(|namespace| {
self.available
.get(&ResolvedName::Project(
format!("{}/{}", namespace, name.basename).into_boxed_str(),
))
.and_then(|list| list.first())
.copied()
});

if let Some(found) = matches.next() {
if matches.next().is_some() {
return Err(FindFunctionError::Ambiguous);
} else {
return Ok(found);
}
}
}

Err(FindFunctionError::NotDefined)
}
}

0 comments on commit 7be20b7

Please sign in to comment.