Array indexing support first pass

This commit is contained in:
2026-01-01 13:46:04 -07:00
parent 072a6b9ea6
commit 0999ae8aed
4 changed files with 258 additions and 3 deletions

View File

@@ -308,7 +308,7 @@ impl<'a> Parser<'a> {
Ok(Some(lhs))
}
/// Handles dot notation chains: x.y.z()
/// Handles dot notation chains: x.y.z() and bracket notation: x[i]
fn parse_postfix(
&mut self,
mut lhs: Spanned<Expression<'a>>,
@@ -411,6 +411,40 @@ impl<'a> Parser<'a> {
}),
};
}
} else if self_matches_peek!(self, TokenType::Symbol(Symbol::LBracket)) {
// Index Access
self.assign_next()?; // consume '[', now current is '['
self.assign_next()?; // advance to the expression, now current is first token of index expr
let index = self.expression()?.ok_or(Error::UnexpectedEOF)?;
// After expression(), current is still on the last token of the index expression
// We need to get the next token and verify it's ']'
let rbracket_token = self.get_next()?.ok_or(Error::UnexpectedEOF)?;
if !token_matches!(rbracket_token, TokenType::Symbol(Symbol::RBracket)) {
return Err(Error::UnexpectedToken(
Self::token_to_span(&rbracket_token),
rbracket_token.clone(),
));
}
let end_span = Self::token_to_span(&rbracket_token);
let combined_span = Span {
start_line: lhs.span.start_line,
start_col: lhs.span.start_col,
end_line: end_span.end_line,
end_col: end_span.end_col,
};
lhs = Spanned {
span: combined_span,
node: Expression::IndexAccess(Spanned {
span: combined_span,
node: IndexAccessExpression {
object: boxed!(lhs),
index: boxed!(index),
},
}),
};
} else {
break;
}
@@ -811,6 +845,7 @@ impl<'a> Parser<'a> {
| Expression::BitwiseNot(_)
| Expression::MemberAccess(_)
| Expression::MethodCall(_)
| Expression::IndexAccess(_)
| Expression::Tuple(_) => {}
_ => {
return Err(Error::InvalidSyntax(

View File

@@ -209,6 +209,18 @@ impl<'a> std::fmt::Display for MethodCallExpression<'a> {
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct IndexAccessExpression<'a> {
pub object: Box<Spanned<Expression<'a>>>,
pub index: Box<Spanned<Expression<'a>>>,
}
impl<'a> std::fmt::Display for IndexAccessExpression<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}[{}]", self.object, self.index)
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum LiteralOrVariable<'a> {
Literal(Literal<'a>),
@@ -402,6 +414,7 @@ pub enum Expression<'a> {
TupleDeclaration(Spanned<TupleDeclarationExpression<'a>>),
Variable(Spanned<Cow<'a, str>>),
While(Spanned<WhileExpression<'a>>),
IndexAccess(Spanned<IndexAccessExpression<'a>>),
}
impl<'a> std::fmt::Display for Expression<'a> {
@@ -450,6 +463,7 @@ impl<'a> std::fmt::Display for Expression<'a> {
Expression::TupleDeclaration(e) => write!(f, "{}", e),
Expression::Variable(id) => write!(f, "{}", id),
Expression::While(e) => write!(f, "{}", e),
Expression::IndexAccess(e) => write!(f, "{}", e),
}
}
}