diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-16 22:33:26 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-02-16 22:37:57 +0100 |
| commit | 3432a32af8c17efdabe20d4249f8da49608de179 (patch) | |
| tree | be65873b249e81493131a62c454f4e46c4d7e9f4 | |
| parent | 299981e74e625b7dc85ebfe2adbd066f6c68c0d8 (diff) | |
| download | sylt-3432a32af8c17efdabe20d4249f8da49608de179.tar.gz | |
simple and dumb unused variable report
| -rw-r--r-- | src/compiler.rs | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index 94ae2aa..3d95e2f 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -127,6 +127,7 @@ struct Variable { upvalue: bool, captured: bool, mutable: bool, + read: bool, } enum LoopOp { @@ -203,6 +204,14 @@ impl Frame { None } + fn mark_read(&mut self, var: &Variable) { + (if var.upvalue { + &mut self.upvalues + } else { + &mut self.stack + })[var.slot].read = true; + } + fn add_upvalue(&mut self, variable: Variable) -> Variable { let new_variable = Variable { outer_upvalue: variable.upvalue, @@ -243,9 +252,16 @@ macro_rules! push_frame { // Return value stored as a variable $compiler.define_variable("", Type::Unknown, &mut $block).unwrap(); + $code - $compiler.frames.pop().unwrap(); + let frame = $compiler.frames.pop().unwrap(); + for var in frame.stack.iter() { + if !(var.read || var.upvalue) { + error!($compiler, format!("Unused variable {}", var.name)); + } + $compiler.panic = false; + } // The 0th slot is the return value, which is passed out // from functions, and should not be popped. 0 @@ -814,6 +830,7 @@ impl Compiler { // Variables if let Some(var) = self.find_variable(&name) { + self.frame_mut().mark_read(&var); if var.upvalue { add_op(self, block, Op::ReadUpvalue(var.slot)); } else { @@ -867,6 +884,7 @@ impl Compiler { active: false, upvalue: false, mutable: true, + read: false, }); Ok(slot) } @@ -892,6 +910,7 @@ impl Compiler { active: false, upvalue: false, mutable: false, + read: false, }); Ok(slot) } @@ -1387,12 +1406,14 @@ impl Compiler { captured: false, upvalue: false, mutable: true, + read: false, }); let mut block = Block::new(name, file, 0); while self.peek() != Token::EOF { self.statement(&mut block); - expect!(self, Token::Newline | Token::EOF, "Expect newline or EOF after expression."); + expect!(self, Token::Newline | Token::EOF, + "Expect newline or EOF after expression."); } add_op(self, &mut block, Op::Constant(self.nil_value())); add_op(self, &mut block, Op::Return); @@ -1410,6 +1431,13 @@ impl Compiler { } } + for var in self.frames.pop().unwrap().stack.iter().skip(1) { + if !(var.read || var.upvalue) { + error!(self, format!("Unused variable {}", var.name)); + } + self.panic = false; + } + self.blocks.insert(0, Rc::new(RefCell::new(block))); if self.errors.is_empty() { |
