feat: 添加break和continue语句的支持,更新解析器、解释器和词法分析器以处理相关语法

This commit is contained in:
0264408
2026-06-10 17:37:12 +08:00
parent dd3f18da6f
commit ae3060708d
7 changed files with 109 additions and 21 deletions
+51 -21
View File
@@ -1,5 +1,6 @@
use crate::ast::*;
use crate::error::RuntimeError;
use crate::interpreter::Signal;
use super::{Value, Env, Function};
use std::collections::HashMap;
use std::rc::Rc;
@@ -23,26 +24,30 @@ impl Interpreter {
Ok(())
}
fn execute(&mut self, stmt: Stmt) -> Result<Option<Value>, RuntimeError> {
fn execute(&mut self, stmt: Stmt) -> Result<Signal, RuntimeError> {
match stmt {
Stmt::Let { name, initializer } => {
let val = self.evaluate(initializer)?;
self.env.borrow_mut().define(name, val);
Ok(None)
Ok(Signal::None)
}
Stmt::ExprStmt(expr) => {
Ok(Some(self.evaluate(expr)?))
self.evaluate(expr)?;
Ok(Signal::None)
}
Stmt::Block(stmts) => {
let previous = Rc::clone(&self.env);
self.env = Rc::new(RefCell::new(Env::new(Some(previous))));
let mut result = None;
let mut signal = Signal::None;
for s in stmts {
result = self.execute(s)?;
signal = self.execute(s)?;
if !matches!(signal, Signal::None) {
break;
}
}
let parent = self.env.borrow().parent.as_ref().unwrap().clone();
self.env = parent;
Ok(result)
Ok(signal)
}
Stmt::If { condition, then_branch, else_branch } => {
let cond_val = self.evaluate(condition)?;
@@ -51,7 +56,7 @@ impl Interpreter {
} else if let Some(else_branch) = else_branch {
self.execute(*else_branch)
} else {
Ok(None)
Ok(Signal::None)
}
}
Stmt::While { condition, body } => {
@@ -60,25 +65,42 @@ impl Interpreter {
if !self.is_truthy(&cond_val) {
break;
}
self.execute(*body.clone())?;
match self.execute(*body.clone())? {
Signal::Break => break,
Signal::Continue => continue,
sig @ Signal::Return(_) => return Ok(sig),
Signal::None => {}
}
}
Ok(None)
Ok(Signal::None)
}
Stmt::For { initializer, condition, step, body } => {
if let Some(init) = initializer {
self.execute(*init)?;
}
while let Some(cond) = &condition {
let cond_val = self.evaluate(cond.clone())?;
if !self.is_truthy(&cond_val) {
break;
loop {
if let Some(cond) = &condition {
let cond_val = self.evaluate(cond.clone())?;
if !self.is_truthy(&cond_val) {
break;
}
}
match self.execute(*body.clone())? {
Signal::Break => break,
Signal::Continue => {
if let Some(step) = &step {
self.evaluate(step.clone())?;
}
continue;
}
sig @ Signal::Return(_) => return Ok(sig),
Signal::None => {}
}
self.execute(*body.clone())?;
if let Some(step) = &step {
self.evaluate(step.clone())?;
}
}
Ok(None)
Ok(Signal::None)
}
Stmt::Function { name, params, body } => {
let func = Value::Function(Rc::new(Function {
@@ -88,15 +110,17 @@ impl Interpreter {
name: Some(name.clone()),
}));
self.env.borrow_mut().define(name, func);
Ok(None)
Ok(Signal::None)
}
Stmt::Return(expr_opt) => {
if let Some(expr) = expr_opt {
Ok(Some(self.evaluate(expr)?))
Ok(Signal::Return(self.evaluate(expr)?))
} else {
Ok(Some(Value::Nil))
Ok(Signal::Return(Value::Nil))
}
}
Stmt::Break => Ok(Signal::Break),
Stmt::Continue => Ok(Signal::Continue),
}
}
@@ -327,9 +351,15 @@ impl Interpreter {
self.env = env;
let mut ret = Value::Nil;
for stmt in &f.body {
if let Some(val) = self.execute(stmt.clone())? {
ret = val;
break;
match self.execute(stmt.clone())? {
Signal::Return(val) => { ret = val; break; }
Signal::None => {}
Signal::Break | Signal::Continue => {
return Err(RuntimeError::RuntimeError {
message: "break/continue outside of loop".to_string(),
token: None,
});
}
}
}
self.env = previous;