feat: 添加对const关键字的支持,允许定义不可变变量并增强相关错误处理
This commit is contained in:
+19
-5
@@ -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;") {
|
||||
|
||||
Reference in New Issue
Block a user