Skip to content

第六步:解释执行

src/interpreter/env.rs

rust
use std::collections::HashMap;

/// 运行时值
#[derive(Debug, Clone)]
pub enum Value {
    Number(f64),
    String(String),
    Boolean(bool),
    Null,
    Function {
        params: Vec<String>,
        body: Vec<crate::parser::ast::Stmt>,
        closure: Environment,
    },
}

/// 环境(作用域)
#[derive(Debug, Clone)]
pub struct Environment {
    variables: HashMap<String, Value>,
    parent: Option<Box<Environment>>,
}

impl Environment {
    pub fn new() -> Self {
        Self {
            variables: HashMap::new(),
            parent: None,
        }
    }
    
    pub fn with_parent(parent: Environment) -> Self {
        Self {
            variables: HashMap::new(),
            parent: Some(Box::new(parent)),
        }
    }
    
    pub fn define(&mut self, name: String, value: Value) {
        self.variables.insert(name, value);
    }
    
    pub fn get(&self, name: &str) -> Option<Value> {
        if let Some(value) = self.variables.get(name) {
            Some(value.clone())
        } else if let Some(parent) = &self.parent {
            parent.get(name)
        } else {
            None
        }
    }
    
    pub fn assign(&mut self, name: &str, value: Value) -> bool {
        if self.variables.contains_key(name) {
            self.variables.insert(name.to_string(), value);
            true
        } else if let Some(parent) = &mut self.parent {
            parent.assign(name, value)
        } else {
            false
        }
    }
}
▶ Run

src/interpreter/eval.rs

rust
use crate::parser::ast::*;
use crate::interpreter::env::{Environment, Value};
use crate::error::Error;

/// 解释器
pub struct Interpreter {
    environment: Environment,
}

impl Interpreter {
    pub fn new() -> Self {
        Self {
            environment: Environment::new(),
        }
    }
    
    /// 执行程序
    pub fn interpret(&mut self, program: &Program) -> Result<Option<Value>, Error> {
        let mut result = None;
        
        for stmt in &program.statements {
            result = self.execute(stmt)?;
        }
        
        Ok(result)
    }
    
    /// 执行语句
    fn execute(&mut self, stmt: &Stmt) -> Result<Option<Value>, Error> {
        match stmt {
            Stmt::Expression(expr) => {
                self.evaluate(expr)?;
                Ok(None)
            }
            
            Stmt::Var { name, initializer } => {
                let value = if let Some(init) = initializer {
                    self.evaluate(init)?
                } else {
                    Value::Null
                };
                self.environment.define(name.clone(), value);
                Ok(None)
            }
            
            Stmt::Function { name, params, body } => {
                let function = Value::Function {
                    params: params.clone(),
                    body: body.clone(),
                    closure: self.environment.clone(),
                };
                self.environment.define(name.clone(), function);
                Ok(None)
            }
            
            Stmt::If { condition, then_branch, else_branch } => {
                let condition_value = self.evaluate(condition)?;
                
                if self.is_truthy(&condition_value) {
                    for stmt in then_branch {
                        if let Some(value) = self.execute(stmt)? {
                            return Ok(Some(value));
                        }
                    }
                } else if let Some(else_stmts) = else_branch {
                    for stmt in else_stmts {
                        if let Some(value) = self.execute(stmt)? {
                            return Ok(Some(value));
                        }
                    }
                }
                
                Ok(None)
            }
            
            Stmt::While { condition, body } => {
                loop {
                    let condition_value = self.evaluate(condition)?;
                    if !self.is_truthy(&condition_value) {
                        break;
                    }
                    
                    for stmt in body {
                        if let Some(value) = self.execute(stmt)? {
                            return Ok(Some(value));
                        }
                    }
                }
                
                Ok(None)
            }
            
            Stmt::Return(value) => {
                let return_value = if let Some(expr) = value {
                    self.evaluate(expr)?
                } else {
                    Value::Null
                };
                Ok(Some(return_value))
            }
            
            Stmt::Block(statements) => {
                let previous = self.environment.clone();
                self.environment = Environment::with_parent(previous.clone());
                
                let mut result = None;
                for stmt in statements {
                    if let Some(value) = self.execute(stmt)? {
                        result = Some(value);
                        break;
                    }
                }
                
                self.environment = previous;
                Ok(result)
            }
        }
    }
    
