From efaab433309170e8330a7722e90c26a93dbec252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edvard=20Th=C3=B6rnros?= Date: Sat, 9 Jan 2021 17:30:09 +0100 Subject: Start on compiler --- src/compiler.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/compiler.rs (limited to 'src/compiler.rs') diff --git a/src/compiler.rs b/src/compiler.rs new file mode 100644 index 0000000..59659f4 --- /dev/null +++ b/src/compiler.rs @@ -0,0 +1,77 @@ +use crate::tokenizer::{Token, TokenStream}; +use crate::vm::{Value, Block, Op}; + +struct Compiler { + curr: usize, + tokens: TokenStream, +} + +impl Compiler { + pub fn new(tokens: TokenStream) -> Self { + Self { + curr: 0, + tokens, + } + } + + fn error(&self, msg: &str) -> ! { + println!("ERROR: {}", msg); + panic!(); + } + + fn peek(&self) -> Token { + if self.tokens.len() < self.curr { + crate::tokenizer::Token::EOF + } else { + self.tokens[self.curr].0.clone() + } + } + + fn eat(&mut self) -> Token { + let t = self.peek(); + self.curr += 1; + t + } + + fn value(&mut self) -> Value { + match self.eat() { + Token::Float(f) => { Value::Float(f) }, + Token::Int(f) => { Value::Int(f) } + _ => { self.error("Invalid value.") } + } + } + + fn expression(&mut self, block: &mut Block) { + let a = self.value(); + block.add(Op::Constant(a)); + + loop { + println!("{:?}", self.peek()); + let op = match self.eat() { + Token::Plus => Op::Add, + Token::Minus => Op::Sub, + Token::Star => Op::Mul, + Token::Slash => Op::Div, + _ => { break; } + }; + + let b = self.value(); + block.add(Op::Constant(b)); + block.add(op); + } + } + + pub fn compile(&mut self, name: &str) -> Block { + let mut block = Block::new(name); + + self.expression(&mut block); + block.add(Op::Print); + block.add(Op::Return); + + block + } +} + +pub fn compile(name: &str, tokens: TokenStream) -> Block { + Compiler::new(tokens).compile(name) +} -- cgit v1.2.1