Skip to content

Commit

Permalink
Merge pull request #75 from meloalright/master
Browse files Browse the repository at this point in the history
补齐 "." 访问语法
  • Loading branch information
flaneur2020 committed Aug 15, 2023
2 parents b998b65 + b2a77f8 commit 4bcb9e3
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ Five types of literals are implemented.
};
载体["name"];
载体.name;
载体["a" + "ge"];
载体[三七五];
载体[99];
Expand Down
2 changes: 2 additions & 0 deletions src/evaluator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,9 @@ let two = "two";
fn test_hash_index_expr() {
let tests = vec![
("{\"foo\": 5}[\"foo\"]", Some(Object::Int(5))),
("{\"foo\": 5}.foo", Some(Object::Int(5))),
("{\"foo\": 5}[\"bar\"]", Some(Object::Null)),
("{\"foo\": 5}.bar", Some(Object::Null)),
("let key = \"foo\"; {\"foo\": 5}[key]", Some(Object::Int(5))),
("{}[\"foo\"]", Some(Object::Null)),
("{5: 5}[5]", Some(Object::Int(5))),
Expand Down
1 change: 1 addition & 0 deletions src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ impl Lexer {
'}' => Token::Rbrace,
'[' => Token::Lbracket,
']' => Token::Rbracket,
'.' => Token::Dot,
',' => Token::Comma,
';' => Token::Semicolon,
':' => Token::Colon,
Expand Down
36 changes: 36 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl Parser {
Token::Plus | Token::Minus => Precedence::Sum,
Token::Slash | Token::Asterisk => Precedence::Product,
Token::Lbracket => Precedence::Index,
Token::Dot => Precedence::Index,
Token::Lparen => Precedence::Call,
_ => Precedence::Lowest,
}
Expand Down Expand Up @@ -267,6 +268,10 @@ impl Parser {
self.bump();
left = self.parse_index_expr(left.unwrap());
}
Token::Dot => {
self.bump();
left = self.parse_dot_access_expr(left.unwrap());
}
Token::Lparen => {
self.bump();
left = self.parse_call_expr(left.unwrap());
Expand Down Expand Up @@ -432,6 +437,20 @@ impl Parser {
Some(Expr::Index(Box::new(left), Box::new(index)))
}

fn parse_dot_access_expr(&mut self, left: Expr) -> Option<Expr> {
self.bump();

match self.parse_ident() {
Some(name) => match name {
Ident(str) => {
Some(Expr::Index(Box::new(left), Box::new(Expr::Literal(Literal::String(str)))))
},
_ => return None
},
None => return None,
}
}

fn parse_grouped_expr(&mut self) -> Option<Expr> {
self.bump();

Expand Down Expand Up @@ -858,6 +877,23 @@ return 993322;
);
}

#[test]
fn test_dot_access_expr() {
let input = "myHash.key";

let mut parser = Parser::new(Lexer::new(input));
let program = parser.parse();

check_parse_errors(&mut parser);
assert_eq!(
vec![Stmt::Expr(Expr::Index(
Box::new(Expr::Ident(Ident(String::from("myHash")))),
Box::new(Expr::Literal(Literal::String(String::from("key")))),
))],
program
);
}

#[test]
fn test_prefix_expr() {
let tests = vec![
Expand Down
1 change: 1 addition & 0 deletions src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub enum Token {
Rbrace,
Lbracket,
Rbracket,
Dot,

// Reseved keywords
Func,
Expand Down

0 comments on commit 4bcb9e3

Please sign in to comment.