[fine] lets can be local or global
This commit is contained in:
parent
fa53841af9
commit
f8f5c9bfac
2 changed files with 32 additions and 8 deletions
|
|
@ -29,6 +29,7 @@ pub enum Instruction {
|
|||
PushString(usize),
|
||||
PushTrue,
|
||||
StoreLocal(usize),
|
||||
StoreModule(usize),
|
||||
}
|
||||
|
||||
pub enum Export {
|
||||
|
|
@ -308,7 +309,10 @@ fn compile_identifier_expression(c: &mut Compiler, t: TreeRef, tree: &Tree) -> O
|
|||
assert!(declaration.index < c.function.args);
|
||||
Instruction::LoadArgument(declaration.index)
|
||||
}
|
||||
Location::Module => Instruction::LoadModule(declaration.index),
|
||||
Location::Module => {
|
||||
assert!(declaration.index < c.module.globals);
|
||||
Instruction::LoadModule(declaration.index)
|
||||
}
|
||||
};
|
||||
c.push(instruction);
|
||||
|
||||
|
|
@ -371,9 +375,22 @@ fn compile_let_statement(c: &mut Compiler, t: TreeRef, tree: &Tree, gen_value: b
|
|||
let environment = c.semantics.environment_of(t);
|
||||
let declaration = environment.bind(tree.nth_token(1)?)?;
|
||||
|
||||
// NOTE: Because this is a let statement I assume it's local!
|
||||
assert!(matches!(declaration.location, Location::Local));
|
||||
c.push(Instruction::StoreLocal(declaration.index));
|
||||
let instruction = match declaration.location {
|
||||
Location::Local => {
|
||||
if declaration.index >= c.function.locals {
|
||||
c.function.locals = declaration.index + 1;
|
||||
}
|
||||
Instruction::StoreLocal(declaration.index)
|
||||
}
|
||||
Location::Module => {
|
||||
if declaration.index >= c.module.globals {
|
||||
c.module.globals = declaration.index + 1;
|
||||
}
|
||||
Instruction::StoreModule(declaration.index)
|
||||
}
|
||||
_ => panic!("unsuitable location for let declaration"),
|
||||
};
|
||||
c.push(instruction);
|
||||
if gen_value {
|
||||
c.push(Instruction::PushNothing);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,12 +424,19 @@ impl<'a> Semantics<'a> {
|
|||
None => Type::Error,
|
||||
};
|
||||
|
||||
let base_index = match parent.location {
|
||||
Location::Local => parent.base_index + parent.declarations.len(),
|
||||
_ => 0,
|
||||
let (location, base_index) = match parent.location {
|
||||
Location::Local => (
|
||||
Location::Local,
|
||||
parent.base_index + parent.declarations.len(),
|
||||
),
|
||||
Location::Module => (
|
||||
Location::Module,
|
||||
parent.base_index + parent.declarations.len(),
|
||||
),
|
||||
Location::Argument => (Location::Local, 0),
|
||||
};
|
||||
|
||||
let mut environment = Environment::new(Some(parent), Location::Local, base_index);
|
||||
let mut environment = Environment::new(Some(parent), location, base_index);
|
||||
environment.insert(name, declaration_type);
|
||||
|
||||
EnvironmentRef::new(environment)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue