1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use crate::{Code, Instructions, Object};
use tonic_parser::{Statement, Expression, Op};
#[derive(Debug)]
pub struct Compiler {
instructions: Instructions,
constants: Vec<Object>,
}
impl Compiler {
pub fn new() -> Self {
Self {
instructions: Vec::new(),
constants: Vec::new()
}
}
pub fn instructions(&self) -> Vec<Code> {
self.instructions.clone()
}
pub fn compile(&mut self, statement: Statement) {
match statement {
Statement::Expression { expression } => {
self.expression(expression)
},
_ => todo!()
}
}
pub fn expression(&mut self, expression: Expression) {
match expression {
Expression::Infix(left, op, right) => {
self.expression(*left);
self.expression(*right);
match op {
Op::Add => self.emit(Code::Add),
_ => todo!()
};
},
Expression::Number(n) => {
let position = self.constant(Object::Number(n));
self.emit(Code::Constant(position));
},
_ => todo!()
}
}
fn constant(&mut self, object: Object) -> usize {
self.constants.push(object);
self.constants.len() - 1
}
fn emit(&mut self, code: Code) -> usize {
self.instructions.push(code);
self.instructions.len() - 1
}
}
#[derive(Debug)]
pub struct Bytecode {
pub instructions: Instructions,
pub constants: Vec<Object>,
}
impl From<Compiler> for Bytecode {
fn from(c: Compiler) -> Self {
Self { instructions: c.instructions, constants: c.constants }
}
}
#[cfg(test)]
mod tests {
use super::*;
use tonic_parser::{Lexer, Parser};
#[test]
fn infixes() {
assert_eq!(compile("1 + 1;"), vec![
Code::Constant(0),
Code::Constant(1),
Code::Add,
]);
}
fn compile(source: &str) -> Vec<Code> {
let program = parse(source);
let mut compiler = Compiler::new();
for statement in program {
compiler.compile(statement);
}
compiler.instructions().clone()
}
fn parse(source: &str) -> Vec<Statement> {
let lexer = Lexer::new(source);
let mut parser = Parser::new(lexer);
parser.read();
parser.read();
parser.parse()
}
}