Skip to content

Commit c66e0e1

Browse files
authored
Merge pull request #123 from antimony-lang/bugfix/nested-array-access
Fix array access
2 parents 6228e74 + 2d2c0c6 commit c66e0e1

3 files changed

Lines changed: 76 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
**Fixes**
6+
7+
- Fixed array access in member variable expressions ([#123](https://github.com/antimony-lang/antimony/pull/123))
8+
59
**Maintenance**
610

711
- Add multi-level AST structure with High-level AST (HAST) and Low-level AST (LAST) ([#124](https://github.com/antimony-lang/antimony/pull/124))

src/parser/rules.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,54 @@ impl Parser {
451451
expr: Box::new(lhs),
452452
field: Box::new(field),
453453
};
454-
if self.peek_token(TokenKind::Dot).is_ok() {
455-
self.parse_field_access(expr)
456-
} else if HBinOp::try_from(self.peek()?.kind).is_ok() {
457-
self.parse_bin_op(Some(expr))
458-
} else {
459-
Ok(expr)
454+
455+
// Look ahead to determine next steps
456+
match self.peek()?.kind {
457+
TokenKind::Dot => self.parse_field_access(expr),
458+
TokenKind::SquareBraceOpen => {
459+
self.match_token(TokenKind::SquareBraceOpen)?;
460+
let index_expr = self.parse_expression()?;
461+
self.match_token(TokenKind::SquareBraceClose)?;
462+
463+
let array_expr = HExpression::ArrayAccess {
464+
name: format!("{:?}", expr),
465+
index: Box::new(index_expr),
466+
};
467+
468+
// Handle any further chaining (like .foo[0] or [0][0])
469+
match self.peek()?.kind {
470+
TokenKind::Dot => self.parse_field_access(array_expr),
471+
TokenKind::SquareBraceOpen => {
472+
// Handle nested array access
473+
let mut current_expr = array_expr;
474+
while self.peek_token(TokenKind::SquareBraceOpen).is_ok() {
475+
self.match_token(TokenKind::SquareBraceOpen)?;
476+
let index = self.parse_expression()?;
477+
self.match_token(TokenKind::SquareBraceClose)?;
478+
479+
current_expr = HExpression::ArrayAccess {
480+
name: format!("{:?}", current_expr),
481+
index: Box::new(index),
482+
};
483+
}
484+
485+
// If there's a dot after the nested array access
486+
if self.peek_token(TokenKind::Dot).is_ok() {
487+
self.parse_field_access(current_expr)
488+
} else if HBinOp::try_from(self.peek()?.kind).is_ok() {
489+
self.parse_bin_op(Some(current_expr))
490+
} else {
491+
Ok(current_expr)
492+
}
493+
}
494+
kind if HBinOp::try_from(kind.clone()).is_ok() => {
495+
self.parse_bin_op(Some(array_expr))
496+
}
497+
_ => Ok(array_expr),
498+
}
499+
}
500+
kind if HBinOp::try_from(kind.clone()).is_ok() => self.parse_bin_op(Some(expr)),
501+
_ => Ok(expr),
460502
}
461503
}
462504

src/parser/tests.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,3 +1056,27 @@ fn test_errors_for_struct_literal() {
10561056
let tree = parse(tokens, Some(raw.to_string()));
10571057
assert!(tree.is_err());
10581058
}
1059+
1060+
#[test]
1061+
fn test_array_access() {
1062+
let raw = "
1063+
fn main() {
1064+
let c = self.chars[0]
1065+
}
1066+
";
1067+
let tokens = tokenize(raw).unwrap();
1068+
let tree = parse(tokens, Some(raw.to_string()));
1069+
assert!(tree.is_ok(), "{:?}", tree.err());
1070+
}
1071+
1072+
#[test]
1073+
fn test_nested_array_access() {
1074+
let raw = "
1075+
fn main() {
1076+
let c = self.chars[0].foo[0][0]
1077+
}
1078+
";
1079+
let tokens = tokenize(raw).unwrap();
1080+
let tree = parse(tokens, Some(raw.to_string()));
1081+
assert!(tree.is_ok(), "{:?}", tree.err());
1082+
}

0 commit comments

Comments
 (0)