pull interpreter value out into its own file

This commit is contained in:
Sebastian Hugentobler 2025-02-11 14:09:52 +01:00
parent 6440819ff2
commit 15b331f447
3 changed files with 48 additions and 30 deletions

View File

@ -3,6 +3,7 @@ use thiserror::Error;
use crate::{ use crate::{
expression::Expression, expression::Expression,
token::{Literal, Token, TokenType}, token::{Literal, Token, TokenType},
value::Value,
}; };
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -15,35 +16,6 @@ pub enum InterpreterError {
BinaryOperatorUnknown(usize, String), BinaryOperatorUnknown(usize, String),
} }
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
String(String),
Number(f64),
Boolean(bool),
Nil,
}
impl Value {
fn is_truthy(&self) -> bool {
match self {
Value::Nil => false,
Value::Boolean(b) => *b,
_ => true,
}
}
}
impl From<Literal> for Value {
fn from(value: Literal) -> Self {
match value {
Literal::String(x) => Value::String(x),
Literal::Number(x) => Value::Number(x),
Literal::Boolean(x) => Value::Boolean(x),
Literal::Nil => Value::Nil,
}
}
}
/// Try to evaluate an expression and return its result. /// Try to evaluate an expression and return its result.
pub fn evaluate(expression: Expression) -> Result<Value, InterpreterError> { pub fn evaluate(expression: Expression) -> Result<Value, InterpreterError> {
match expression { match expression {

View File

@ -27,6 +27,7 @@ pub mod tokenizer {
pub mod string; pub mod string;
pub mod whitespace; pub mod whitespace;
} }
pub mod value;
/// Read the source code in a file and scan it to tokens. /// Read the source code in a file and scan it to tokens.
pub fn compile(source: &Path) -> Result<(), io::Error> { pub fn compile(source: &Path) -> Result<(), io::Error> {
@ -57,7 +58,7 @@ fn run(input: &str) {
let tokens = scanner::tokenize(input); let tokens = scanner::tokenize(input);
match parser::generate_ast(tokens) { match parser::generate_ast(tokens) {
Ok(ast) => match interpreter::evaluate(ast) { Ok(ast) => match interpreter::evaluate(ast) {
Ok(value) => info!("{value:?}"), Ok(value) => println!("{value}"),
Err(e) => error!("{e}"), Err(e) => error!("{e}"),
}, },
Err(e) => error!("{e}"), Err(e) => error!("{e}"),

45
rust/rox/src/value.rs Normal file
View File

@ -0,0 +1,45 @@
use std::fmt::Display;
use crate::token::Literal;
/// Concrete value in the interpreter.
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
String(String),
Number(f64),
Boolean(bool),
Nil,
}
impl Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Value::String(x) => write!(f, "{x}"),
Value::Number(x) => write!(f, "{x}"),
Value::Boolean(x) => write!(f, "{x}"),
Value::Nil => write!(f, "nil"),
}
}
}
impl Value {
/// Return false for nil or a false boolean, true otherwise.
pub fn is_truthy(&self) -> bool {
match self {
Value::Nil => false,
Value::Boolean(b) => *b,
_ => true,
}
}
}
impl From<Literal> for Value {
fn from(value: Literal) -> Self {
match value {
Literal::String(x) => Value::String(x),
Literal::Number(x) => Value::Number(x),
Literal::Boolean(x) => Value::Boolean(x),
Literal::Nil => Value::Nil,
}
}
}