surql_parser/upstream/syn/parser/
function.rs1use super::{ParseResult, Parser};
2use crate::upstream::sql::{Expr, Function, FunctionCall, Model};
3use crate::upstream::syn::error::{bail, syntax_error};
4use crate::upstream::syn::parser::mac::{expected, expected_whitespace, unexpected};
5use crate::upstream::syn::token::{TokenKind, t};
6use reblessive::Stk;
7impl Parser<'_> {
8 pub async fn parse_function_name(&mut self) -> ParseResult<Function> {
9 let peek = self.peek();
10 let fnc = match peek.kind {
11 t!("fn") => {
12 self.pop_peek();
13 expected!(self, t!("::"));
14 let mut name = self.parse_ident()?;
15 while self.eat(t!("::")) {
16 name.push_str("::");
17 name.push_str(self.parse_ident_str()?);
18 }
19 Function::Custom(name)
20 }
21 t!("mod") => {
22 self.pop_peek();
23 if !self.settings.surrealism_enabled {
24 bail!(
25 "Experimental capability `surrealism` is not enabled", @ self
26 .last_span() => "Use of `mod::` is still experimental"
27 )
28 }
29 expected!(self, t!("::"));
30 let name = self.parse_ident()?;
31 let sub = if self.eat(t!("::")) {
32 Some(self.parse_ident()?)
33 } else {
34 None
35 };
36 Function::Module(name, sub)
37 }
38 t!("silo") => {
39 self.pop_peek();
40 if !self.settings.surrealism_enabled {
41 bail!(
42 "Experimental capability `surrealism` is not enabled", @ self
43 .last_span() => "Use of `silo::` is still experimental"
44 )
45 }
46 expected!(self, t!("::"));
47 let org = self.parse_ident()?;
48 expected!(self, t!("::"));
49 let pkg = self.parse_ident()?;
50 expected!(self, t!("<"));
51 let major = self.parse_version_digits()?;
52 expected!(self, t!("."));
53 let minor = self.parse_version_digits()?;
54 expected!(self, t!("."));
55 let patch = self.parse_version_digits()?;
56 expected!(self, t!(">"));
57 let sub = if self.eat(t!("::")) {
58 Some(self.parse_ident()?)
59 } else {
60 None
61 };
62 Function::Silo {
63 org,
64 pkg,
65 major,
66 minor,
67 patch,
68 sub,
69 }
70 }
71 t!("ml") => {
72 self.pop_peek();
73 expected!(self, t!("::"));
74 let mut name = self.parse_ident()?;
75 while self.eat(t!("::")) {
76 name.push_str("::");
77 name.push_str(self.parse_ident_str()?);
78 }
79 let (major, minor, patch) = self.parse_model_version()?;
80 let version = format!("{}.{}.{}", major, minor, patch);
81 Function::Model(Model { name, version })
82 }
83 TokenKind::Identifier => {
84 let mut name = self.parse_ident()?;
85 while self.eat(t!("::")) {
86 name.push_str("::");
87 name.push_str(self.parse_ident_str()?)
88 }
89 Function::Normal(name)
90 }
91 x if Self::kind_is_keyword_like(x) => {
92 self.pop_peek();
93 let mut name = self.lexer.span_str(peek.span).to_string();
94 while self.eat(t!("::")) {
95 name.push_str("::");
96 name.push_str(self.parse_ident_str()?)
97 }
98 Function::Normal(name)
99 }
100 _ => unexpected!(self, self.peek(), "a function name"),
101 };
102 Ok(fnc)
103 }
104 pub(super) async fn parse_custom_function(
108 &mut self,
109 stk: &mut Stk,
110 ) -> ParseResult<FunctionCall> {
111 expected!(self, t!("::"));
112 let mut name = self.parse_ident()?;
113 while self.eat(t!("::")) {
114 name.push_str("::");
115 name.push_str(self.parse_ident_str()?)
116 }
117 expected!(self, t!("(")).span;
118 let args = self.parse_function_args(stk).await?;
119 let name = Function::Custom(name);
120 Ok(FunctionCall {
121 receiver: name,
122 arguments: args,
123 })
124 }
125 pub(super) async fn parse_module_function(
129 &mut self,
130 stk: &mut Stk,
131 ) -> ParseResult<FunctionCall> {
132 if !self.settings.surrealism_enabled {
133 bail!(
134 "Experimental capability `surrealism` is not enabled", @ self.last_span()
135 => "Use of `mod::` is still experimental"
136 )
137 }
138 expected!(self, t!("::"));
139 let name = self.parse_ident()?;
140 let sub = if self.eat(t!("::")) {
141 Some(self.parse_ident()?)
142 } else {
143 None
144 };
145 expected!(self, t!("(")).span;
146 let args = self.parse_function_args(stk).await?;
147 let name = Function::Module(name, sub);
148 Ok(FunctionCall {
149 receiver: name,
150 arguments: args,
151 })
152 }
153 pub(super) async fn parse_silo_function(&mut self, stk: &mut Stk) -> ParseResult<FunctionCall> {
157 if !self.settings.surrealism_enabled {
158 bail!(
159 "Experimental capability `surrealism` is not enabled", @ self.last_span()
160 => "Use of `silo::` is still experimental"
161 )
162 }
163 expected!(self, t!("::"));
164 let org = self.parse_ident()?;
165 expected!(self, t!("::"));
166 let pkg = self.parse_ident()?;
167 expected!(self, t!("<"));
168 let major = self.parse_version_digits()?;
169 expected!(self, t!("."));
170 let minor = self.parse_version_digits()?;
171 expected!(self, t!("."));
172 let patch = self.parse_version_digits()?;
173 expected!(self, t!(">"));
174 let sub = if self.eat(t!("::")) {
175 Some(self.parse_ident()?)
176 } else {
177 None
178 };
179 expected!(self, t!("(")).span;
180 let args = self.parse_function_args(stk).await?;
181 let name = Function::Silo {
182 org,
183 pkg,
184 major,
185 minor,
186 patch,
187 sub,
188 };
189 Ok(FunctionCall {
190 receiver: name,
191 arguments: args,
192 })
193 }
194 pub(super) async fn parse_function_args(&mut self, stk: &mut Stk) -> ParseResult<Vec<Expr>> {
195 let start = self.last_span();
196 let mut args = Vec::new();
197 loop {
198 if self.eat(t!(")")) {
199 break;
200 }
201 let arg = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
202 args.push(arg);
203 if !self.eat(t!(",")) {
204 self.expect_closing_delimiter(t!(")"), start)?;
205 break;
206 }
207 }
208 Ok(args)
209 }
210 pub fn parse_version_digits(&mut self) -> ParseResult<u32> {
211 let token = self.next();
212 match token.kind {
213 TokenKind::Digits => self
214 .span_str(token.span)
215 .parse::<u32>()
216 .map_err(|e| syntax_error!("Failed to parse model version: {e}", @ token.span)),
217 _ => unexpected!(self, token, "an integer"),
218 }
219 }
220 pub(super) fn parse_model_version(&mut self) -> ParseResult<(u32, u32, u32)> {
221 let start = expected!(self, t!("<")).span;
222 let major: u32 = self.parse_version_digits()?;
223 expected_whitespace!(self, t!("."));
224 let minor: u32 = self.parse_version_digits()?;
225 expected_whitespace!(self, t!("."));
226 let patch: u32 = self.parse_version_digits()?;
227 self.expect_closing_delimiter(t!(">"), start)?;
228 Ok((major, minor, patch))
229 }
230 pub(super) async fn parse_model(&mut self, stk: &mut Stk) -> ParseResult<FunctionCall> {
234 expected!(self, t!("::"));
235 let mut name = self.parse_ident()?;
236 while self.eat(t!("::")) {
237 name.push_str("::");
238 name.push_str(self.parse_ident_str()?)
239 }
240 let (major, minor, patch) = self.parse_model_version()?;
241 let start = expected!(self, t!("(")).span;
242 let mut args = Vec::new();
243 loop {
244 if self.eat(t!(")")) {
245 break;
246 }
247 let arg = stk.run(|ctx| self.parse_expr_inherit(ctx)).await?;
248 args.push(arg);
249 if !self.eat(t!(",")) {
250 self.expect_closing_delimiter(t!(")"), start)?;
251 break;
252 }
253 }
254 let func = Function::Model(Model {
255 name,
256 version: format!("{}.{}.{}", major, minor, patch),
257 });
258 Ok(FunctionCall {
259 receiver: func,
260 arguments: args,
261 })
262 }
263}