feat: 实现for循环语句的解析和执行逻辑,更新词法分析器以支持for关键字

This commit is contained in:
0264408
2026-02-11 09:39:06 +08:00
parent 0e0077d96b
commit 5dc55c3476
6 changed files with 71 additions and 0 deletions

9
examples/loop.ast Normal file
View File

@@ -0,0 +1,9 @@
let i = 0;
while(i < 10) {
print(i);
i = i + 1;
}
for (let i = 0; i < 10; i = i + 1) {
print(i)
}

View File

@@ -27,6 +27,14 @@ pub enum Stmt {
body: Box<Stmt>,
},
/// for 循环
For {
initializer: Option<Box<Stmt>>,
condition: Option<Expr>,
step: Option<Expr>,
body: Box<Stmt>,
},
/// 函数声明
Function {
name: String,

View File

@@ -64,6 +64,22 @@ impl Interpreter {
}
Ok(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;
}
self.execute(*body.clone())?;
if let Some(step) = &step {
self.evaluate(step.clone())?;
}
}
Ok(None)
}
Stmt::Function { name, params, body } => {
let func = Value::Function(Rc::new(Function {
params,

View File

@@ -243,6 +243,7 @@ impl Lexer {
"if" => TokenKind::If,
"else" => TokenKind::Else,
"while" => TokenKind::While,
"for" => TokenKind::For,
"return" => TokenKind::Return,
"true" => TokenKind::True,
"false" => TokenKind::False,

View File

@@ -27,6 +27,7 @@ pub enum TokenKind {
If,
Else,
While,
For,
Return,
True,
False,

View File

@@ -37,6 +37,8 @@ impl Parser {
self.if_statement()
} else if self.match_kind(&[TokenKind::While]) {
self.while_statement()
} else if self.match_kind(&[TokenKind::For]) {
self.for_statement()
} else if self.match_kind(&[TokenKind::Return]) {
self.return_statement()
} else if self.match_kind(&[TokenKind::LeftBrace]) {
@@ -117,6 +119,40 @@ impl Parser {
Stmt::While { condition, body }
}
fn for_statement(&mut self) -> Stmt {
self.consume(TokenKind::LeftParen, "Expected '(' after 'for'.").unwrap();
let initializer = if self.match_kind(&[TokenKind::Semicolon]) {
None
} else if self.match_kind(&[TokenKind::Let]) {
Some(self.let_declaration())
} else {
Some(self.expression_statement())
};
let condition = if !self.check(&TokenKind::Semicolon) {
Some(self.expression())
} else {
None
};
self.consume(TokenKind::Semicolon, "Expected ';' after loop condition.").unwrap();
let step = if !self.check(&TokenKind::RightParen) {
Some(self.expression())
} else {
None
};
self.consume(TokenKind::RightParen, "Expected ')' after for clauses.").unwrap();
let body = Box::new(self.statement());
Stmt::For {
initializer: initializer.map(Box::new),
condition,
step,
body
}
}
fn return_statement(&mut self) -> Stmt {
let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) {
Some(self.expression())