Skip to content

Commit 7be20b7

Browse files
committed
Added simple namespace inference during function resolution
1 parent 77fda01 commit 7be20b7

File tree

4 files changed

+67
-27
lines changed

4 files changed

+67
-27
lines changed

Diff for: .github/workflows/remoteBuild.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ jobs:
8383
run: |
8484
cargo build --release --target x86_64-pc-windows-gnu
8585
env:
86-
CFLAGS: -static-libstdc++
87-
CXXFLAGS: -static-libstdc++
86+
CFLAGS: -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread
87+
CXXFLAGS: -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread
8888
LLVM_SYS_181_PREFIX: C:\msys64\mingw64
8989
zstd_DIR: C:\msys64\mingw64
9090
zstd_LIBRARY: C:\msys64\mingw64\lib\libzstd.a

Diff for: src/resolve/error.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::function_search_ctx::FindFunctionError;
12
use crate::{
23
show::Show,
34
source_files::{Source, SourceFiles},
@@ -30,6 +31,7 @@ pub enum ResolveErrorKind {
3031
},
3132
FailedToFindFunction {
3233
name: String,
34+
reason: FindFunctionError,
3335
},
3436
UndeclaredVariable {
3537
name: String,
@@ -197,9 +199,12 @@ impl Display for ResolveErrorKind {
197199
value
198200
)?;
199201
}
200-
ResolveErrorKind::FailedToFindFunction { name } => {
201-
write!(f, "Failed to find function '{}'", name)?;
202-
}
202+
ResolveErrorKind::FailedToFindFunction { name, reason } => match reason {
203+
FindFunctionError::NotDefined => write!(f, "Failed to find function '{}'", name)?,
204+
FindFunctionError::Ambiguous => {
205+
write!(f, "Multiple possibilities for function '{}'", name)?
206+
}
207+
},
203208
ResolveErrorKind::UndeclaredVariable { name } => {
204209
write!(f, "Undeclared variable '{}'", name)?;
205210
}

Diff for: src/resolve/expr/call.rs

+8-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use super::{resolve_expr, PreferredType, ResolveExprCtx};
22
use crate::{
33
ast::{self, ConformBehavior},
4-
name::ResolvedName,
54
resolve::{
65
conform::{conform_expr, to_default::conform_expr_to_default, ConformMode},
76
error::{ResolveError, ResolveErrorKind},
@@ -23,24 +22,15 @@ pub fn resolve_call_expr(
2322
.at(source));
2423
}
2524

26-
eprintln!("warning: function call name resolution not fully implemented yet");
27-
let resolved_name = if !call.function_name.namespace.is_empty() {
28-
ResolvedName::Project(
29-
format!(
30-
"{}{}",
31-
call.function_name.namespace, call.function_name.basename
32-
)
33-
.into_boxed_str(),
34-
)
35-
} else {
36-
ResolvedName::Project(call.function_name.basename.clone().into_boxed_str())
37-
};
38-
39-
let Some(function_ref) = ctx.function_search_ctx.find_function(&resolved_name) else {
40-
return Err(ResolveErrorKind::FailedToFindFunction {
41-
name: call.function_name.to_string(),
25+
let function_ref = match ctx.function_search_ctx.find_function(&call.function_name) {
26+
Ok(function_ref) => function_ref,
27+
Err(reason) => {
28+
return Err(ResolveErrorKind::FailedToFindFunction {
29+
name: call.function_name.to_string(),
30+
reason,
31+
}
32+
.at(source));
4233
}
43-
.at(source));
4434
};
4535

4636
let function = ctx.resolved_ast.functions.get(function_ref).unwrap();

Diff for: src/resolve/function_search_ctx.rs

+49-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,67 @@
1-
use crate::{name::ResolvedName, resolved};
1+
use crate::{
2+
name::{Name, ResolvedName},
3+
resolved,
4+
};
25
use std::collections::HashMap;
36

47
#[derive(Clone, Debug)]
58
pub struct FunctionSearchCtx {
69
pub available: HashMap<ResolvedName, Vec<resolved::FunctionRef>>,
10+
pub imported_namespaces: Vec<Box<str>>,
11+
}
12+
13+
#[derive(Clone, Debug)]
14+
pub enum FindFunctionError {
15+
NotDefined,
16+
Ambiguous,
717
}
818

919
impl FunctionSearchCtx {
1020
pub fn new() -> Self {
1121
Self {
1222
available: Default::default(),
23+
// TODO: Make this value user-specified
24+
imported_namespaces: vec!["io".to_string().into_boxed_str()],
1325
}
1426
}
1527

16-
pub fn find_function(&self, name: &ResolvedName) -> Option<resolved::FunctionRef> {
17-
self.available
18-
.get(name)
28+
pub fn find_function(&self, name: &Name) -> Result<resolved::FunctionRef, FindFunctionError> {
29+
eprintln!("warning: function call name resolution not fully implemented yet");
30+
31+
let resolved_name = if !name.namespace.is_empty() {
32+
ResolvedName::Project(format!("{}{}", name.namespace, name.basename).into_boxed_str())
33+
} else {
34+
ResolvedName::Project(name.basename.clone().into_boxed_str())
35+
};
36+
37+
if let Some(found) = self
38+
.available
39+
.get(&resolved_name)
1940
.and_then(|list| list.first())
2041
.copied()
42+
{
43+
return Ok(found);
44+
}
45+
46+
if name.namespace.is_empty() {
47+
let mut matches = self.imported_namespaces.iter().filter_map(|namespace| {
48+
self.available
49+
.get(&ResolvedName::Project(
50+
format!("{}/{}", namespace, name.basename).into_boxed_str(),
51+
))
52+
.and_then(|list| list.first())
53+
.copied()
54+
});
55+
56+
if let Some(found) = matches.next() {
57+
if matches.next().is_some() {
58+
return Err(FindFunctionError::Ambiguous);
59+
} else {
60+
return Ok(found);
61+
}
62+
}
63+
}
64+
65+
Err(FindFunctionError::NotDefined)
2166
}
2267
}

0 commit comments

Comments
 (0)