feat: 实现for循环语句的解析和执行逻辑,更新词法分析器以支持for关键字
This commit is contained in:
9
examples/loop.ast
Normal file
9
examples/loop.ast
Normal 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)
|
||||||
|
}
|
||||||
@@ -27,6 +27,14 @@ pub enum Stmt {
|
|||||||
body: Box<Stmt>,
|
body: Box<Stmt>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// for 循环
|
||||||
|
For {
|
||||||
|
initializer: Option<Box<Stmt>>,
|
||||||
|
condition: Option<Expr>,
|
||||||
|
step: Option<Expr>,
|
||||||
|
body: Box<Stmt>,
|
||||||
|
},
|
||||||
|
|
||||||
/// 函数声明
|
/// 函数声明
|
||||||
Function {
|
Function {
|
||||||
name: String,
|
name: String,
|
||||||
|
|||||||
@@ -64,6 +64,22 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
Ok(None)
|
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 } => {
|
Stmt::Function { name, params, body } => {
|
||||||
let func = Value::Function(Rc::new(Function {
|
let func = Value::Function(Rc::new(Function {
|
||||||
params,
|
params,
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ impl Lexer {
|
|||||||
"if" => TokenKind::If,
|
"if" => TokenKind::If,
|
||||||
"else" => TokenKind::Else,
|
"else" => TokenKind::Else,
|
||||||
"while" => TokenKind::While,
|
"while" => TokenKind::While,
|
||||||
|
"for" => TokenKind::For,
|
||||||
"return" => TokenKind::Return,
|
"return" => TokenKind::Return,
|
||||||
"true" => TokenKind::True,
|
"true" => TokenKind::True,
|
||||||
"false" => TokenKind::False,
|
"false" => TokenKind::False,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ pub enum TokenKind {
|
|||||||
If,
|
If,
|
||||||
Else,
|
Else,
|
||||||
While,
|
While,
|
||||||
|
For,
|
||||||
Return,
|
Return,
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ impl Parser {
|
|||||||
self.if_statement()
|
self.if_statement()
|
||||||
} else if self.match_kind(&[TokenKind::While]) {
|
} else if self.match_kind(&[TokenKind::While]) {
|
||||||
self.while_statement()
|
self.while_statement()
|
||||||
|
} else if self.match_kind(&[TokenKind::For]) {
|
||||||
|
self.for_statement()
|
||||||
} else if self.match_kind(&[TokenKind::Return]) {
|
} else if self.match_kind(&[TokenKind::Return]) {
|
||||||
self.return_statement()
|
self.return_statement()
|
||||||
} else if self.match_kind(&[TokenKind::LeftBrace]) {
|
} else if self.match_kind(&[TokenKind::LeftBrace]) {
|
||||||
@@ -117,6 +119,40 @@ impl Parser {
|
|||||||
Stmt::While { condition, body }
|
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 {
|
fn return_statement(&mut self) -> Stmt {
|
||||||
let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) {
|
let value = if !self.check(&TokenKind::Semicolon) && !self.check(&TokenKind::RightBrace) {
|
||||||
Some(self.expression())
|
Some(self.expression())
|
||||||
|
|||||||
Reference in New Issue
Block a user