From f8f5c9bfacb2705750433681192eb1f3b9fdabd1 Mon Sep 17 00:00:00 2001 From: John Doty Date: Tue, 9 Jan 2024 09:17:37 -0800 Subject: [PATCH] [fine] lets can be local or global --- fine/src/compiler.rs | 25 +++++++++++++++++++++---- fine/src/semantics.rs | 15 +++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/fine/src/compiler.rs b/fine/src/compiler.rs index aa640b74..a187aa00 100644 --- a/fine/src/compiler.rs +++ b/fine/src/compiler.rs @@ -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); } diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index 7c72a8d1..03746659 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -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)