Skip to main content

surql_parser/upstream/syn/parser/
object.rs

1use super::mac::unexpected;
2use crate::upstream::sql::literal::ObjectEntry;
3use crate::upstream::sql::{Block, Expr, Literal};
4use crate::upstream::syn::lexer::compound;
5use crate::upstream::syn::parser::mac::expected;
6use crate::upstream::syn::parser::{ParseResult, Parser, enter_object_recursion};
7use crate::upstream::syn::token::{Span, TokenKind, t};
8use reblessive::Stk;
9impl Parser<'_> {
10	/// Parse an production which starts with an `{`
11	///
12	/// Either a block statemnt, a object or geometry.
13	pub(super) async fn parse_object_like(
14		&mut self,
15		stk: &mut Stk,
16		start: Span,
17	) -> ParseResult<Expr> {
18		if self.eat(t!("}")) {
19			return Ok(Expr::Literal(Literal::Object(Vec::new())));
20		}
21		if self.eat(t!(",")) {
22			self.expect_closing_delimiter(t!("}"), start)?;
23			return Ok(Expr::Literal(Literal::Set(Vec::new())));
24		}
25		if self.eat(t!(";")) {
26			let block = self.parse_block_remaining(stk, start, Vec::new()).await?;
27			return Ok(Expr::Block(Box::new(block)));
28		}
29		if let t!("\"")
30		| t!("'")
31		| TokenKind::Identifier
32		| TokenKind::Digits
33		| TokenKind::Keyword(_)
34		| TokenKind::Language(_)
35		| TokenKind::Algorithm(_)
36		| TokenKind::Distance(_)
37		| TokenKind::VectorType(_) = self.peek().kind
38			&& let Some(x) = self
39				.speculate(stk, async |stk, this| {
40					enter_object_recursion!(
41						this = this => { let Ok(key) = this.parse_object_key() else {
42						return Ok(None) }; if ! this.eat(t!(":")) { return Ok(None) }
43						let value = stk.run(| stk | this.parse_expr_inherit(stk)).
44						await ?; let res = vec![ObjectEntry { key, value }]; if this
45						.eat(t!(",")) { this.parse_object_inner(stk, start, res).
46						await .map(Some) } else { this
47						.expect_closing_delimiter(t!("}"), start) ?; Ok(Some(res)) }
48						}
49					)
50				})
51				.await?
52		{
53			return Ok(Expr::Literal(Literal::Object(x)));
54		}
55		let statement_peek = self.peek();
56		let first_expr = stk.run(|stk| self.parse_expr_inherit(stk)).await?;
57		let first_expr_span = statement_peek.span.covers(self.last_span());
58		let next = self.peek();
59		match next.kind {
60			t!(",") => {
61				self.pop_peek();
62				let mut exprs = self.parse_set(stk, start).await?;
63				exprs.insert(0, first_expr);
64				Ok(Expr::Literal(Literal::Set(exprs)))
65			}
66			t!("}") => {
67				self.pop_peek();
68				if statement_peek.kind != t!("(") {
69					Self::reject_letless_let(&first_expr, first_expr_span)?;
70				}
71				Ok(Expr::Block(Box::new(Block(vec![first_expr]))))
72			}
73			_ => {
74				if statement_peek.kind != t!("(") {
75					Self::reject_letless_let(&first_expr, first_expr_span)?;
76				}
77				let block = self
78					.parse_block_remaining(stk, start, vec![first_expr])
79					.await?;
80				Ok(Expr::Block(Box::new(block)))
81			}
82		}
83	}
84	/// Parses an object.
85	///
86	/// Expects the span of the starting `{` as an argument.
87	///
88	/// # Parser state
89	/// Expects the first `{` to already have been eaten.
90	pub(super) async fn parse_object(
91		&mut self,
92		stk: &mut Stk,
93		start: Span,
94	) -> ParseResult<Vec<ObjectEntry>> {
95		enter_object_recursion!(
96			this = self => { return this.parse_object_inner(stk, start, Vec::new()).
97			await; }
98		)
99	}
100	pub(super) async fn parse_object_inner(
101		&mut self,
102		stk: &mut Stk,
103		start: Span,
104		mut res: Vec<ObjectEntry>,
105	) -> ParseResult<Vec<ObjectEntry>> {
106		loop {
107			if self.eat(t!("}")) {
108				return Ok(res);
109			}
110			let (key, value) = self.parse_object_entry(stk).await?;
111			res.push(ObjectEntry { key, value });
112			if !self.eat(t!(",")) {
113				self.expect_closing_delimiter(t!("}"), start)?;
114				return Ok(res);
115			}
116		}
117	}
118	pub async fn parse_set(&mut self, stk: &mut Stk, start: Span) -> ParseResult<Vec<Expr>> {
119		enter_object_recursion!(
120			this = self => { return this.parse_set_inner(stk, start). await; }
121		)
122	}
123	async fn parse_set_inner(&mut self, stk: &mut Stk, start: Span) -> ParseResult<Vec<Expr>> {
124		let mut res = Vec::new();
125		loop {
126			if self.eat(t!("}")) {
127				return Ok(res);
128			}
129			let value = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
130			res.push(value);
131			if !self.eat(t!(",")) {
132				self.expect_closing_delimiter(t!("}"), start)?;
133				return Ok(res);
134			}
135		}
136	}
137	/// Parses a block of statements.
138	///
139	/// # Parser State
140	/// Expects the starting `{` to have already been eaten and its span to be
141	/// handed to this functions as the `start` parameter.
142	pub async fn parse_block(&mut self, stk: &mut Stk, start: Span) -> ParseResult<Block> {
143		self.parse_block_remaining(stk, start, Vec::new()).await
144	}
145	/// Parses the remaining statements in a block.
146	///
147	/// # Parser State
148	/// Expects the starting `{` to have already been eaten and its span to be
149	/// handed to this functions as the `start` parameter.
150	///
151	/// Any statements which have already been parsed can be passed in as the `existing_stmts`
152	/// parameter.
153	async fn parse_block_remaining(
154		&mut self,
155		stk: &mut Stk,
156		start: Span,
157		mut existing_stmts: Vec<Expr>,
158	) -> ParseResult<Block> {
159		loop {
160			while self.eat(t!(";")) {}
161			if self.eat(t!("}")) {
162				break;
163			}
164			let stmt = self.parse_block_expr(stk).await?;
165			existing_stmts.push(stmt);
166			if !self.eat(t!(";")) {
167				self.expect_closing_delimiter(t!("}"), start)?;
168				break;
169			}
170		}
171		Ok(Block(existing_stmts))
172	}
173	async fn parse_block_expr(&mut self, stk: &mut Stk) -> ParseResult<Expr> {
174		let peek = self.peek().kind;
175		let before = self.recent_span();
176		let stmt = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
177		let span = before.covers(self.last_span());
178		if peek != t!("(") {
179			Self::reject_letless_let(&stmt, span)?;
180		}
181		Ok(stmt)
182	}
183	/// Parse a single entry in the object, i.e. `field: value + 1` in the
184	/// object `{ field: value + 1 }`
185	async fn parse_object_entry(&mut self, stk: &mut Stk) -> ParseResult<(String, Expr)> {
186		let text = self.parse_object_key()?;
187		expected!(self, t!(":"));
188		let value = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
189		Ok((text, value))
190	}
191	/// Parses the key of an object, i.e. `field` in the object `{ field: 1 }`.
192	pub(super) fn parse_object_key(&mut self) -> ParseResult<String> {
193		let token = self.peek();
194		match token.kind {
195			x if Self::kind_is_keyword_like(x) => {
196				self.pop_peek();
197				let str = self.span_str(token.span);
198				Ok(str.to_string())
199			}
200			TokenKind::Identifier => self.parse_ident(),
201			t!("\"") | t!("'") => Ok(self.parse_string_lit()?),
202			TokenKind::Digits => {
203				self.pop_peek();
204				let span = self.lex_compound(token, compound::number)?.span;
205				let str = self.span_str(span);
206				Ok(str.to_string())
207			}
208			_ => unexpected!(self, token, "an object key"),
209		}
210	}
211}