feat: 新增对象字面量和属性访问表达式
This commit is contained in:
+48
-20
@@ -154,14 +154,11 @@ impl Parser {
|
||||
|
||||
if self.match_kind(&[TokenKind::Equal]) {
|
||||
let value = self.assignment();
|
||||
if let Expr::Variable(name) = expr {
|
||||
return Expr::Assign {
|
||||
name,
|
||||
value: Box::new(value),
|
||||
};
|
||||
} else {
|
||||
panic!("Invalid assignment target.");
|
||||
}
|
||||
return match expr {
|
||||
Expr::Variable(name) => Expr::Assign { name, value: Box::new(value) },
|
||||
Expr::Get { object, name } => Expr::Set { object, name, value: Box::new(value) },
|
||||
_ => panic!("Invalid assignment target."),
|
||||
};
|
||||
}
|
||||
|
||||
expr
|
||||
@@ -299,21 +296,31 @@ impl Parser {
|
||||
fn call(&mut self) -> Expr {
|
||||
let mut expr = self.primary();
|
||||
|
||||
while self.match_kind(&[TokenKind::LeftParen]) {
|
||||
let mut arguments = Vec::new();
|
||||
if !self.check(&TokenKind::RightParen) {
|
||||
loop {
|
||||
arguments.push(self.expression());
|
||||
if !self.match_kind(&[TokenKind::Comma]) {
|
||||
break;
|
||||
loop {
|
||||
if self.match_kind(&[TokenKind::LeftParen]) {
|
||||
let mut arguments = Vec::new();
|
||||
if !self.check(&TokenKind::RightParen) {
|
||||
loop {
|
||||
arguments.push(self.expression());
|
||||
if !self.match_kind(&[TokenKind::Comma]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.consume(TokenKind::RightParen, "Expected ')' after arguments.").unwrap();
|
||||
expr = Expr::Call {
|
||||
callee: Box::new(expr),
|
||||
arguments,
|
||||
};
|
||||
} else if self.match_kind(&[TokenKind::Dot]) {
|
||||
let name = self.consume_ident("Expected property name after '.'.").unwrap();
|
||||
expr = Expr::Get {
|
||||
object: Box::new(expr),
|
||||
name,
|
||||
};
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
self.consume(TokenKind::RightParen, "Expected ')' after arguments.").unwrap();
|
||||
expr = Expr::Call {
|
||||
callee: Box::new(expr),
|
||||
arguments,
|
||||
};
|
||||
}
|
||||
|
||||
expr
|
||||
@@ -363,6 +370,10 @@ impl Parser {
|
||||
return expr;
|
||||
}
|
||||
|
||||
if self.match_kind(&[TokenKind::LeftBrace]) {
|
||||
return self.object_literal();
|
||||
}
|
||||
|
||||
panic!("Expected expression at line {}", self.peek().line);
|
||||
}
|
||||
|
||||
@@ -428,4 +439,21 @@ impl Parser {
|
||||
fn previous(&self) -> &Token {
|
||||
&self.tokens[self.current - 1]
|
||||
}
|
||||
|
||||
fn object_literal(&mut self) -> Expr {
|
||||
let mut properties = Vec::new();
|
||||
if !self.check(&TokenKind::RightBrace) {
|
||||
loop {
|
||||
let name = self.consume_ident("Expected property name in object literal").unwrap();
|
||||
self.consume(TokenKind::Colon, "Expected ':' after property name in object literal").unwrap();
|
||||
let value = self.expression();
|
||||
properties.push((name, value));
|
||||
if !self.match_kind(&[TokenKind::Comma]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.consume(TokenKind::RightBrace, "Expected '}' after object literal").unwrap();
|
||||
Expr::ObjectLiteral { properties }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user