1use super::{Parser, literal};
2use crate::lexer::Token;
3use crate::parser::ast::{IndexNode, Node};
4use crate::parser::error::ParseError;
5
6pub fn parse_index(it: &mut Parser, mut node: Node) -> Result<Node, ParseError> {
8 if let Some((Token::Colon, _, _)) = &it.current_token {
9 node = parse_index_selector(it, node)?;
10 }
11
12 Ok(node)
13}
14
15pub fn parse_index_selector(it: &mut Parser, node: Node) -> Result<Node, ParseError> {
17 if !it.check_token(&Token::Colon) {
18 let (line, column) = it.get_current_position();
19 let current = it.get_current_token_str();
20 return Err(ParseError::unexpected_token(":", ¤t, line, column));
21 }
22
23 it.consume_token(&Token::Colon)?;
24
25 it.check_depth()?;
26
27 let index_node = match &it.current_token {
28 Some((Token::Colon, _, _)) => {
29 it.read_token();
30 let end_index = if let Some((Token::Colon, _, _)) = &it.current_token {
31 it.read_token();
32 None
33 } else {
34 Some(literal::parse_literal(it)?)
35 };
36
37 let step_value = if let Some((Token::Colon, _, _)) = &it.current_token {
38 it.read_token();
39 Some(literal::parse_literal(it)?)
40 } else {
41 match literal::parse_literal(it) {
42 Ok(step) => Some(step),
43 Err(_) => None,
44 }
45 };
46
47 IndexNode::Range(None, end_index, step_value)
48 }
49 _ => {
50 let start_index = literal::parse_literal(it)?;
51 match &it.current_token {
52 Some((Token::Colon, _, _)) => {
53 it.read_token();
54 let end_index = if let Some((Token::Colon, _, _)) = &it.current_token {
55 it.read_token();
56 None
57 } else {
58 Some(literal::parse_literal(it)?)
59 };
60
61 let step_value = if let Some((Token::Colon, _, _)) = &it.current_token {
62 it.read_token();
63 Some(literal::parse_literal(it)?)
64 } else {
65 match literal::parse_literal(it) {
66 Ok(step) => Some(step),
67 Err(_) => None,
68 }
69 };
70
71 IndexNode::Range(Some(start_index), end_index, step_value)
72 }
73 Some((Token::Comma, _, _)) => {
74 it.read_token();
75
76 let mut indexs = vec![start_index];
77
78 while let Some((Token::Comma, _, _)) = &it.current_token {
79 it.read_token();
80 let index = literal::parse_literal(it)?;
81 indexs.push(index);
82 }
83
84 IndexNode::Multiple(indexs)
85 }
86 _ => IndexNode::Single(start_index),
87 }
88 }
89 };
90
91 it.decrease_depth();
92
93 Ok(Node::IndexSelection(Box::new(node), Box::new(index_node)))
94}