Skip to content

Commit

Permalink
Refactored and cleaned up some additional top-level resolution code
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacShelton committed Nov 3, 2024
1 parent 8b11a08 commit fe5ade6
Show file tree
Hide file tree
Showing 17 changed files with 484 additions and 408 deletions.
6 changes: 3 additions & 3 deletions src/resolve/ctx.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use super::{function_search_ctx::FunctionSearchCtx, job::FuncJob};
use super::{function_haystack::FunctionHaystack, job::FuncJob};
use crate::{resolved, workspace::fs::FsNodeId};
use indexmap::IndexMap;
use std::collections::{HashMap, VecDeque};

pub struct ResolveCtx {
pub jobs: VecDeque<FuncJob>,
pub function_search_ctxs: IndexMap<FsNodeId, FunctionSearchCtx>,
pub function_haystacks: IndexMap<FsNodeId, FunctionHaystack>,
pub public_functions: HashMap<FsNodeId, HashMap<String, Vec<resolved::FunctionRef>>>,
pub types_in_modules: HashMap<FsNodeId, HashMap<String, resolved::TypeDecl>>,
pub globals_in_modules: HashMap<FsNodeId, HashMap<String, resolved::GlobalVarDecl>>,
Expand All @@ -16,7 +16,7 @@ impl ResolveCtx {
pub fn new() -> Self {
Self {
jobs: Default::default(),
function_search_ctxs: Default::default(),
function_haystacks: Default::default(),
public_functions: HashMap::new(),
types_in_modules: HashMap::new(),
globals_in_modules: HashMap::new(),
Expand Down
2 changes: 1 addition & 1 deletion src/resolve/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::function_search_ctx::FindFunctionError;
use super::function_haystack::FindFunctionError;
use crate::{
resolved::UnaliasError,
show::Show,
Expand Down
51 changes: 25 additions & 26 deletions src/resolve/expr/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,33 +238,32 @@ pub fn resolve_call_expr(
}
}

let function_ref = match ctx.function_search_ctx.find_function(
ctx,
&call.function_name,
&arguments[..],
source,
) {
Ok(function_ref) => function_ref,
Err(reason) => {
let args = arguments
.iter()
.map(|arg| arg.resolved_type.to_string())
.collect_vec();

let signature = format!("{}({})", call.function_name, args.join(", "));

let almost_matches = ctx
.function_search_ctx
.find_function_almost_matches(ctx, &call.function_name);

return Err(ResolveErrorKind::FailedToFindFunction {
signature,
reason,
almost_matches,
let function_ref =
match ctx
.function_haystack
.find(ctx, &call.function_name, &arguments[..], source)
{
Ok(function_ref) => function_ref,
Err(reason) => {
let args = arguments
.iter()
.map(|arg| arg.resolved_type.to_string())
.collect_vec();

let signature = format!("{}({})", call.function_name, args.join(", "));

let almost_matches = ctx
.function_haystack
.find_near_matches(ctx, &call.function_name);

return Err(ResolveErrorKind::FailedToFindFunction {
signature,
reason,
almost_matches,
}
.at(source));
}
.at(source));
}
};
};

let function = ctx.resolved_ast.functions.get(function_ref).unwrap();
let return_type = function.return_type.clone();
Expand Down
8 changes: 4 additions & 4 deletions src/resolve/expr/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn resolve_conditional_expr(
let mut branches_without_else = Vec::with_capacity(conditions.len());

for (expr, block) in conditions.iter() {
ctx.variable_search_ctx.begin_scope();
ctx.variable_haystack.begin_scope();
let condition = resolve_expr(ctx, expr, preferred_type, Initialized::Require)?;

let stmts = resolve_stmts(ctx, &block.stmts)?;
Expand All @@ -46,15 +46,15 @@ pub fn resolve_conditional_expr(
block: resolved::Block::new(stmts),
});

ctx.variable_search_ctx.end_scope();
ctx.variable_haystack.end_scope();
}

let mut otherwise = otherwise
.as_ref()
.map(|otherwise| {
ctx.variable_search_ctx.begin_scope();
ctx.variable_haystack.begin_scope();
let maybe_block = resolve_stmts(ctx, &otherwise.stmts).map(resolved::Block::new);
ctx.variable_search_ctx.end_scope();
ctx.variable_haystack.end_scope();
maybe_block
})
.transpose()?;
Expand Down
2 changes: 1 addition & 1 deletion src/resolve/expr/declare_assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn resolve_declare_assign_expr(
.variables
.add_variable(value.resolved_type.clone(), true);

ctx.variable_search_ctx
ctx.variable_haystack
.put(&declare_assign.name, value.resolved_type.clone(), key);

Ok(TypedExpr::new(
Expand Down
12 changes: 6 additions & 6 deletions src/resolve/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use super::{
conform::{conform_expr_or_error, ConformMode},
destination::resolve_expr_to_destination,
error::ResolveError,
function_search_ctx::FunctionSearchCtx,
variable_search_ctx::VariableSearchCtx,
function_haystack::FunctionHaystack,
variable_haystack::VariableHaystack,
Initialized, ResolveTypeCtx,
};
use crate::{
Expand All @@ -46,8 +46,8 @@ use std::collections::HashMap;

pub struct ResolveExprCtx<'a, 'b> {
pub resolved_ast: &'b mut resolved::Ast<'a>,
pub function_search_ctx: &'b FunctionSearchCtx,
pub variable_search_ctx: VariableSearchCtx,
pub function_haystack: &'b FunctionHaystack,
pub variable_haystack: VariableHaystack,
pub resolved_function_ref: Option<resolved::FunctionRef>,
pub settings: &'b Settings,
pub public_functions: &'b HashMap<FsNodeId, HashMap<String, Vec<resolved::FunctionRef>>>,
Expand Down Expand Up @@ -320,7 +320,7 @@ pub fn resolve_expr(
resolve_conditional_expr(ctx, conditional, preferred_type, source)
}
ast::ExprKind::While(while_loop) => {
ctx.variable_search_ctx.begin_scope();
ctx.variable_haystack.begin_scope();

let expr = resolve_expr(
ctx,
Expand All @@ -340,7 +340,7 @@ pub fn resolve_expr(
.expr;

let block = resolved::Block::new(resolve_stmts(ctx, &while_loop.block.stmts)?);
ctx.variable_search_ctx.end_scope();
ctx.variable_haystack.end_scope();

Ok(TypedExpr::new(
resolved::TypeKind::Void.at(source),
Expand Down
4 changes: 2 additions & 2 deletions src/resolve/expr/short_circuiting_binary_operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn resolve_short_circuiting_binary_operation_expr(
.at(source)
})?;

ctx.variable_search_ctx.begin_scope();
ctx.variable_haystack.begin_scope();

let right = resolve_expr(
ctx,
Expand All @@ -70,7 +70,7 @@ pub fn resolve_short_circuiting_binary_operation_expr(
.at(source)
})?;

ctx.variable_search_ctx.end_scope();
ctx.variable_haystack.end_scope();

Ok(TypedExpr::new(
local_bool_type,
Expand Down
2 changes: 1 addition & 1 deletion src/resolve/expr/variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn resolve_variable_expr(
) -> Result<TypedExpr, ResolveError> {
if let Some(variable) = name
.as_plain_str()
.and_then(|name| ctx.variable_search_ctx.find_variable(name))
.and_then(|name| ctx.variable_haystack.find(name))
{
if let Some(function) = ctx.resolved_function_ref.map(|function_ref| {
ctx.resolved_ast
Expand Down
132 changes: 132 additions & 0 deletions src/resolve/function_body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use super::{
ctx::ResolveCtx, error::ResolveError, expr::ResolveExprCtx, job::FuncJob, stmt::resolve_stmts,
type_ctx::ResolveTypeCtx, variable_haystack::VariableHaystack,
};
use crate::{
ast::{self, AstWorkspace},
ir::FunctionRef,
resolved,
workspace::fs::FsNodeId,
};

pub fn resolve_function_bodies(
ctx: &mut ResolveCtx,
resolved_ast: &mut resolved::Ast,
ast_workspace: &AstWorkspace,
) -> Result<(), ResolveError> {
while let Some(job) = ctx.jobs.pop_front() {
match job {
FuncJob::Regular(real_file_id, function_index, resolved_function_ref) => {
let module_file_id = ast_workspace
.get_owning_module(real_file_id)
.unwrap_or(real_file_id);

// NOTE: This module should already have a function search context
let function_haystack = ctx
.function_haystacks
.get(&module_file_id)
.expect("function search context to exist for file");

let ast_file = ast_workspace
.files
.get(&real_file_id)
.expect("file referenced by job to exist");

let ast_function = ast_file
.functions
.get(function_index)
.expect("function referenced by job to exist");

let mut variable_haystack = VariableHaystack::new();

{
for parameter in ast_function.parameters.required.iter() {
let type_ctx = ResolveTypeCtx::new(
&resolved_ast,
module_file_id,
real_file_id,
&ctx.types_in_modules,
);

let resolved_type = type_ctx.resolve(&parameter.ast_type)?;

let function = resolved_ast
.functions
.get_mut(resolved_function_ref)
.unwrap();

let variable_key = function.variables.add_parameter(resolved_type.clone());

variable_haystack.put(parameter.name.clone(), resolved_type, variable_key);
}
}

let file = ast_workspace
.files
.get(&real_file_id)
.expect("referenced file exists");

let settings = &ast_workspace.settings[file.settings.unwrap_or_default().0];

let resolved_stmts = {
let mut ctx = ResolveExprCtx {
resolved_ast,
function_haystack,
variable_haystack,
resolved_function_ref: Some(resolved_function_ref),
settings,
public_functions: &ctx.public_functions,
types_in_modules: &ctx.types_in_modules,
globals_in_modules: &ctx.globals_in_modules,
helper_exprs_in_modules: &mut ctx.helper_exprs_in_modules,
module_fs_node_id: module_file_id,
physical_fs_node_id: real_file_id,
};

resolve_stmts(&mut ctx, &ast_function.stmts)?
};

let resolved_function = resolved_ast
.functions
.get_mut(resolved_function_ref)
.expect("resolved function head to exist");

resolved_function.stmts = resolved_stmts;
}
}
}

Ok(())
}

fn resolve_parameter_variables(
ctx: &mut ResolveCtx,
resolved_ast: &mut resolved::Ast,
module_file_id: FsNodeId,
physical_file_id: FsNodeId,
ast_function: &ast::Function,
resolved_function_ref: FunctionRef,
) -> Result<VariableHaystack, ResolveError> {
let mut variable_haystack = VariableHaystack::new();

for parameter in ast_function.parameters.required.iter() {
let type_ctx = ResolveTypeCtx::new(
&resolved_ast,
module_file_id,
physical_file_id,
&ctx.types_in_modules,
);

let resolved_type = type_ctx.resolve(&parameter.ast_type)?;

let function = resolved_ast
.functions
.get_mut(resolved_function_ref)
.unwrap();

let key = function.variables.add_parameter(resolved_type.clone());
variable_haystack.put(parameter.name.clone(), resolved_type, key);
}

Ok(variable_haystack)
}
Loading

0 comments on commit fe5ade6

Please sign in to comment.