1
0
Fork 0

Refactor interpreter get symtab as argument

This commit is contained in:
Vili Sinervä 2025-02-04 14:06:00 +02:00
parent 1ec86d4845
commit 77b89dbf37
No known key found for this signature in database
GPG key ID: DF8FEAF54EFAC996
2 changed files with 116 additions and 127 deletions

View file

@ -1,7 +1,8 @@
use std::io; use std::io;
use interpreter::Interpreter; use interpreter::interpret;
use parser::parse; use parser::parse;
use symtab::SymTab;
use tokenizer::tokenize; use tokenizer::tokenize;
mod ast; mod ast;
@ -10,6 +11,7 @@ mod parser;
mod symtab; mod symtab;
mod token; mod token;
mod tokenizer; mod tokenizer;
//mod type_checker;
mod value; mod value;
pub fn compile(code: &str) { pub fn compile(code: &str) {
@ -25,8 +27,7 @@ pub fn start_interpreter() {
let tokens = tokenize(&code); let tokens = tokenize(&code);
let ast = parse(&tokens); let ast = parse(&tokens);
let mut interpreter = Interpreter::new(); let val = interpret(&ast, &mut SymTab::new());
let val = interpreter.interpret(&ast);
println!("{}", val); println!("{}", val);
} }
} }

View file

