Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
WIP: support deeper module paths
Browse files Browse the repository at this point in the history
  • Loading branch information
yaahc committed Feb 23, 2024
1 parent 5297339 commit 728db10
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 7 deletions.
3 changes: 3 additions & 0 deletions src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,9 @@ impl Codegen {
}
}
}
AstNode::NamespacedLookup { .. } => {
self.codegen_node(*item, local_inferences, output)
}
_ => {
panic!("unsupported namespace lookup")
}
Expand Down
72 changes: 65 additions & 7 deletions src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,6 @@ pub struct Scope {
allow_unsafe: bool,
}

#[derive(Debug)]
pub struct Module {
scope: Scope,
}

impl Scope {
pub fn new() -> Scope {
Scope {
Expand Down Expand Up @@ -185,6 +180,14 @@ impl Scope {
None
}

fn find_module(&self, module: ModuleId) -> Option<&Module> {
todo!()
}
}

#[derive(Debug)]
pub struct Module {
scope: Scope,
}

pub struct Typechecker {
Expand Down Expand Up @@ -2384,15 +2387,34 @@ impl Typechecker {
}
}

#[instrument(skip(self))]
pub fn typecheck_namespaced_lookup_in_module(
&mut self,
namespace: NodeId,
item: NodeId,
local_inferences: &mut Vec<TypeId>,
module: ModuleId,
) -> TypeId {
let module = self.compiler.get_module(module);
if let Some(module_id) = self.find_module_in_module(namespace, module) {
self.typecheck_namespaced_item_lookup(namespace, module_id, item, local_inferences)
} else if let Some(type_id) = self.find_type_in_module(namespace, module) {
self.typecheck_namespaced_type_lookup(namespace, type_id, item, local_inferences)
} else {
self.error("could not find namespace", namespace);
VOID_TYPE_ID
}
}

// enter the module's scope then recurse and call typecheck_namespaced_lookup?
fn typecheck_namespaced_item_lookup(
&mut self,
namespace: NodeId,
module: ModuleId,
module_id: ModuleId,
item: NodeId,
local_inferences: &mut Vec<TypeId>,
) -> TypeId {
let module = self.compiler.get_module(module);
let module = self.compiler.get_module(module_id);
let node = self.compiler.get_node(item).clone();
match &node {
AstNode::Call { head, args } => {
Expand All @@ -2405,13 +2427,17 @@ impl Typechecker {
);
let fun_id = module.scope.find_fun(name);
if let Some(fun_id) = fun_id {
debug!(?fun_id, "found {name}", name = std::str::from_utf8(name).unwrap());
self.typecheck_call_with_fun_id(*head, fun_id, args, None, local_inferences)
} else {
debug!(?node);
self.error("could not find item in namespace", namespace);
VOID_TYPE_ID
}
}
AstNode::NamespacedLookup { namespace, item } => {
self.typecheck_namespaced_lookup_in_module(*namespace, *item, local_inferences, module_id)
}
_ => {
debug!(?node);
self.error("could not find item in namespace", namespace);
Expand Down Expand Up @@ -3129,6 +3155,7 @@ impl Typechecker {
if file_name
== unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(name) }
{
debug!(?module_id, "found module");
return Some(*module_id);
}
}
Expand All @@ -3139,6 +3166,33 @@ impl Typechecker {
None
}

#[instrument(skip(self))]
pub fn find_module_in_module(&self, namespace: NodeId, module: &Module) -> Option<ModuleId> {
let name = self.compiler.get_source(namespace);
debug!(
"searching for module \"{name}\"",
name = std::str::from_utf8(name).unwrap()
);
let scope = &module.scope;
for (path, module_id) in scope.modules.iter() {
trace!(?path, ?module_id);
// definitely incorrect, but we currently only have one path segment
// this needs to somehow be able to resolve the path against all the segments of the path
for path in path.ancestors() {
if let Some(file_name) = path.file_stem() {
if file_name
== unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(name) }
{
debug!(?module_id, "found module");
return Some(*module_id);
}
}
}
}

None
}

pub fn find_type_in_scope(&self, type_name: NodeId) -> Option<TypeId> {
let name = self.compiler.get_source(type_name);
for scope in self.scope.iter().rev() {
Expand All @@ -3151,6 +3205,10 @@ impl Typechecker {
None
}

pub fn find_type_in_module(&self, type_name: NodeId, module: &Module) -> Option<TypeId> {
todo!()
}

pub fn find_type_in_scope_by_name(&self, name: &[u8]) -> Option<TypeId> {
for scope in self.scope.iter().rev() {
if let Some(type_id) = scope.types.get(name) {
Expand Down

0 comments on commit 728db10

Please sign in to comment.