| 98 | } |
| 99 | |
| 100 | pub(crate) fn parse_expr_path<'heap, 'span, 'source, E>( |
| 101 | input: &mut Input<'heap, 'span, 'source>, |
| 102 | ) -> ModalResult<Expr<'heap>, E> |
| 103 | where |
| 104 | E: ParserError<Input<'heap, 'span, 'source>> |
| 105 | + FromExternalError<Input<'heap, 'span, 'source>, ParseIntError> |
| 106 | + AddContext<Input<'heap, 'span, 'source>, StrContext>, |
| 107 | { |
| 108 | let ((path, path_span), access): (_, Vec<_>) = ( |
| 109 | parse_path.with_span(), |
| 110 | repeat( |
| 111 | 0.., |
| 112 | preceded( |
| 113 | multispace0, |
| 114 | dispatch! {peek(any); |
| 115 | '[' => parse_index_access.context(StrContext::Label("index")), |
| 116 | '.' => parse_field_access.context(StrContext::Label("field")), |
| 117 | _ => fail |
| 118 | .context(StrContext::Expected(StrContextValue::CharLiteral('['))) |
| 119 | .context(StrContext::Expected(StrContextValue::CharLiteral('.'))) |
| 120 | } |
| 121 | .with_span(), |
| 122 | ), |
| 123 | ), |
| 124 | ) |
| 125 | .parse_next(input)?; |
| 126 | |
| 127 | let mut range = path_span; |
| 128 | |
| 129 | let mut expr = Expr { |
| 130 | id: NodeId::PLACEHOLDER, |
| 131 | span: path.span, |
| 132 | kind: ExprKind::Path(path), |
| 133 | }; |
| 134 | |
| 135 | for (access, span) in access { |
| 136 | range.end = span.end; |
| 137 | |
| 138 | let span = input.state.span(range.clone()); |
| 139 | |
| 140 | // We de-sugar into expressions directly instead of special forms, not to save |
| 141 | // on memory, but just because it is a lot easier and terse to create these |
| 142 | // nodes instead of fully-fledged call nodes. |
| 143 | let kind = match access { |
| 144 | Access::IndexByLiteral(literal) => ExprKind::Index(IndexExpr { |
| 145 | id: NodeId::PLACEHOLDER, |
| 146 | span, |
| 147 | value: Box::new_in(expr, input.state.heap), |
| 148 | index: Box::new_in( |
| 149 | Expr { |
| 150 | id: NodeId::PLACEHOLDER, |
| 151 | span: literal.span, |
| 152 | kind: ExprKind::Literal(literal), |
| 153 | }, |
| 154 | input.state.heap, |
| 155 | ), |
| 156 | }), |
| 157 | Access::IndexByExpr(index) => ExprKind::Index(IndexExpr { |