feat: 添加对const关键字的支持,允许定义不可变变量并增强相关错误处理

This commit is contained in:
0264408
2026-06-16 17:24:17 +08:00
parent 284a29a4be
commit c2d6c518fc
8 changed files with 254 additions and 102 deletions
+19 -5
View File
@@ -31,7 +31,9 @@ impl Parser {
fn declaration(&mut self) -> Result<Stmt, RuntimeError> {
if self.match_kind(&[TokenKind::Let]) {
self.let_declaration()
self.let_declaration(true)
} else if self.match_kind(&[TokenKind::Const]) {
self.let_declaration(false)
} else if self.match_kind(&[TokenKind::Fn]) {
self.fn_declaration()
} else {
@@ -59,13 +61,13 @@ impl Parser {
}
}
fn let_declaration(&mut self) -> Result<Stmt, RuntimeError> {
fn let_declaration(&mut self, mutable: bool) -> Result<Stmt, RuntimeError> {
let name = self.consume_ident("Expected variable name.")?;
self.consume(TokenKind::Equal, "Expected '=' after variable name.")?;
let initializer = self.expression()?;
self.match_kind(&[TokenKind::Semicolon]); // 分号可选
Ok(Stmt::Let { name, initializer })
Ok(Stmt::Let { name, initializer, mutable })
}
fn fn_declaration(&mut self) -> Result<Stmt, RuntimeError> {
@@ -135,7 +137,7 @@ impl Parser {
let initializer = if self.match_kind(&[TokenKind::Semicolon]) {
None
} else if self.match_kind(&[TokenKind::Let]) {
Some(self.let_declaration()?)
Some(self.let_declaration(true)?)
} else {
Some(self.expression_statement()?)
};
@@ -565,6 +567,7 @@ impl Parser {
match self.peek().kind {
TokenKind::Let
| TokenKind::Const
| TokenKind::Fn
| TokenKind::If
| TokenKind::While
@@ -1106,7 +1109,7 @@ mod tests {
#[test]
fn parse_let_statement() {
match parse_stmt("let x = 5;") {
Stmt::Let { name, initializer } => {
Stmt::Let { name, initializer, .. } => {
assert_eq!(name, "x");
assert!(matches!(initializer, Expr::Literal(Literal::Number(5.0))));
}
@@ -1123,6 +1126,17 @@ mod tests {
}
}
#[test]
fn parse_const_statement() {
match parse_stmt("const x = 5;") {
Stmt::Let { name, mutable, .. } => {
assert_eq!(name, "x");
assert!(!mutable, "const should set mutable=false");
}
e => panic!("Expected Let (const), got {:?}", e),
}
}
#[test]
fn parse_expression_statement() {
match parse_stmt("x;") {