    /// 求值表达式
    fn evaluate(&mut self, expr: &Expr) -> Result<Value, Error> {
        match expr {
            Expr::Number(n) => Ok(Value::Number(*n)),
            Expr::String(s) => Ok(Value::String(s.clone())),
            Expr::Boolean(b) => Ok(Value::Boolean(*b)),
            Expr::Null => Ok(Value::Null),
            
            Expr::Identifier(name) => {
                self.environment.get(name)
                    .ok_or_else(|| Error::RuntimeError(format!("未定义的变量: {}", name), 0))
            }
            
            Expr::Binary { left, operator, right } => {
                let left_val = self.evaluate(left)?;
                let right_val = self.evaluate(right)?;
                
                self.apply_binary_op(operator, left_val, right_val)
            }
            
            Expr::Unary { operator, operand } => {
                let operand_val = self.evaluate(operand)?;
                self.apply_unary_op(operator, operand_val)
            }
            
            Expr::Call { callee, arguments } => {
                let callee_val = self.evaluate(callee)?;
                
                let mut arg_values = Vec::new();
                for arg in arguments {
                    arg_values.push(self.evaluate(arg)?);
                }
                
                self.call_function(callee_val, arg_values)
            }
            
            Expr::Conditional { condition, then_branch, else_branch } => {
                let condition_val = self.evaluate(condition)?;
                
                if self.is_truthy(&condition_val) {
                    self.evaluate(then_branch)
                } else if let Some(else_expr) = else_branch {
                    self.evaluate(else_expr)
                } else {
                    Ok(Value::Null)
                }
            }
        }
    }
    
    fn apply_binary_op(&self, op: &BinaryOp, left: Value, right: Value) -> Result<Value, Error> {
        match op {
            BinaryOp::Add => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a + b)),
                    (Value::String(a), Value::String(b)) => Ok(Value::String(a.clone() + b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法相加".to_string(), 0)),
                }
            }
            BinaryOp::Subtract => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a - b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法相减".to_string(), 0)),
                }
            }
            BinaryOp::Multiply => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a * b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法相乘".to_string(), 0)),
                }
            }
            BinaryOp::Divide => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => {
                        if *b == 0.0 {
                            Err(Error::RuntimeError("除零错误".to_string(), 0))
                        } else {
                            Ok(Value::Number(a / b))
                        }
                    }
                    _ => Err(Error::RuntimeError("类型错误: 无法相除".to_string(), 0)),
                }
            }
            BinaryOp::Modulo => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a % b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法取模".to_string(), 0)),
                }
            }
            BinaryOp::Equal => Ok(Value::Boolean(self.is_equal(&left, &right))),
            BinaryOp::NotEqual => Ok(Value::Boolean(!self.is_equal(&left, &right))),
            BinaryOp::Less => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Boolean(a < b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法比较".to_string(), 0)),
                }
            }
            BinaryOp::LessEqual => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Boolean(a <= b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法比较".to_string(), 0)),
                }
            }
            BinaryOp::Greater => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Boolean(a > b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法比较".to_string(), 0)),
                }
            }
            BinaryOp::GreaterEqual => {
                match (&left, &right) {
                    (Value::Number(a), Value::Number(b)) => Ok(Value::Boolean(a >= b)),
                    _ => Err(Error::RuntimeError("类型错误: 无法比较".to_string(), 0)),
                }
            }
            BinaryOp::And => Ok(Value::Boolean(self.is_truthy(&left) && self.is_truthy(&right))),
            BinaryOp::Or => Ok(Value::Boolean(self.is_truthy(&left) || self.is_truthy(&right))),
        }
    }
    
    fn apply_unary_op(&self, op: &UnaryOp, operand: Value) -> Result<Value, Error> {
        match op {
            UnaryOp::Negate => {
                match operand {
                    Value::Number(n) => Ok(Value::Number(-n)),
                    _ => Err(Error::RuntimeError("类型错误: 无法取负".to_string(), 0)),
                }
            }
            UnaryOp::Not => Ok(Value::Boolean(!self.is_truthy(&operand))),
        }
    }
    
    fn call_function(&mut self, callee: Value, arguments: Vec<Value>) -> Result<Value, Error> {
        match callee {
            Value::Function { params, body, closure } => {
                if params.len() != arguments.len() {
                    return Err(Error::RuntimeError(
                        format!("参数数量不匹配: 期望 {}, 实际 {}", params.len(), arguments.len()),
                        0,
                    ));
                }
                
                // 创建函数环境
                let mut function_env = Environment::with_parent(closure);
                for (param, arg) in params.iter().zip(arguments.iter()) {
                    function_env.define(param.clone(), arg.clone());
                }
                
                // 保存当前环境
                let previous = self.environment.clone();
                self.environment = function_env;
                
                // 执行函数体
                let mut result = Value::Null;
                for stmt in &body {
                    if let Some(value) = self.execute(stmt)? {
                        result = value;
                        break;
                    }
                }
                
                // 恢复环境
                self.environment = previous;
                
                Ok(result)
            }
            _ => Err(Error::RuntimeError("只能调用函数".to_string(), 0)),
        }
    }
    
    fn is_truthy(&self, value: &Value) -> bool {
        match value {
            Value::Boolean(b) => *b,
            Value::Null => false,
            Value::Number(n) => *n != 0.0,
            Value::String(s) => !s.is_empty(),
            Value::Function { .. } => true,
        }
    }
    
    fn is_equal(&self, a: &Value, b: &Value) -> bool {
        match (a, b) {
            (Value::Number(x), Value::Number(y)) => x == y,
            (Value::String(x), Value::String(y)) => x == y,
            (Value::Boolean(x), Value::Boolean(y)) => x == y,
            (Value::Null, Value::Null) => true,
            _ => false,
        }
    }
}
▶ Run

