[fine] Simplify function compilation

This is simpler because we don't "discover" functions to compile as we
go, we just compile all the ones we can find, and functions have
pre-defined exports. This is good and useful to us as we can now refer
to functions in different modules by known indices, but it *does* make
me wonder what we're going to do for compiling generic specializations.
The previous technique was better for that sort of thing.

This is all predicated on the idea that I want to have
partially-compiled modules, which I can't really say why I want it. If
I'm happy to just compile things cross module in the same kind of
space then it's much easier to go back to the function key way of
working.
This commit is contained in:
John Doty 2024-03-29 19:12:18 -07:00
parent 4c061fbd28
commit ab477cd783
14 changed files with 190 additions and 214 deletions

View file

@ -344,9 +344,9 @@ pub enum Location {
Local, // A local in an frame
Slot, // A slot in an object
Module, // A global in a module
Function, // A function in a module (index unrelated)
Function, // A function in a module
ExternalFunction, // An external function (module unrelated)
Class, // A class in a module (index unrelated)
Class, // A class in a module
Import, // An import in a module (index unrelated)
}
@ -683,6 +683,9 @@ pub struct Semantics {
// This is what is used for binding.
logical_parents: Vec<Option<TreeRef>>,
function_count: usize,
function_indices: Vec<Option<usize>>,
// TODO: State should be externalized instead of this refcell nonsense.
errors: RefCell<Vec<Rc<Error>>>,
types: RefCell<Vec<Incremental<Type>>>,
@ -706,6 +709,19 @@ impl Semantics {
let root_environment = Environment::new(mid, None, Location::Module);
let mut function_count = 0;
let mut function_indices = vec![None; tree.len()];
for t in tree.trees() {
let tree = &tree[t];
match tree.kind {
TreeKind::FunctionDecl | TreeKind::ClassDecl => {
function_indices[t.index()] = Some(function_count);
function_count += 1;
}
_ => {}
}
}
let mut semantics = Semantics {
mid,
file,
@ -714,6 +730,8 @@ impl Semantics {
lines,
import_map: OnceCell::new(),
logical_parents,
function_count,
function_indices,
errors: RefCell::new(vec![]),
types: RefCell::new(vec![Incremental::None; tree.len()]),
environments: RefCell::new(vec![Incremental::None; tree.len()]),
@ -892,6 +910,27 @@ impl Semantics {
Environment::error(error)
}
pub fn function_count(&self) -> usize {
self.function_count
}
pub fn get_function_index(&self, t: TreeRef) -> Option<usize> {
let index = t.index();
if index >= self.function_indices.len() {
None
} else {
self.function_indices[t.index()]
}
}
pub fn function_index_of(&self, t: TreeRef) -> usize {
let Some(index) = self.function_indices[t.index()] else {
self.internal_compiler_error(Some(t), "Why didn't I get a function index for this?");
};
index
}
pub fn environment_of(&self, t: TreeRef) -> EnvironmentRef {
{
// I want to make sure that this borrow is dropped after this block.
@ -952,7 +991,7 @@ impl Semantics {
name.as_str(&self.source).into(),
Declaration {
location: Location::Function,
index: 0,
index: self.function_index_of(*t),
module: self.mid,
origin: Origin::Source(*t),
exported: false,
@ -1007,7 +1046,7 @@ impl Semantics {
let declaration = Declaration {
location: Location::Function,
index: 0,
index: self.function_index_of(t),
module: self.mid,
origin: Origin::Source(t),
exported,
@ -1024,7 +1063,7 @@ impl Semantics {
let declaration = Declaration {
location: Location::Class,
index: 0,
index: self.function_index_of(t),
module: self.mid,
origin: Origin::Source(t),
exported,
@ -1393,7 +1432,7 @@ impl Semantics {
(&*method.name).into(),
Declaration {
location: Location::Function,
index: 0,
index: self.function_index_of(method.declaration),
module: self.mid,
origin: Origin::Source(method.declaration),
exported: false,