aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdvard Thörnros <edvard.thornros@gmail.com>2021-01-09 16:03:41 +0100
committerEdvard Thörnros <edvard.thornros@gmail.com>2021-01-09 16:03:41 +0100
commit3b480795fd82b5fd66b2b6263a2cac3335717202 (patch)
treed161ef210b0d22962b3613876666df45b58ffaf1
parentfccbcffcc8b1707760445d9f18f1bbdebbb4b69c (diff)
downloadsylt-3b480795fd82b5fd66b2b6263a2cac3335717202.tar.gz
Super simple VM
-rw-r--r--src/main.rs12
-rw-r--r--src/tokenizer.rs10
-rw-r--r--src/vm.rs102
3 files changed, 119 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 576ca20..f407767 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,11 +1,19 @@
mod tokenizer;
+mod vm;
fn main() {
- println!("Hello, world!");
-
+ /*
let tokens = tokenizer::file_to_tokens("tests/simple.tdy");
for token in tokens.iter() {
println!("| {:?}", token);
}
+ */
+
+ let mut blocks = vm::Block::new("main");
+ blocks.add(vm::Op::Constant(vm::Value::Bool(true)));
+ blocks.add(vm::Op::Print);
+ blocks.add(vm::Op::Return);
+
+ vm::run_block(blocks);
}
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index f1f0658..efea700 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -1,5 +1,5 @@
use std::fs;
-use logos::Logos;
+use logos::{Logos, Span};
#[derive(Logos, Debug, PartialEq)]
pub enum Token {
@@ -26,6 +26,10 @@ pub enum Token {
#[token("loop")]
Loop,
+ // TODO(ed): Remove
+ #[token("print")]
+ Print,
+
#[token("+")]
Plus,
#[token("++")]
@@ -94,8 +98,8 @@ pub enum Token {
Error,
}
-pub fn file_to_tokens(filename: &str) -> Vec<Token> {
+pub fn file_to_tokens(filename: &str) -> Vec<(Token, Span)> {
let content = fs::read_to_string(filename).unwrap();
let lexer = Token::lexer(&content);
- lexer.collect()
+ lexer.spanned().collect()
}
diff --git a/src/vm.rs b/src/vm.rs
new file mode 100644
index 0000000..6b26b65
--- /dev/null
+++ b/src/vm.rs
@@ -0,0 +1,102 @@
+
+#[derive(Debug, Clone, Copy)]
+pub enum Value {
+ Float(f64),
+ Int(i64),
+ Bool(bool),
+}
+
+#[derive(Debug)]
+pub enum Op {
+ Pop,
+ Constant(Value),
+ Print,
+ Return,
+}
+
+#[derive(Debug)]
+pub struct Block {
+ name: String,
+ ops: Vec<Op>,
+}
+
+impl Block {
+ pub fn new(name: &str) -> Self {
+ Self {
+ name: String::from(name),
+ ops: Vec::new(),
+ }
+ }
+
+ pub fn add(&mut self, op: Op) -> usize {
+ self.ops.push(op);
+ self.ops.len()
+ }
+}
+
+#[derive(Debug)]
+pub struct VM {
+ stack: Vec<Value>,
+
+ block: Block,
+ ip: usize,
+}
+
+pub fn run_block(block: Block) {
+ let mut vm = VM {
+ stack: Vec::new(),
+
+ block,
+ ip: 0,
+ };
+
+ vm.run();
+}
+
+impl VM {
+ pub fn run(&mut self) {
+ const PRINT_WHILE_RUNNING: bool = true;
+ const PRINT_BLOCK: bool = true;
+
+ if PRINT_BLOCK {
+ println!(" === {} ===", self.block.name);
+ for s in self.block.ops.iter() {
+ println!("| {:?}", s);
+ }
+ println!("");
+ }
+
+ loop {
+
+ if PRINT_WHILE_RUNNING {
+ print!(" [");
+ for s in self.stack.iter() {
+ print!("{:?} ", s);
+ }
+ println!("]");
+
+ println!("{:?}", self.block.ops[self.ip]);
+ }
+
+ match self.block.ops[self.ip] {
+ Op::Pop => {
+ self.stack.pop();
+ }
+
+ Op::Constant(value) => {
+ self.stack.push(value);
+ }
+
+ Op::Print => {
+ println!("PRINT: {:?}", self.stack[0]);
+ }
+
+ Op::Return => {
+ return;
+ }
+ }
+
+ self.ip += 1;
+ }
+ }
+}