diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-09 22:05:56 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-09 22:05:56 +0100 |
| commit | a894b3642114f63209fb4b787187ba249672ccee (patch) | |
| tree | 449156f6a34d928788d60c7f8b18682d040216ea /src | |
| parent | 3ede943556bebb85427415f21ec231973da9e080 (diff) | |
| download | sylt-a894b3642114f63209fb4b787187ba249672ccee.tar.gz | |
Add line numbers
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiler.rs | 21 | ||||
| -rw-r--r-- | src/main.rs | 5 | ||||
| -rw-r--r-- | src/tokenizer.rs | 24 | ||||
| -rw-r--r-- | src/vm.rs | 14 |
4 files changed, 51 insertions, 13 deletions
diff --git a/src/compiler.rs b/src/compiler.rs index c34063d..40a597f 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -23,7 +23,7 @@ impl Compiler { } fn error(&self, msg: &str) -> ! { - println!("ERROR: {} range {:?}", msg, self.tokens[self.curr].1); + println!("ERROR: {} line {:?}", msg, self.line()); panic!(); } @@ -63,6 +63,13 @@ impl Compiler { } } + fn line(&self) -> Option<usize> { + match self.tokens.get(self.curr) { + Some((_, line)) => Some(*line), + None => None, + } + } + fn prefix(&mut self, token: Token, block: &mut Block) -> bool { match token { Token::LeftParen => self.grouping(block), @@ -109,7 +116,7 @@ impl Compiler { Token::Bool(b) => { Value::Bool(b) } _ => { self.error("Invalid value.") } }; - block.add(Op::Constant(value)); + block.add(Op::Constant(value), self.line()); } fn grouping(&mut self, block: &mut Block) { @@ -131,7 +138,7 @@ impl Compiler { _ => self.error("Invalid unary operator"), }; self.value(block); - block.add(op); + block.add(op, self.line()); } fn binary(&mut self, block: &mut Block) { @@ -147,7 +154,7 @@ impl Compiler { Token::AssertEqual => Op::AssertEqual, _ => { self.error("Illegal operator"); } }; - block.add(op); + block.add(op, self.line()); } fn comparison(&mut self, block: &mut Block) { @@ -163,7 +170,7 @@ impl Compiler { Token::GreaterEqual => &[Op::Less, Op::Not], _ => { self.error("Illegal comparison operator"); } }; - block.add_from(op); + block.add_from(op, self.line()); } fn expression(&mut self, block: &mut Block) { @@ -192,13 +199,13 @@ impl Compiler { } self.expression(&mut block); - block.add(Op::Print); + block.add(Op::Print, self.line()); if self.eat() != Token::Newline { self.error("Invalid expression"); } } - block.add(Op::Return); + block.add(Op::Return, self.line()); block } diff --git a/src/main.rs b/src/main.rs index afe09ca..0bd80fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,13 +3,14 @@ mod vm; mod compiler; fn main() { - let tokens = tokenizer::file_to_tokens("tests/simple.tdy"); + let file = "tests/simple.tdy"; + let tokens = tokenizer::file_to_tokens(file); for token in tokens.iter() { println!("{:?}", token); } - let block = compiler::compile("main", tokens); + let block = compiler::compile("main", file, tokens); vm::run_block(block); } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index acebcca..9b33a06 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -1,5 +1,5 @@ use std::fs; -use logos::{Logos, Span}; +use logos::Logos; #[derive(Logos, Debug, PartialEq, Clone)] pub enum Token { @@ -114,18 +114,34 @@ pub enum Token { Error, } -pub type PlacedToken = (Token, Span); +pub type PlacedToken = (Token, usize); pub type TokenStream = Vec<PlacedToken>; + pub fn file_to_tokens(filename: &str) -> TokenStream { let content = fs::read_to_string(filename).unwrap(); let lexer = Token::lexer(&content); - let mut line = 1; + + let mut placed_tokens = lexer.spanned().peekable(); + + let mut lined_tokens = Vec::new(); + let mut line: usize = 1; for (c_idx, c) in content.chars().enumerate() { + if let Some((kind, t_range)) = placed_tokens.peek() { + if t_range.start == c_idx { + let kind = kind.clone(); + placed_tokens.next(); + lined_tokens.push((kind, line)); + } + } else { + break; + } + if c == '\n' { line += 1; } } - lexer.spanned().collect() + + lined_tokens } #[cfg(test)] @@ -117,6 +117,19 @@ impl VM { self.stack.get(self.stack.len() - amount) } + fn print_error(&self) { + let find_line = || { + for i in (0..=self.ip).rev() { + if let Some(line) = self.block.line_offsets.get(&i) { + return *line; + } + } + return 0; + }; + + println!("RUNTIME ERROR OR LINE: {}", find_line()); + } + pub fn run(&mut self) -> Result<(), VMError>{ const PRINT_WHILE_RUNNING: bool = true; const PRINT_BLOCK: bool = true; @@ -229,6 +242,7 @@ impl VM { Op::AssertEqual => { let (a, b) = self.pop_twice(); if a != b { + self.print_error(); println!("Assert failed for '{:?}' and '{:?}'", a, b); } self.stack.push(Value::Bool(a == b)); |
