aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler.rs21
-rw-r--r--src/main.rs5
-rw-r--r--src/tokenizer.rs24
-rw-r--r--src/vm.rs14
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)]
diff --git a/src/vm.rs b/src/vm.rs
index d45e4d6..a53b5a9 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -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));