From 090dd8c52e4ae60742fe8bad7b74e18bb808ba0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Wed, 17 Feb 2021 21:15:54 +0100 Subject: use enums instead of 2 bools --- src/compiler.rs | 3 +-- src/lib.rs | 29 +++++++++++++++++++++++++---- src/vm.rs | 4 ++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index c0dacec..c70640d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -923,8 +923,7 @@ impl Compiler { }; add_op(self, block, Op::Link(slot)); if let Value::Function(_, block) = &self.constants[slot] { - let needs_linking = block.borrow().upvalues.len() != 0; - block.borrow_mut().constant = needs_linking; + block.borrow_mut().mark_constant(); } else { unreachable!(); } diff --git a/src/lib.rs b/src/lib.rs index 1bdcc00..42a74a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -625,18 +625,24 @@ mod op { } } +#[derive(Debug)] +enum BlockLinkState { + Linked, + Unlinked, + Nothing, +} + #[derive(Debug)] pub struct Block { pub ty: Type, upvalues: Vec<(usize, bool, Type)>, + linking: BlockLinkState, pub name: String, pub file: PathBuf, ops: Vec, last_line_offset: usize, line_offsets: HashMap, - linked: bool, - constant: bool, } impl Block { @@ -644,16 +650,31 @@ impl Block { Self { ty: Type::Void, upvalues: Vec::new(), + linking: BlockLinkState::Nothing, + name: String::from(name), file: file.to_owned(), ops: Vec::new(), last_line_offset: 0, line_offsets: HashMap::new(), - linked: false, - constant: false, } } + fn mark_constant(&mut self) { + if self.upvalues.is_empty() { + return; + } + self.linking = BlockLinkState::Unlinked; + } + + fn link(&mut self) { + self.linking = BlockLinkState::Linked; + } + + fn needs_linking(&self) -> bool { + matches!(self.linking, BlockLinkState::Unlinked) + } + // Used to create empty functions. fn stubbed_block(ty: &Type) -> Self { let mut block = Block::new("/empty/", Path::new("")); diff --git a/src/vm.rs b/src/vm.rs index 20125be..5e7810d 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -557,7 +557,7 @@ impl VM { Value::Function(_, block) => { self.push(Value::Function(Vec::new(), block.clone())); - if block.borrow().constant && !block.borrow().linked { + if block.borrow().needs_linking() { error!(self, ErrorKind::InvalidProgram, format!("Calling function '{}' before all captured variables are declared.", @@ -676,7 +676,7 @@ impl VM { Op::Link(slot) => { match self.constant(slot).clone() { Value::Function(_, block) => { - block.borrow_mut().linked = true; + block.borrow_mut().link(); } value => { error!(self, -- cgit v1.2.1