[fine] Many more import-related shuffles
This commit is contained in:
parent
994268abb6
commit
a3ae4339cf
8 changed files with 159 additions and 67 deletions
|
|
@ -104,6 +104,13 @@ impl std::ops::Deref for ClassRef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ImportRecord {
|
||||
pub name: String,
|
||||
pub module_id: u64,
|
||||
pub semantics: Weak<Semantics>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Type {
|
||||
// Signals a type error. If you receive this then you know that an error
|
||||
|
|
@ -156,7 +163,7 @@ pub enum Type {
|
|||
Alternate(Box<[Type]>),
|
||||
|
||||
// A module of some kind. What module?
|
||||
Module(Rc<str>),
|
||||
Module(ImportRecord),
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
|
@ -251,7 +258,7 @@ impl fmt::Display for Type {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
Module(name) => write!(f, "module {}", name),
|
||||
Module(name) => write!(f, "module {}", name.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -583,7 +590,11 @@ fn set_logical_parents(
|
|||
// Process escapes and convert a string constant in source to a runtime String value.
|
||||
pub fn string_constant_to_string(s: &str) -> String {
|
||||
let mut result = String::new();
|
||||
let mut input = s.chars();
|
||||
if s.len() <= 2 {
|
||||
return result;
|
||||
}
|
||||
|
||||
let mut input = s[1..s.len() - 1].chars();
|
||||
while let Some(ch) = input.next() {
|
||||
if ch == '\\' {
|
||||
if let Some(ch) = input.next() {
|
||||
|
|
@ -615,7 +626,7 @@ pub struct Semantics {
|
|||
syntax_tree: Rc<SyntaxTree>,
|
||||
lines: Rc<Lines>,
|
||||
|
||||
import_map: OnceCell<HashMap<String, Weak<Semantics>>>,
|
||||
import_map: OnceCell<HashMap<String, ImportRecord>>,
|
||||
|
||||
// Instead of physical parents, this is the set of *logical* parents.
|
||||
// This is what is used for binding.
|
||||
|
|
@ -661,7 +672,7 @@ impl Semantics {
|
|||
semantics
|
||||
}
|
||||
|
||||
pub fn set_imports(&self, imports: HashMap<String, Weak<Semantics>>) {
|
||||
pub fn set_imports(&self, imports: HashMap<String, ImportRecord>) {
|
||||
self.import_map.set(imports).expect("imports already set");
|
||||
}
|
||||
|
||||
|
|
@ -678,7 +689,22 @@ impl Semantics {
|
|||
}
|
||||
|
||||
pub fn imports(&self) -> Vec<String> {
|
||||
vec![]
|
||||
self.syntax_tree
|
||||
.root()
|
||||
.map(|file| {
|
||||
self.syntax_tree[file]
|
||||
.children_of_kind(&self.syntax_tree, TreeKind::Import)
|
||||
.filter_map(|import| {
|
||||
let tok = self.syntax_tree[import].nth_token(1)?;
|
||||
if tok.kind != TokenKind::String {
|
||||
None
|
||||
} else {
|
||||
Some(string_constant_to_string(tok.as_str(&self.source)))
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or(Vec::new())
|
||||
}
|
||||
|
||||
pub fn snapshot_errors(&self) -> Vec<Error> {
|
||||
|
|
@ -2213,7 +2239,20 @@ impl Semantics {
|
|||
if tok.kind != TokenKind::String {
|
||||
return Some(Type::Error); // Already reported as syntax error
|
||||
}
|
||||
Some(Type::Module(tok.as_str(&self.source).into()))
|
||||
|
||||
// do we bind it here? it's not normalized....
|
||||
let Some(import_map) = self.import_map.get() else {
|
||||
self.internal_compiler_error(None, "import map not initialized");
|
||||
};
|
||||
|
||||
let name = tok.as_str(&self.source);
|
||||
match import_map.get(name) {
|
||||
Some(import) => Some(Type::Module(import.clone())),
|
||||
None => {
|
||||
self.report_error_tree(tree, format!("unable to resolve module import {name}"));
|
||||
Some(Type::Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Really want to TEST THIS also uh can we generate bytecode for functions and call it??
|
||||
|
|
@ -2488,7 +2527,7 @@ pub fn check(s: &Semantics) {
|
|||
TreeKind::WhileStatement => check_while_statement(s, tree),
|
||||
|
||||
TreeKind::Import => {
|
||||
// TODO: Check Import Statement
|
||||
let _ = s.type_of(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue