Skip to content

Commit 8b4a419

Browse files
committed
Added namespace support for global variables and helper exprs
1 parent d81670f commit 8b4a419

File tree

4 files changed

+103
-31
lines changed

4 files changed

+103
-31
lines changed

Diff for: src/lower/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ fn lower_expr(
923923
}
924924
})
925925
}
926-
ExprKind::ResolvedNamedExpression(_name, resolved_expr) => {
926+
ExprKind::ResolvedNamedExpression(resolved_expr) => {
927927
lower_expr(builder, ir_module, resolved_expr, function, resolved_ast)
928928
}
929929
ExprKind::Zeroed(resolved_type) => {

Diff for: src/resolve/error.rs

+6
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ pub enum ResolveErrorKind {
160160
ty: String,
161161
member: String,
162162
},
163+
AmbiguousSymbol {
164+
name: String,
165+
},
163166
Other {
164167
message: String,
165168
},
@@ -412,6 +415,9 @@ impl Display for ResolveErrorKind {
412415
ResolveErrorKind::StaticMemberOfTypeDoesNotExist { ty, member } => {
413416
write!(f, "Static member '{member}' does not exist on type '{ty}'")?;
414417
}
418+
ResolveErrorKind::AmbiguousSymbol { name } => {
419+
write!(f, "Ambiguous symbol '{name}'")?;
420+
}
415421
ResolveErrorKind::Other { message } => {
416422
write!(f, "{}", message)?;
417423
}

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

+95-29
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
use super::{PreferredType, ResolveExprCtx};
22
use crate::{
3+
ast::HelperExpr,
4+
ir::GlobalVarRef,
35
name::{Name, ResolvedName},
46
resolve::{
57
error::{ResolveError, ResolveErrorKind},
68
expr::resolve_expr,
79
Initialized,
810
},
9-
resolved::{self, TypedExpr},
11+
resolved::{self, Type, TypedExpr},
1012
source_files::Source,
1113
};
1214

@@ -49,41 +51,105 @@ pub fn resolve_variable_expr(
4951
let resolved_name = ResolvedName::new(name);
5052

5153
if let Some((resolved_type, reference)) = ctx.global_search_ctx.find_global(&resolved_name) {
52-
return Ok(TypedExpr::new(
53-
resolved_type.clone(),
54-
resolved::Expr::new(
55-
resolved::ExprKind::GlobalVariable(Box::new(resolved::GlobalVariable {
56-
reference: *reference,
57-
resolved_type: resolved_type.clone(),
58-
})),
59-
source,
60-
),
61-
));
54+
return Ok(resolve_global_variable(resolved_type, *reference, source));
6255
}
6356

64-
if let Some(define) = ctx.helper_exprs.get(&resolved_name) {
65-
let TypedExpr {
66-
resolved_type,
67-
expr,
68-
is_initialized,
69-
} = resolve_expr(ctx, &define.value, preferred_type, initialized)?;
70-
71-
return Ok(TypedExpr::new_maybe_initialized(
72-
resolved_type,
73-
resolved::Expr::new(
74-
resolved::ExprKind::ResolvedNamedExpression(name.to_string(), Box::new(expr)),
75-
source,
76-
),
77-
is_initialized,
78-
));
57+
if let Some(helper_expr) = ctx.helper_exprs.get(&resolved_name) {
58+
return resolve_helper_expr(ctx, helper_expr, preferred_type, initialized, source);
7959
}
8060

81-
// TODO: Check if any global variables from imported namespaces match
82-
// TODO: Check if any helper exprs from imported namespaces match
83-
// TODO: They should probably be checked at the same time
61+
if name.namespace.is_empty() {
62+
let mut matches = ctx
63+
.settings
64+
.imported_namespaces
65+
.iter()
66+
.flat_map(|namespace| {
67+
let resolved_name = ResolvedName::new(&Name::new(
68+
Some(namespace.to_string()),
69+
name.basename.to_string(),
70+
));
71+
72+
let global = ctx
73+
.global_search_ctx
74+
.find_global(&resolved_name)
75+
.map(GlobalOrHelper::Global);
76+
77+
let helper_expr = ctx
78+
.helper_exprs
79+
.get(&resolved_name)
80+
.copied()
81+
.map(GlobalOrHelper::HelperExpr);
82+
83+
[global, helper_expr]
84+
})
85+
.flatten();
86+
87+
if let Some(found) = matches.next() {
88+
if matches.next().is_some() {
89+
return Err(ResolveErrorKind::AmbiguousSymbol {
90+
name: name.to_string(),
91+
}
92+
.at(source));
93+
}
94+
95+
return match found {
96+
GlobalOrHelper::Global((ty, reference)) => {
97+
Ok(resolve_global_variable(ty, *reference, source))
98+
}
99+
GlobalOrHelper::HelperExpr(helper_expr) => {
100+
resolve_helper_expr(ctx, helper_expr, preferred_type, initialized, source)
101+
}
102+
};
103+
}
104+
}
84105

85106
Err(ResolveErrorKind::UndeclaredVariable {
86107
name: name.to_string(),
87108
}
88109
.at(source))
89110
}
111+
112+
enum GlobalOrHelper<'a> {
113+
Global((&'a Type, &'a GlobalVarRef)),
114+
HelperExpr(&'a HelperExpr),
115+
}
116+
117+
fn resolve_global_variable(
118+
resolved_type: &Type,
119+
reference: GlobalVarRef,
120+
source: Source,
121+
) -> TypedExpr {
122+
TypedExpr::new(
123+
resolved_type.clone(),
124+
resolved::Expr::new(
125+
resolved::ExprKind::GlobalVariable(Box::new(resolved::GlobalVariable {
126+
reference,
127+
resolved_type: resolved_type.clone(),
128+
})),
129+
source,
130+
),
131+
)
132+
}
133+
134+
fn resolve_helper_expr(
135+
ctx: &mut ResolveExprCtx,
136+
helper_expr: &HelperExpr,
137+
preferred_type: Option<PreferredType>,
138+
initialized: Initialized,
139+
source: Source,
140+
) -> Result<TypedExpr, ResolveError> {
141+
let TypedExpr {
142+
resolved_type,
143+
expr,
144+
is_initialized,
145+
} = resolve_expr(ctx, &helper_expr.value, preferred_type, initialized)?;
146+
147+
return Ok(TypedExpr::new_maybe_initialized(
148+
resolved_type,
149+
resolved::Expr::new(
150+
resolved::ExprKind::ResolvedNamedExpression(Box::new(expr)),
151+
source,
152+
),
153+
is_initialized,
154+
));
155+
}

Diff for: src/resolved/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ pub enum ExprKind {
435435
While(Box<While>),
436436
ArrayAccess(Box<ArrayAccess>),
437437
EnumMemberLiteral(Box<EnumMemberLiteral>),
438-
ResolvedNamedExpression(String, Box<Expr>),
438+
ResolvedNamedExpression(Box<Expr>),
439439
Zeroed(Box<Type>),
440440
InterpreterSyscall(InterpreterSyscallKind, Vec<Expr>),
441441
}

0 commit comments

Comments
 (0)