@ -4,145 +4,133 @@ use crate::compiler::{
value::Value, value::Value,
}; };
pub struct Interpreter<'source> { pub fn interpret<'source>(ast: &Expression<'source>, symbols: &mut SymTab<'source>) -> Value {
symbols: SymTab<'source>, match ast {
} EmptyLiteral(_) => Value::None(),
IntLiteral(_, val) => Value::Int(*val),
impl<'source> Interpreter<'source> { BoolLiteral(_, val) => Value::Bool(*val),
pub fn new() -> Self { Identifier(_, name) => *symbols.get(name),
Interpreter { UnaryOp(_, op, expr) => match *op {
symbols: SymTab::new(), "-" => {
} let Value::Func(op_fn) = symbols.get("neg") else {
} panic!("Operator {} does not correspond to a function!", op);
};
pub fn interpret(&mut self, ast: &Expression<'source>) -> Value { op_fn(&[interpret(expr, symbols)])
match ast {
EmptyLiteral(_) => Value::None(),
IntLiteral(_, val) => Value::Int(*val),
BoolLiteral(_, val) => Value::Bool(*val),
Identifier(_, name) => *self.symbols.get(name),
UnaryOp(_, op, expr) => match *op {
"-" => {
let Value::Func(op_fn) = self.symbols.get("neg") else {
panic!("Operator {} does not correspond to a function!", op);
};
op_fn(&[self.interpret(expr)])
}
_ => {
let Value::Func(op_fn) = self.symbols.get(op) else {
panic!("Operator {} does not correspond to a function!", op);
};
op_fn(&[self.interpret(expr)])
}
},
BinaryOp(_, left, op, right) => match *op {
"and" => {
let left_val = self.interpret(left);
if let Value::Bool(val_l) = left_val {
if !val_l {
Value::Bool(false)
} else {
let right_val = self.interpret(right);
if let Value::Bool(val_r) = right_val {
Value::Bool(val_r)
} else {
panic!("Non-bool with and operator");
}
}
} else {
panic!("Non-bool with and operator");
}
}
"or" => {
let left_val = self.interpret(left);
if let Value::Bool(val_l) = left_val {
if val_l {
Value::Bool(true)
} else {
let right_val = self.interpret(right);
if let Value::Bool(val_r) = right_val {
Value::Bool(val_r)
} else {
panic!("Non-bool with and operator");
}
}
} else {
panic!("Non-bool with and operator");
}
}
"=" => {
if let Expression::Identifier(_, name) = **left {
let val = self.interpret(right);
*self.symbols.get(name) = val;
val
} else {
panic!("Assignment must have identifier as left expr!");
}
}
_ => {
let Value::Func(op_fn) = self.symbols.get(op) else {
panic!("Operator {} does not correspond to a function!", op);
};
op_fn(&[self.interpret(left), self.interpret(right)])
}
},
VarDeclaration(_, name, expr) => {
let val = self.interpret(expr);
self.symbols.insert(name, val);
Value::None()
} }
Conditional(_, condition_expr, then_expr, else_expr) => { _ => {
if let Value::Bool(condition) = self.interpret(condition_expr) { let Value::Func(op_fn) = symbols.get(op) else {
if condition { panic!("Operator {} does not correspond to a function!", op);
self.interpret(then_expr) };
} else if let Some(expr) = else_expr { op_fn(&[interpret(expr, symbols)])
self.interpret(expr) }
},
BinaryOp(_, left, op, right) => match *op {
"and" => {
let left_val = interpret(left, symbols);
if let Value::Bool(val_l) = left_val {
if !val_l {
Value::Bool(false)
} else { } else {
Value::None() let right_val = interpret(right, symbols);
if let Value::Bool(val_r) = right_val {
Value::Bool(val_r)
} else {
panic!("Non-bool with and operator");
}
} }
} else { } else {
panic!("Non-bool as if-then-else condition!"); panic!("Non-bool with and operator");
} }
} }
While(_, condition, do_expr) => { "or" => {
let mut val = Value::None(); let left_val = interpret(left, symbols);
loop { if let Value::Bool(val_l) = left_val {
let condition = self.interpret(condition); if val_l {
if let Value::Bool(cond) = condition { Value::Bool(true)
if cond {
val = self.interpret(do_expr);
} else {
break;
}
} else { } else {
panic!("Non-boon as while-do condition!"); let right_val = interpret(right, symbols);
if let Value::Bool(val_r) = right_val {
Value::Bool(val_r)
} else {
panic!("Non-bool with and operator");
}
} }
} else {
panic!("Non-bool with and operator");
} }
val
} }
FunCall(_, name, args) => { "=" => {
let mut arg_values = Vec::new(); if let Expression::Identifier(_, name) = **left {
for arg in args { let val = interpret(right, symbols);
arg_values.push(self.interpret(arg)); *symbols.get(name) = val;
val
} else {
panic!("Assignment must have identifier as left expr!");
} }
}
let Value::Func(function) = self.symbols.get(name) else { _ => {
panic!("Identifier {} does not correspond to a function!", name); let Value::Func(op_fn) = symbols.get(op) else {
panic!("Operator {} does not correspond to a function!", op);
}; };
op_fn(&[interpret(left, symbols), interpret(right, symbols)])
function(&arg_values)
} }
Block(_, expressions) => { },
self.symbols.push_level(); VarDeclaration(_, name, expr) => {
let val = interpret(expr, symbols);
let mut val = Value::None(); symbols.insert(name, val);
for expression in expressions { Value::None()
val = self.interpret(expression); }
Conditional(_, condition_expr, then_expr, else_expr) => {
if let Value::Bool(condition) = interpret(condition_expr, symbols) {
if condition {
interpret(then_expr, symbols)
} else if let Some(expr) = else_expr {
interpret(expr, symbols)
} else {
Value::None()
} }
} else {
self.symbols.remove_level(); panic!("Non-bool as if-then-else condition!");
val
} }
} }
While(_, condition, do_expr) => {
let mut val = Value::None();
loop {
let condition = interpret(condition, symbols);
if let Value::Bool(cond) = condition {
if cond {
val = interpret(do_expr, symbols);
} else {
break;
}
} else {
panic!("Non-boon as while-do condition!");
}
}
val
}
FunCall(_, name, args) => {
let mut arg_values = Vec::new();
for arg in args {
arg_values.push(interpret(arg, symbols));
}
let Value::Func(function) = symbols.get(name) else {
panic!("Identifier {} does not correspond to a function!", name);
};
function(&arg_values)
}
Block(_, expressions) => {
symbols.push_level();
let mut val = Value::None();
for expression in expressions {
val = interpret(expression, symbols);
}
symbols.remove_level();
val
}
} }
} }