crafting-interpreters/rust/rox/src/interpreter.rs

461 lines
15 KiB
Rust
Raw Normal View History

2025-05-25 10:52:20 +02:00
use std::{cell::RefCell, collections::HashMap, rc::Rc};
2025-02-12 13:10:07 +01:00
2025-05-25 10:52:20 +02:00
use ordered_float::OrderedFloat;
2025-02-11 11:19:56 +01:00
use thiserror::Error;
2025-02-12 10:30:51 +01:00
use tracing::error;
2025-02-11 11:19:56 +01:00
use crate::{
2025-02-13 12:29:31 +01:00
callable::CallingError,
2025-02-12 10:30:51 +01:00
environment::{Environment, EnvironmentError},
2025-02-11 11:19:56 +01:00
expression::Expression,
2025-02-13 12:29:31 +01:00
function::Function,
native_functions,
2025-02-12 10:30:51 +01:00
statement::Statement,
2025-02-11 11:19:56 +01:00
token::{Literal, Token, TokenType},
value::Value,
2025-02-11 11:19:56 +01:00
};
#[derive(Error, Debug)]
pub enum InterpreterError {
2025-05-25 10:55:50 +02:00
#[error("line {0}: MINUS unary expression expects a number on the right")]
2025-02-11 11:19:56 +01:00
UnaryExpressionNotANumber(usize),
2025-05-25 10:55:50 +02:00
#[error("line {0}: unknown unary operator: {1}")]
2025-02-11 11:19:56 +01:00
UnaryOperatorUnknown(usize, String),
2025-05-25 10:55:50 +02:00
#[error("line {0}: unknown binary operator: {1}")]
2025-02-11 11:19:56 +01:00
BinaryOperatorUnknown(usize, String),
2025-05-25 10:55:50 +02:00
#[error("line {0}: left or right is not a number.")]
2025-02-12 10:30:51 +01:00
BinaryExpressionNeedsNumber(usize),
2025-05-25 10:55:50 +02:00
#[error("line {0}: left or right is neither a number nor string.")]
2025-02-12 10:30:51 +01:00
BinaryExpressionNeedsNumberOrString(usize),
#[error("{0}")]
UndefinedVariable(EnvironmentError),
2025-05-25 10:55:50 +02:00
#[error("line {0}: {1} is not callable.")]
2025-02-13 12:29:31 +01:00
NotACallable(usize, Value),
2025-05-25 10:55:50 +02:00
#[error("line {0}: {1}.")]
2025-02-13 12:29:31 +01:00
FailedToCall(usize, CallingError),
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
/// Interpreter for the Lox language.
2025-02-13 12:29:31 +01:00
#[derive(Debug)]
2025-02-12 10:30:51 +01:00
pub struct Interpreter {
2025-02-13 12:29:31 +01:00
pub globals: Rc<RefCell<Environment>>,
2025-02-12 13:10:07 +01:00
environment: Rc<RefCell<Environment>>,
2025-05-25 10:52:20 +02:00
locals: HashMap<Expression, usize>,
2025-02-11 11:19:56 +01:00
}
2025-02-13 12:29:31 +01:00
/// Default configuration for the interpreter, with builtin native functions.
impl Default for Interpreter {
fn default() -> Self {
let env: Rc<RefCell<Environment>> = Default::default();
{
// add all native functions to global environment
let mut env = env.borrow_mut();
for (name, fun) in native_functions::all() {
env.define(name, fun);
}
}
Self {
globals: env.clone(),
environment: env.clone(),
2025-05-25 10:52:20 +02:00
locals: HashMap::new(),
2025-02-13 12:29:31 +01:00
}
}
}
2025-02-12 10:30:51 +01:00
impl Interpreter {
/// Try to evaluate an expression and return its result.
pub fn run(&mut self, statements: Vec<Statement>) -> Result<(), InterpreterError> {
for stmt in statements {
2025-02-12 13:10:07 +01:00
match self.execute(&stmt) {
2025-02-12 10:30:51 +01:00
Ok(_) => {}
Err(e) => error!("{e}"),
};
}
2025-02-11 11:19:56 +01:00
2025-02-12 10:30:51 +01:00
Ok(())
}
2025-02-11 11:19:56 +01:00
2025-05-25 10:52:20 +02:00
pub fn resolve(&mut self, expression: Expression, depth: usize) {
self.locals.insert(expression, depth);
}
2025-02-12 10:30:51 +01:00
///Execute a statement.
2025-02-13 12:29:31 +01:00
fn execute(&mut self, statement: &Statement) -> Result<Option<Value>, InterpreterError> {
2025-02-12 10:30:51 +01:00
match statement {
Statement::Block(statements) => {
let sub_env = Environment::with_enclosing(self.environment.clone());
2025-02-13 12:29:31 +01:00
self.block(statements, sub_env)
2025-02-12 10:30:51 +01:00
}
2025-02-13 12:29:31 +01:00
Statement::Print(expression) => self.print_statement(expression),
Statement::Expression(expression) => Ok(Some(self.evaluate(expression)?)),
2025-02-12 13:10:07 +01:00
Statement::Var { name, initializer } => {
2025-02-13 12:29:31 +01:00
self.var_statement(name, initializer.as_ref().as_ref())
2025-02-12 13:10:07 +01:00
}
Statement::If {
condition,
then_branch,
else_branch,
} => {
let else_branch = else_branch.as_ref().map(|x| *x.clone());
2025-02-13 12:29:31 +01:00
self.if_statement(condition, then_branch, else_branch.as_ref())
2025-02-12 13:10:07 +01:00
}
2025-02-13 12:29:31 +01:00
Statement::While { condition, body } => self.while_statement(condition, body),
Statement::Function { name, params, body } => {
self.function_statement(name, params, body)
}
Statement::Return { keyword: _, value } => self.return_statement(value),
}
2025-02-12 10:30:51 +01:00
}
2025-02-11 11:19:56 +01:00
2025-02-12 10:30:51 +01:00
/// Execute all statements within a block, using a new environment (with the old one as the
2025-02-13 12:29:31 +01:00
/// enclosing one). Immediately return the value if a Return Value is encountered after
/// execution of a statement.
pub fn block(
2025-02-12 10:30:51 +01:00
&mut self,
2025-02-13 12:29:31 +01:00
statements: &[Statement],
2025-02-12 10:30:51 +01:00
environment: Environment,
2025-02-13 12:29:31 +01:00
) -> Result<Option<Value>, InterpreterError> {
2025-02-12 13:10:07 +01:00
let prev_env = self.environment.clone();
self.environment = Rc::new(RefCell::new(environment));
2025-02-12 10:30:51 +01:00
for stmt in statements {
2025-02-13 12:29:31 +01:00
let execution = self.execute(stmt);
match execution {
Ok(x) => {
if let Some(Value::Return(x)) = x {
self.environment = prev_env.clone();
return Ok(Some(*x));
}
}
Err(e) => error!("{e}"),
2025-02-11 11:19:56 +01:00
}
}
2025-02-12 10:30:51 +01:00
self.environment = prev_env.clone();
2025-02-13 12:29:31 +01:00
Ok(None)
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
/// Evaluate an expression and return its value.
2025-02-12 13:10:07 +01:00
fn evaluate(&mut self, expression: &Expression) -> Result<Value, InterpreterError> {
2025-02-12 10:30:51 +01:00
match expression {
2025-02-12 13:10:07 +01:00
Expression::Literal { value } => self.literal(value.clone()),
Expression::Grouping { expression } => self.grouping(expression),
2025-02-12 10:30:51 +01:00
Expression::Unary {
operator: op,
right,
2025-02-12 13:10:07 +01:00
} => self.unary(op, right),
2025-02-12 10:30:51 +01:00
Expression::Binary {
left,
operator,
right,
2025-02-12 13:10:07 +01:00
} => self.binary(left, operator, right),
2025-05-25 10:52:20 +02:00
Expression::Variable { name } => self.var_expression(name, expression),
2025-02-12 13:10:07 +01:00
Expression::Assign { name, value } => self.assign(name, value),
Expression::Logical {
left,
operator,
right,
} => self.logical_expression(left, operator, right),
2025-02-13 12:29:31 +01:00
Expression::Call {
callee,
paren,
args,
} => self.call(callee, paren, args),
}
}
/// Call a callable if it is one (meaning it starts with a LeftParen after an identifier),
/// otherwise evaluate the expression.
fn call(
&mut self,
callee: &Expression,
paren: &Token,
arg_expressions: &[Expression],
) -> Result<Value, InterpreterError> {
let callee = self.evaluate(callee)?;
let mut args = Vec::new();
for arg in arg_expressions {
args.push(self.evaluate(arg)?);
2025-02-12 13:10:07 +01:00
}
2025-02-13 12:29:31 +01:00
if let Value::Callable(f) = callee {
f.call(self, args)
.map_err(|e| InterpreterError::FailedToCall(paren.line, e))
} else {
Err(InterpreterError::NotACallable(paren.line, callee))
}
}
/// Define a new function.
fn function_statement(
&mut self,
name: &Token,
params: &[Token],
body: &[Statement],
) -> Result<Option<Value>, InterpreterError> {
let fn_name = name.lexeme.clone();
let fun = Function {
name: name.clone(),
params: params.to_vec(),
body: body.to_vec(),
closure: self.environment.clone(),
};
self.environment
.borrow_mut()
.define(fn_name, Value::Callable(Rc::new(fun)));
Ok(None)
2025-02-12 13:10:07 +01:00
}
/// If the condition evaluates to truthy, execute the then branch, otherwise the else branch.
fn if_statement(
&mut self,
condition: &Expression,
then_branch: &Statement,
else_branch: Option<&Statement>,
2025-02-13 12:29:31 +01:00
) -> Result<Option<Value>, InterpreterError> {
2025-02-12 13:10:07 +01:00
if self.evaluate(condition)?.is_truthy() {
self.execute(then_branch)
} else if let Some(else_branch) = else_branch {
self.execute(else_branch)
} else {
2025-02-13 12:29:31 +01:00
Ok(None)
2025-02-12 10:30:51 +01:00
}
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
/// Evaluate an expression and print its value to stdout.
2025-02-13 12:29:31 +01:00
fn print_statement(
&mut self,
expression: &Expression,
) -> Result<Option<Value>, InterpreterError> {
2025-02-12 10:30:51 +01:00
let value = self.evaluate(expression)?;
println!("{value}");
2025-02-13 12:29:31 +01:00
Ok(None)
}
/// Return a value from a statement.
fn return_statement(
&mut self,
value: &Option<Expression>,
) -> Result<Option<Value>, InterpreterError> {
Ok(match value {
Some(x) => Some(Value::Return(Box::new(self.evaluate(x)?))),
None => Some(Value::Return(Box::new(Value::Nil))),
})
2025-02-12 10:30:51 +01:00
}
/// Initialize a variable with an initializer expression or nil.
fn var_statement(
&mut self,
2025-02-12 13:10:07 +01:00
name: &Token,
initializer: Option<&Expression>,
2025-02-13 12:29:31 +01:00
) -> Result<Option<Value>, InterpreterError> {
2025-02-12 10:30:51 +01:00
let value = if let Some(initializer) = initializer {
self.evaluate(initializer)
} else {
Ok(Value::Nil)
}?;
2025-02-12 13:10:07 +01:00
self.environment
.borrow_mut()
.define(name.lexeme.clone(), value);
2025-02-13 12:29:31 +01:00
Ok(None)
2025-02-12 13:10:07 +01:00
}
/// Execute the body as long as the condition evaluates to true.
fn while_statement(
&mut self,
condition: &Expression,
body: &Statement,
2025-02-13 12:29:31 +01:00
) -> Result<Option<Value>, InterpreterError> {
2025-02-12 13:10:07 +01:00
while self.evaluate(condition)?.is_truthy() {
self.execute(body)?;
}
2025-02-12 10:30:51 +01:00
2025-02-13 12:29:31 +01:00
Ok(None)
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
/// Assign the value of an expression to a variable.
2025-05-25 10:52:20 +02:00
fn assign(&mut self, name: &Token, expression: &Expression) -> Result<Value, InterpreterError> {
let value = self.evaluate(expression)?;
2025-02-12 10:30:51 +01:00
self.environment
2025-02-12 13:10:07 +01:00
.borrow_mut()
2025-02-12 10:30:51 +01:00
.assign(name, value.clone())
.map_err(InterpreterError::UndefinedVariable)?;
2025-05-25 10:52:20 +02:00
if let Some(distance) = self.locals.get(expression) {
self.environment
.borrow_mut()
.assign_at(*distance, name, value.clone())
.map_err(InterpreterError::UndefinedVariable)?;
} else {
self.globals
.borrow_mut()
.assign(name, value.clone())
.map_err(InterpreterError::UndefinedVariable)?;
}
2025-02-12 10:30:51 +01:00
Ok(value)
}
/// Convert the literal value into a Value.
fn literal(&self, literal: Literal) -> Result<Value, InterpreterError> {
Ok(literal.into())
}
2025-02-12 13:10:07 +01:00
/// Evaluate left and if the operator is Or and left is truthy or the operator is not Or and
/// not leftis truthy short circuit and return left. Otherwise evaluate and return right.
fn logical_expression(
&mut self,
left: &Expression,
operator: &Token,
right: &Expression,
) -> Result<Value, InterpreterError> {
let left = self.evaluate(left)?;
let truthy = if operator.token_type == TokenType::Or {
left.is_truthy()
} else {
!left.is_truthy()
};
if truthy {
Ok(left)
} else {
self.evaluate(right)
}
}
2025-02-12 10:30:51 +01:00
/// Evaluate the inner expression.
2025-02-12 13:10:07 +01:00
fn grouping(&mut self, inner: &Expression) -> Result<Value, InterpreterError> {
2025-02-12 10:30:51 +01:00
self.evaluate(inner)
}
/// Evaluate the expression on the right and use its result when evaluating the unary operator.
2025-02-12 13:10:07 +01:00
fn unary(&mut self, op: &Token, right: &Expression) -> Result<Value, InterpreterError> {
2025-02-12 10:30:51 +01:00
let right = self.evaluate(right)?;
match op.token_type {
TokenType::Minus => {
if let Value::Number(val) = right {
Ok(Value::Number(-val))
} else {
Err(InterpreterError::UnaryExpressionNotANumber(op.line))
}
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
TokenType::Bang => Ok(Value::Boolean(!right.is_truthy())),
2025-02-12 13:10:07 +01:00
_ => Err(InterpreterError::UnaryOperatorUnknown(
op.line,
op.lexeme.clone(),
)),
2025-02-12 10:30:51 +01:00
}
}
/// Get the value of a variable.
2025-05-25 10:52:20 +02:00
fn var_expression(
&mut self,
name: &Token,
expression: &Expression,
) -> Result<Value, InterpreterError> {
self.lookup_var(name, expression)
}
fn lookup_var(
&mut self,
name: &Token,
expression: &Expression,
) -> Result<Value, InterpreterError> {
if let Some(distance) = self.locals.get(expression) {
self.environment
.borrow()
.get_at(*distance, name)
.map_err(InterpreterError::UndefinedVariable)
} else {
self.globals
.borrow()
.get(name)
.map_err(InterpreterError::UndefinedVariable)
}
2025-02-12 10:30:51 +01:00
}
/// Calculate number operations.
fn number_op(&self, left: f64, op: TokenType, right: f64) -> f64 {
match op {
TokenType::Minus => left - right,
TokenType::Plus => left + right,
TokenType::Slash => left / right,
TokenType::Star => left * right,
_ => unreachable!(),
}
}
/// Calculate boolean operations.
fn boolean_op(&self, left: f64, op: TokenType, right: f64) -> bool {
match op {
TokenType::Greater => left > right,
TokenType::GreaterEqual => left >= right,
TokenType::Less => left < right,
TokenType::LessEqual => left <= right,
_ => unreachable!(),
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
}
/// Evaluate the left and right expressions (in that order) and then combine them with the
/// specified operator.
fn binary(
&mut self,
2025-02-12 13:10:07 +01:00
left: &Expression,
op: &Token,
right: &Expression,
2025-02-12 10:30:51 +01:00
) -> Result<Value, InterpreterError> {
let left = self.evaluate(left)?;
let right = self.evaluate(right)?;
match op.token_type {
TokenType::Minus | TokenType::Slash | TokenType::Star | TokenType::Plus => {
if let (Value::Number(left), Value::Number(right)) = (left.clone(), right.clone()) {
2025-05-25 10:52:20 +02:00
Ok(Value::Number(OrderedFloat(self.number_op(
*left,
op.token_type,
*right,
))))
2025-02-12 10:30:51 +01:00
} else if let (Value::String(left), Value::String(right)) = (left, right) {
Ok(Value::String(format!("{}{}", left.clone(), right.clone())))
} else {
Err(InterpreterError::BinaryExpressionNeedsNumberOrString(
op.line,
))
}
}
TokenType::Greater
| TokenType::GreaterEqual
| TokenType::Less
| TokenType::LessEqual => {
if let (Value::Number(left), Value::Number(right)) = (left, right) {
2025-05-25 10:52:20 +02:00
Ok(Value::Boolean(self.boolean_op(
*left,
op.token_type,
*right,
)))
2025-02-12 10:30:51 +01:00
} else {
Err(InterpreterError::BinaryExpressionNeedsNumber(op.line))
}
2025-02-11 11:19:56 +01:00
}
2025-02-12 10:30:51 +01:00
TokenType::BangEqual => Ok(Value::Boolean(left != right)),
TokenType::EqualEqual => Ok(Value::Boolean(left == right)),
2025-02-12 13:10:07 +01:00
_ => Err(InterpreterError::BinaryOperatorUnknown(
op.line,
op.lexeme.clone(),
)),
2025-02-11 11:19:56 +01:00
}
}
}