Start implementing interpreter

- Implemented tree-walk-interpreter for expressions only
- Binops Add, Mul
- Value Types I64
This commit is contained in:
Daniel M 2022-01-02 21:58:10 +01:00
parent ef4dee98dc
commit 39dd5e81f2
4 changed files with 56 additions and 13 deletions

42
src/interpreter.rs Normal file
View File

@ -0,0 +1,42 @@
use crate::parser::{Ast, BinOpType};
#[derive(Debug)]
pub enum Value {
I64(i64),
}
pub struct Interpreter {
// Runtime storage, for example variables ...
}
impl Interpreter {
pub fn new() -> Self {
Self {}
}
pub fn run(&mut self, prog: Ast) {
let result = self.resolve_expr(prog);
println!("Result = {:?}", result);
}
fn resolve_expr(&mut self, expr: Ast) -> Value {
match expr {
Ast::I64(val) => Value::I64(val),
Ast::BinOp(bo, lhs, rhs) => self.resolve_binop(bo, *lhs, *rhs),
}
}
fn resolve_binop(&mut self, bo: BinOpType, lhs: Ast, rhs: Ast) -> Value {
let lhs = self.resolve_expr(lhs);
let rhs = self.resolve_expr(rhs);
match (lhs, rhs) {
(Value::I64(lhs), Value::I64(rhs)) => match bo {
BinOpType::Add => Value::I64(lhs + rhs),
BinOpType::Mul => Value::I64(lhs * rhs),
},
// _ => panic!("Value types are not compatible"),
}
}
}

View File

@ -1,2 +1,3 @@
pub mod lexer; pub mod lexer;
pub mod parser; pub mod parser;
pub mod interpreter;

View File

@ -1,23 +1,23 @@
use nek_lang::{lexer::lex, parser::parse}; use nek_lang::{lexer::lex, parser::parse, interpreter::Interpreter};
fn main() { fn main() {
let code = "33 +5*2"; let mut code = String::new();
// Should produce ast: Add {
// lhs: I64(33),
// rhs: Mul: {
// lhs: I64(5),
// rhs: I64(2)
// }
// }
let tokens = lex(code); std::io::stdin().read_line(&mut code).unwrap();
let code = code.trim();
let tokens = lex(&code);
println!("Tokens: {:?}\n", tokens); println!("Tokens: {:?}\n", tokens);
let ast = parse(tokens); let ast = parse(tokens);
println!("Ast: {:#?}", ast); println!("Ast: {:#?}\n", ast);
let mut interpreter = Interpreter::new();
interpreter.run(ast);
} }

View File

@ -3,7 +3,7 @@ use std::iter::Peekable;
use crate::lexer::Token; use crate::lexer::Token;
/// Types for binary operators /// Types for binary operators
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum BinOpType { pub enum BinOpType {
/// Addition /// Addition
Add, Add,
@ -12,7 +12,7 @@ pub enum BinOpType {
Mul, Mul,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum Ast { pub enum Ast {
/// Integer literal (64-bit) /// Integer literal (64-bit)
I64(i64), I64(i64),