第七步:主入口

src/main.rs

rust
use rustyline::error::ReadlineError;
use rustyline::DefaultEditor;

mod lexer;
mod parser;
mod interpreter;
mod error;

use lexer::scanner::Scanner;
use parser::parser::Parser;
use interpreter::eval::Interpreter;
use interpreter::env::Value;

fn main() -> anyhow::Result<()> {
    println!("Mini Interpreter v0.1");
    println!("输入 .quit 退出\n");
    
    let mut rl = DefaultEditor::new()?;
    let mut interpreter = Interpreter::new();
    
    loop {
        let readline = rl.readline(">>> ");
        
        match readline {
            Ok(line) => {
                if line.trim() == ".quit" {
                    break;
                }
                
                if line.trim().is_empty() {
                    continue;
                }
                
                rl.add_history_entry(line.as_str()).ok();
                
                // 词法分析
                let mut scanner = Scanner::new(&line);
                let tokens = match scanner.scan_tokens() {
                    Ok(t) => t,
                    Err(e) => {
                        println!("词法错误: {}", e);
                        continue;
                    }
                };
                
                // 语法解析
                let mut parser = Parser::new(tokens);
                let program = match parser.parse() {
                    Ok(p) => p,
                    Err(e) => {
                        println!("语法错误: {}", e);
                        continue;
                    }
                };
                
                // 解释执行
                match interpreter.interpret(&program) {
                    Ok(Some(value)) => println!("{}", format_value(&value)),
                    Ok(None) => {}
                    Err(e) => println!("运行时错误: {}", e),
                }
            }
            Err(ReadlineError::Interrupted) => {
                println!("^C");
                continue;
            }
            Err(ReadlineError::Eof) => {
                println!("退出");
                break;
            }
            Err(err) => {
                println!("错误: {:?}", err);
                break;
            }
        }
    }
    
    Ok(())
}

fn format_value(value: &Value) -> String {
    match value {
        Value::Number(n) => format!("{}", n),
        Value::String(s) => format!("\"{}\"", s),
        Value::Boolean(b) => format!("{}", b),
        Value::Null => "null".to_string(),
        Value::Function { .. } => "<function>".to_string(),
    }
}
▶ Run

运行效果

bash
cargo run

Mini Interpreter v0.1
输入 .quit 退出

>>> let x = 10;
>>> let y = 20;
>>> x + y
30
>>> fn add(a, b) { return a + b; }
>>> add(5, 3)
8
>>> let i = 0;
>>> while (i < 5) { print(i); i = i + 1; }
0
1
2
3
4
>>> .quit

小结

本项目涵盖:

  • ✅ 词法分析
  • ✅ 语法解析
  • ✅ AST 构建
  • ✅ 解释执行
  • ✅ 变量作用域
  • ✅ 函数定义与调用

恭喜完成!

你已经完成了所有 9 个实战项目!