1use crate::prelude::*;
2use std::collections::HashMap;
3
4impl Runtime {
5 pub fn parse_obj(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
6 self.parse_obj_hierarchy0(tb)
7 }
8
9 fn parse_obj_hierarchy0(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
11 let left = self.parse_obj_hierarchy1(tb)?;
12 if tb.exceed_end_of_head() {
13 return Ok(left);
14 }
15 if tb.current_token_is_equal_to(INFIX_FN_NAME_SIGN) {
16 tb.skip()?; let fn_name = self.parse_identifier_or_identifier_with_mod(tb)?;
18 let right = self.parse_obj(tb)?;
19
20 if is_key_symbol_or_keyword(&fn_name.to_string()) {
21 return match fn_name.to_string().as_str() {
22 UNION => Ok(Union::new(left, right).into()),
23 INTERSECT => Ok(Intersect::new(left, right).into()),
24 SET_MINUS => Ok(SetMinus::new(left, right).into()),
25 SET_DIFF => Ok(SetDiff::new(left, right).into()),
26 RANGE => Ok(Range::new(left, right).into()),
27 CLOSED_RANGE => Ok(ClosedRange::new(left, right).into()),
28 PROJ => Ok(Proj::new(left, right).into()),
29 _ => Err(RuntimeError::from(ParseRuntimeError(
30 RuntimeErrorStruct::new_with_msg_and_line_file(
31 format!("{} does not support infix function syntax", fn_name),
32 tb.line_file.clone(),
33 ),
34 ))),
35 };
36 }
37
38 let body = vec![vec![Box::new(left), Box::new(right)]];
39
40 let head = FnObjHead::given_an_atom_return_a_fn_obj_head(fn_name).ok_or_else(|| {
41 RuntimeError::from(ParseRuntimeError(RuntimeErrorStruct::new_with_msg_and_line_file("infix (backtick) expects an identifier or single field-access name for the function"
42 .to_string(), tb.line_file.clone())))
43 })?;
44 Ok(FnObj::new(head, body).into())
45 } else {
46 Ok(left)
47 }
48 }
49
50 fn parse_obj_hierarchy1(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
52 let mut left = self.parse_obj_hierarchy2(tb)?;
53 loop {
54 if tb.exceed_end_of_head() {
55 return Ok(left);
56 }
57 if tb.current_token_is_equal_to(ADD) {
58 tb.skip()?;
59 let right = self.parse_obj_hierarchy2(tb)?;
60
61 left = Add::new(left, right).into();
62 } else if tb.current_token_is_equal_to(SUB) {
63 tb.skip()?;
64 let right = self.parse_obj_hierarchy2(tb)?;
65 left = Sub::new(left, right).into();
66 } else {
67 return Ok(left);
68 }
69 }
70 }
71
72 fn parse_obj_hierarchy2(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
74 let mut left = self.parse_obj_hierarchy3(tb)?;
75 loop {
76 if tb.exceed_end_of_head() {
77 return Ok(left);
78 }
79 if tb.current_token_is_equal_to(MUL) {
80 tb.skip()?;
81 let right = self.parse_obj_hierarchy3(tb)?;
82 left = Mul::new(left, right).into();
83 } else if tb.current_token_is_equal_to(DIV) {
84 tb.skip()?;
85 let right = self.parse_obj_hierarchy3(tb)?;
86 left = Div::new(left, right).into();
87 } else if tb.current_token_is_equal_to(MOD) {
88 tb.skip()?;
89 let right = self.parse_obj_hierarchy3(tb)?;
90 left = Mod::new(left, right).into();
91 } else if tb.current_token_is_equal_to(MATRIX_SCALAR_MUL) {
92 tb.skip()?;
93 let right = self.parse_obj_hierarchy3(tb)?;
94 left = MatrixScalarMul::new(left, right).into();
95 } else {
96 return Ok(left);
97 }
98 }
99 }
100
101 fn parse_obj_hierarchy3(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
103 let left = self.parse_obj_hierarchy4(tb)?;
104 if tb.exceed_end_of_head() {
105 return Ok(left);
106 }
107 if tb.current_token_is_equal_to(POW) {
108 tb.skip()?;
109 let right = self.parse_obj_hierarchy3(tb)?; Ok(Pow::new(left, right).into())
111 } else if tb.current_token_is_equal_to(MATRIX_POW) {
112 tb.skip()?;
113 let right = self.parse_obj_hierarchy3(tb)?;
114 Ok(MatrixPow::new(left, right).into())
115 } else if tb.current_token_is_equal_to(MATRIX_MUL) {
116 tb.skip()?;
117 let right = self.parse_obj_hierarchy3(tb)?;
118 Ok(MatrixMul::new(left, right).into())
119 } else if tb.current_token_is_equal_to(MATRIX_SUB) {
120 tb.skip()?;
121 let right = self.parse_obj_hierarchy3(tb)?;
122 Ok(MatrixSub::new(left, right).into())
123 } else if tb.current_token_is_equal_to(MATRIX_ADD) {
124 tb.skip()?;
125 let right = self.parse_obj_hierarchy3(tb)?;
126 Ok(MatrixAdd::new(left, right).into())
127 } else {
128 Ok(left)
129 }
130 }
131
132 fn parse_obj_hierarchy4(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
134 let mut left = self.parse_obj_hierarchy5(tb)?;
135 loop {
136 if tb.current_token_is_equal_to(LEFT_BRACKET) {
137 tb.skip_token(LEFT_BRACKET)?;
138 let obj = self.parse_obj(tb)?;
139 tb.skip_token(RIGHT_BRACKET)?;
140 left = ObjAtIndex::new(left, obj).into();
141 } else {
142 return Ok(left);
143 }
144 }
145 }
146
147 fn parse_obj_hierarchy5(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
149 let left = self.parse_obj_hierarchy6(tb)?;
150
151 if tb.current_token_is_equal_to(DOT_DOT_DOT) {
152 tb.skip_token(DOT_DOT_DOT)?;
153 let right = self.parse_obj_hierarchy1(tb)?;
154 Ok(ClosedRange::new(left, right).into())
155 } else {
156 Ok(left)
157 }
158 }
159
160 fn parse_obj_hierarchy6(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
162 if tb.current_token_is_equal_to(LEFT_CURLY_BRACE) {
163 self.parse_set_builder_or_set_list(tb)
164 } else if tb.current_token_is_equal_to(LEFT_BRACKET) {
165 tb.skip_token(LEFT_BRACKET)?;
166 if tb.current_token_is_equal_to(LEFT_BRACKET) {
167 let mut rows: Vec<Vec<Obj>> = vec![];
168 loop {
169 tb.skip_token(LEFT_BRACKET)?;
170 let mut row: Vec<Obj> = vec![];
171 if !tb.current_token_is_equal_to(RIGHT_BRACKET) {
172 row.push(self.parse_obj(tb)?);
173 while tb.current_token_is_equal_to(COMMA) {
174 tb.skip_token(COMMA)?;
175 row.push(self.parse_obj(tb)?);
176 }
177 }
178 tb.skip_token(RIGHT_BRACKET)?;
179 rows.push(row);
180 if tb.current_token_is_equal_to(COMMA) {
181 tb.skip_token(COMMA)?;
182 if !tb.current_token_is_equal_to(LEFT_BRACKET) {
183 return Err(RuntimeError::from(ParseRuntimeError(
184 RuntimeErrorStruct::new_with_msg_and_line_file(
185 "matrix literal: expected `[` after `,` between rows"
186 .to_string(),
187 tb.line_file.clone(),
188 ),
189 )));
190 }
191 } else if tb.current_token_is_equal_to(RIGHT_BRACKET) {
192 tb.skip_token(RIGHT_BRACKET)?;
193 return Ok(MatrixListObj::new(rows).into());
194 } else {
195 return Err(RuntimeError::from(ParseRuntimeError(
196 RuntimeErrorStruct::new_with_msg_and_line_file(
197 "matrix literal: expected `,` or closing `]`".to_string(),
198 tb.line_file.clone(),
199 ),
200 )));
201 }
202 }
203 } else if tb.current_token_is_equal_to(RIGHT_BRACKET) {
204 tb.skip_token(RIGHT_BRACKET)?;
205 let list = FiniteSeqListObj::new(vec![]);
206 let mut result: Obj = list.clone().into();
207 let head = FnObjHead::FiniteSeqListObj(list);
208 let mut body_vectors: Vec<Vec<Box<Obj>>> = vec![];
209 while !tb.exceed_end_of_head() && tb.current()? == LEFT_BRACE {
210 let args = self.parse_fn_obj_arg_group(tb)?;
211 let group: Vec<Box<Obj>> = args.into_iter().map(Box::new).collect();
212 body_vectors.push(group);
213 }
214 if !body_vectors.is_empty() {
215 result = FnObj::new(head, body_vectors).into();
216 }
217 Ok(result)
218 } else {
219 let mut objs = vec![self.parse_obj(tb)?];
220 while tb.current_token_is_equal_to(COMMA) {
221 tb.skip_token(COMMA)?;
222 objs.push(self.parse_obj(tb)?);
223 }
224 tb.skip_token(RIGHT_BRACKET)?;
225 let list = FiniteSeqListObj::new(objs);
226 let mut result: Obj = list.clone().into();
227 let head = FnObjHead::FiniteSeqListObj(list);
228 let mut body_vectors: Vec<Vec<Box<Obj>>> = vec![];
229 while !tb.exceed_end_of_head() && tb.current()? == LEFT_BRACE {
230 let args = self.parse_fn_obj_arg_group(tb)?;
231 let group: Vec<Box<Obj>> = args.into_iter().map(Box::new).collect();
232 body_vectors.push(group);
233 }
234 if !body_vectors.is_empty() {
235 result = FnObj::new(head, body_vectors).into();
236 }
237 Ok(result)
238 }
239 } else if tb.current_token_is_equal_to(FN_LOWER_CASE) {
240 tb.skip_token(FN_LOWER_CASE)?;
241 Ok(self.parse_fn_set(tb)?.into())
242 } else if tb.current_token_is_equal_to(ANONYMOUS_FN_PREFIX) {
243 let mut result = self.parse_anonymous_fn(tb)?;
244 if let Obj::AnonymousFn(anon) = &result {
245 let mut body_vectors: Vec<Vec<Box<Obj>>> = vec![];
246 while !tb.exceed_end_of_head() && tb.current()? == LEFT_BRACE {
247 let args = self.parse_fn_obj_arg_group(tb)?;
248 let group: Vec<Box<Obj>> = args.into_iter().map(Box::new).collect();
249 body_vectors.push(group);
250 }
251 if !body_vectors.is_empty() {
252 let head = FnObjHead::AnonymousFnLiteral(Box::new(anon.clone()));
253 result = FnObj::new(head, body_vectors).into();
254 }
255 }
256 Ok(result)
257 } else {
258 self.parse_number_or_primary_obj_or_fn_obj_with_minus_prefix(tb)
259 }
260 }
261
262 pub fn parse_anonymous_fn(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
267 tb.skip_token(ANONYMOUS_FN_PREFIX)?;
268 if tb.current_token_is_equal_to(LEFT_BRACE) {
269 let built = self.run_in_local_parsing_time_name_scope(|this| {
270 tb.skip_token(LEFT_BRACE)?;
271 let mut params_def_with_set: Vec<ParamGroupWithSet> = vec![];
272 loop {
273 let param = parse_synthetically_correct_identifier_string(tb)?;
274 let mut current_params = vec![param];
275
276 while tb.current_token_is_equal_to(COMMA) {
277 tb.skip_token(COMMA)?;
278 current_params.push(parse_synthetically_correct_identifier_string(tb)?);
279 }
280
281 let param_group = if tb.current_token_is_equal_to(COLON) {
282 ParamGroupWithSet::new(current_params, StandardSet::R.into())
283 } else {
284 ParamGroupWithSet::new(current_params, this.parse_obj(tb)?)
285 };
286 this.parsing_free_param_collection.begin_scope(
287 ParamObjType::FnSet,
288 ¶m_group.params,
289 tb.line_file.clone(),
290 )?;
291
292 params_def_with_set.push(param_group);
293
294 if tb.current_token_is_equal_to(COMMA) {
295 tb.skip_token(COMMA)?;
296 continue;
297 } else if tb.current_token_is_equal_to(COLON) {
298 break;
299 } else if tb.current_token_is_equal_to(RIGHT_BRACE) {
300 break;
301 } else {
302 return Err(RuntimeError::from(ParseRuntimeError(
303 RuntimeErrorStruct::new_with_msg_and_line_file("anonymous fn: expected `,`, `:`, or closing `)` after parameter group"
304 .to_string(), tb.line_file.clone()),
305 )));
306 }
307 }
308
309 let all_fn_names = ParamGroupWithSet::collect_param_names(¶ms_def_with_set);
310
311 let mut dom_facts = vec![];
312 if tb.current_token_is_equal_to(COLON) {
313 tb.skip_token(COLON)?;
314 let cur = this.parse_or_and_chain_atomic_fact(tb)?;
315 dom_facts.push(cur);
316 while tb.current_token_is_equal_to(COMMA) {
317 tb.skip_token(COMMA)?;
318 let cur = this.parse_or_and_chain_atomic_fact(tb)?;
319 dom_facts.push(cur);
320 }
321 }
322
323 tb.skip_token(RIGHT_BRACE)?;
324 this.parsing_free_param_collection
326 .end_scope(ParamObjType::FnSet, &all_fn_names);
327 let ret_set_parsed = this.parse_obj(tb)?;
328 let equal_to = this.parse_in_local_free_param_scope(
329 ParamObjType::FnSet,
330 &all_fn_names,
331 tb.line_file.clone(),
332 |inner| {
333 tb.skip_token(LEFT_CURLY_BRACE)?;
334 let equal_to = inner.parse_obj(tb)?;
335 tb.skip_token(RIGHT_CURLY_BRACE)?;
336 Ok(equal_to)
337 },
338 )?;
339 let built =
340 this.new_anonymous_fn(params_def_with_set, dom_facts, ret_set_parsed, equal_to)?;
341 Ok(built)
342 })?;
343 Ok(built.into())
344 } else {
345 let set_obj = self.parse_and_reclassify_atom_as_free_param_obj(tb)?;
346 let built = self.run_in_local_parsing_time_name_scope(|this| {
347 tb.skip_token(LEFT_BRACE)?;
348 let mut params = vec![parse_synthetically_correct_identifier_string(tb)?];
349 while tb.current_token_is_equal_to(COMMA) {
350 tb.skip_token(COMMA)?;
351 params.push(parse_synthetically_correct_identifier_string(tb)?);
352 }
353 tb.skip_token(RIGHT_BRACE)?;
354 let param_group = ParamGroupWithSet::new(params, set_obj.clone());
355 let param_groups = vec![param_group.clone()];
356 let all_names = ParamGroupWithSet::collect_param_names(¶m_groups);
357 this.parsing_free_param_collection.begin_scope(
358 ParamObjType::FnSet,
359 &all_names,
360 tb.line_file.clone(),
361 )?;
362 tb.skip_token(LEFT_CURLY_BRACE)?;
363 let equal_to = this.parse_obj(tb)?;
364 tb.skip_token(RIGHT_CURLY_BRACE)?;
365 this.parsing_free_param_collection
366 .end_scope(ParamObjType::FnSet, &all_names);
367 this.new_anonymous_fn(vec![param_group], vec![], set_obj, equal_to)
368 })?;
369 Ok(built.into())
370 }
371 }
372
373 pub fn parse_fn_set(&mut self, tb: &mut TokenBlock) -> Result<FnSet, RuntimeError> {
374 let fn_set = self.run_in_local_parsing_time_name_scope(|this| {
375 tb.skip_token(LEFT_BRACE)?;
376 let mut params_def_with_set: Vec<ParamGroupWithSet> = vec![];
377 loop {
378 let param = parse_synthetically_correct_identifier_string(tb)?;
379 let mut current_params = vec![param];
380
381 while tb.current_token_is_equal_to(COMMA) {
382 tb.skip_token(COMMA)?;
383 current_params.push(parse_synthetically_correct_identifier_string(tb)?);
384 }
385
386 let param_group = ParamGroupWithSet::new(current_params, this.parse_obj(tb)?);
387 this.parsing_free_param_collection.begin_scope(
388 ParamObjType::FnSet,
389 ¶m_group.params,
390 tb.line_file.clone(),
391 )?;
392
393 params_def_with_set.push(param_group);
394
395 if tb.current_token_is_equal_to(COMMA) {
396 tb.skip_token(COMMA)?;
397 continue;
398 } else if tb.current_token_is_equal_to(COLON) {
399 break;
400 } else if tb.current_token_is_equal_to(RIGHT_BRACE) {
401 break;
402 } else {
403 return Err(RuntimeError::from(ParseRuntimeError(
404 RuntimeErrorStruct::new_with_msg_and_line_file(
405 "Expected comma or colon".to_string(),
406 tb.line_file.clone(),
407 ),
408 )));
409 }
410 }
411
412 let all_fn_names = ParamGroupWithSet::collect_param_names(¶ms_def_with_set);
413
414 let mut dom_facts = vec![];
415 if tb.current_token_is_equal_to(COLON) {
416 tb.skip_token(COLON)?;
417 let cur = this.parse_or_and_chain_atomic_fact(tb)?;
418 dom_facts.push(cur);
419 while tb.current_token_is_equal_to(COMMA) {
420 tb.skip_token(COMMA)?;
421 let cur = this.parse_or_and_chain_atomic_fact(tb)?;
422 dom_facts.push(cur);
423 }
424 }
425
426 tb.skip_token(RIGHT_BRACE)?;
427 this.parsing_free_param_collection
429 .end_scope(ParamObjType::FnSet, &all_fn_names);
430 let ret_set_parsed = this.parse_obj(tb)?;
431 let built = this.new_fn_set(params_def_with_set, dom_facts, ret_set_parsed);
432 Ok(FnSetOrFnSetClause::FnSet(built?))
433 });
434 match fn_set {
435 Ok(fn_set) => match fn_set {
436 FnSetOrFnSetClause::FnSet(fn_set) => Ok(fn_set),
437 FnSetOrFnSetClause::FnSetClause(_) => {
438 panic!("FnSetOrFnSetClause::FnSetClause should not be returned");
439 }
440 },
441 Err(e) => Err(e),
442 }
443 }
444
445 pub fn parse_fn_set_clause(
446 &mut self,
447 tb: &mut TokenBlock,
448 ) -> Result<FnSetClause, RuntimeError> {
449 let clause = self.run_in_local_parsing_time_name_scope(|this| {
450 tb.skip_token(LEFT_BRACE)?;
451 let mut params_def_with_set: Vec<ParamGroupWithSet> = vec![];
452 loop {
453 let param = parse_synthetically_correct_identifier_string(tb)?;
454 let mut current_params = vec![param];
455
456 while tb.current_token_is_equal_to(COMMA) {
457 tb.skip_token(COMMA)?;
458 current_params.push(parse_synthetically_correct_identifier_string(tb)?);
459 }
460
461 let param_group = ParamGroupWithSet::new(current_params, this.parse_obj(tb)?);
462 this.parsing_free_param_collection.begin_scope(
463 ParamObjType::FnSet,
464 ¶m_group.params,
465 tb.line_file.clone(),
466 )?;
467
468 params_def_with_set.push(param_group);
469
470 if tb.current_token_is_equal_to(COMMA) {
471 tb.skip_token(COMMA)?;
472 continue;
473 } else if tb.current_token_is_equal_to(COLON) {
474 break;
475 } else if tb.current_token_is_equal_to(RIGHT_BRACE) {
476 break;
477 } else {
478 return Err(RuntimeError::from(ParseRuntimeError(
479 RuntimeErrorStruct::new_with_msg_and_line_file(
480 "Expected comma or colon".to_string(),
481 tb.line_file.clone(),
482 ),
483 )));
484 }
485 }
486
487 let all_fn_names = ParamGroupWithSet::collect_param_names(¶ms_def_with_set);
488
489 let mut dom_facts = vec![];
490 if tb.current_token_is_equal_to(COLON) {
491 tb.skip_token(COLON)?;
492 let cur = this.parse_or_and_chain_atomic_fact(tb)?;
493 dom_facts.push(cur);
494 while tb.current_token_is_equal_to(COMMA) {
495 tb.skip_token(COMMA)?;
496 let cur = this.parse_or_and_chain_atomic_fact(tb)?;
497 dom_facts.push(cur);
498 }
499 }
500
501 tb.skip_token(RIGHT_BRACE)?;
502 this.parsing_free_param_collection
504 .end_scope(ParamObjType::FnSet, &all_fn_names);
505 let ret_set_parsed = this.parse_obj(tb)?;
506 let clause_ok = FnSetClause::new(params_def_with_set, dom_facts, ret_set_parsed)?;
507 Ok(FnSetOrFnSetClause::FnSetClause(clause_ok))
508 });
509 match clause {
510 Ok(clause) => match clause {
511 FnSetOrFnSetClause::FnSetClause(clause) => Ok(clause),
512 FnSetOrFnSetClause::FnSet(_) => {
513 panic!("FnSetOrFnSetClause::FnSet should not be returned");
514 }
515 },
516 Err(e) => Err(e),
517 }
518 }
519
520 pub fn parse_number_or_primary_obj_or_fn_obj_with_minus_prefix(
521 &mut self,
522 tb: &mut TokenBlock,
523 ) -> Result<Obj, RuntimeError> {
524 if tb.current_token_is_equal_to(SUB) {
525 if minus_token_is_standalone_operator_obj(tb) {
526 tb.skip()?;
527 return Ok(Identifier::new(SUB.to_string()).into());
528 }
529 tb.skip()?;
530 let obj = self.parse_number_or_primary_obj_or_fn_obj(tb)?;
531 Ok(Mul::new(Number::new("-1".to_string()).into(), obj).into())
532 } else {
533 self.parse_number_or_primary_obj_or_fn_obj(tb)
534 }
535 }
536
537 fn parse_number_or_primary_obj_or_fn_obj(
539 &mut self,
540 tb: &mut TokenBlock,
541 ) -> Result<Obj, RuntimeError> {
542 let token = tb.current()?;
543
544 if token == LEFT_BRACE {
546 tb.skip()?;
547 let obj = self.parse_obj(tb)?;
548
549 if tb.current_token_is_equal_to(COMMA) {
550 let mut args = vec![obj];
551 while tb.current_token_is_equal_to(COMMA) {
552 tb.skip_token(COMMA)?;
553
554 args.push(self.parse_obj(tb)?);
555 }
556 tb.skip_token(RIGHT_BRACE)?;
557 return Ok(Tuple::new(args).into());
558 } else {
559 tb.skip_token(RIGHT_BRACE)?;
560 return Ok(obj);
561 }
562 }
563
564 if starts_with_digit(token) {
566 let number = tb.advance()?;
567 if tb.exceed_end_of_head() {
569 if !is_number(&number) {
570 return Err(RuntimeError::from(ParseRuntimeError(
571 RuntimeErrorStruct::new_with_msg_and_line_file(
572 format!("Invalid number: {}", number),
573 tb.line_file.clone(),
574 ),
575 )));
576 }
577 return Ok(Number::new(number).into());
578 }
579
580 if tb.current()? == DOT_AKA_FIELD_ACCESS_SIGN {
581 tb.skip()?;
582 let fraction = tb.advance()?;
583 let number = format!("{}{}{}", number, DOT_AKA_FIELD_ACCESS_SIGN, fraction);
584 if !is_number(&number) {
585 return Err(RuntimeError::from(ParseRuntimeError(
586 RuntimeErrorStruct::new_with_msg_and_line_file(
587 format!("Invalid number: {}", number),
588 tb.line_file.clone(),
589 ),
590 )));
591 }
592 return Ok(Number::new(number).into());
593 } else {
594 if !is_number(&number) {
595 return Err(RuntimeError::from(ParseRuntimeError(
596 RuntimeErrorStruct::new_with_msg_and_line_file(
597 format!("Invalid number: {}", number),
598 tb.line_file.clone(),
599 ),
600 )));
601 }
602 return Ok(Number::new(number).into());
603 }
604 }
605
606 let mut result = self.parse_primary_obj(tb)?;
608
609 let (head, mut body_vectors) = match &result {
611 Obj::Atom(AtomObj::Identifier(i)) => (FnObjHead::Identifier(i.clone()), vec![]),
612 Obj::Atom(AtomObj::IdentifierWithMod(m)) => {
613 (FnObjHead::IdentifierWithMod(m.clone()), vec![])
614 }
615 Obj::Atom(AtomObj::Forall(p)) => (FnObjHead::Forall(p.clone()), vec![]),
616 Obj::Atom(AtomObj::Exist(p)) => (FnObjHead::Exist(p.clone()), vec![]),
617 Obj::Atom(AtomObj::Def(p)) => (FnObjHead::DefHeader(p.clone()), vec![]),
618 Obj::Atom(AtomObj::SetBuilder(p)) => (FnObjHead::SetBuilder(p.clone()), vec![]),
619 Obj::Atom(AtomObj::FnSet(p)) => (FnObjHead::FnSet(p.clone()), vec![]),
620 Obj::Atom(AtomObj::Induc(p)) => (FnObjHead::Induc(p.clone()), vec![]),
621 Obj::Atom(AtomObj::DefAlgo(p)) => (FnObjHead::DefAlgo(p.clone()), vec![]),
622 Obj::Atom(AtomObj::DefStructField(_)) => return Ok(result),
623 Obj::AnonymousFn(anon) => (
624 FnObjHead::AnonymousFnLiteral(Box::new(anon.clone())),
625 vec![],
626 ),
627 Obj::FiniteSeqListObj(list) => (FnObjHead::FiniteSeqListObj(list.clone()), vec![]),
628 Obj::InstantiatedTemplateObj(t) => {
629 (FnObjHead::InstantiatedTemplateObj(t.clone()), vec![])
630 }
631 _ => return Ok(result),
632 };
633 while !tb.exceed_end_of_head() && tb.current()? == LEFT_BRACE {
634 let args = self.parse_fn_obj_arg_group(tb)?;
635 let group: Vec<Box<Obj>> = args.into_iter().map(Box::new).collect();
636 body_vectors.push(group);
637 }
638 if !body_vectors.is_empty() {
639 result = FnObj::new(head, body_vectors).into();
640 }
641 Ok(result)
642 }
643
644 fn parse_primary_obj(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
646 let tok = tb.current()?;
647
648 if tok == STRUCT_VIEW_PREFIX {
649 return self.parse_struct_view_obj(tb);
650 }
651 if tok == TEMPLATE_INSTANCE_PREFIX {
652 return self.parse_instantiated_template_obj(tb);
653 }
654 if tok == ABS {
655 tb.skip()?;
656 tb.skip_token(LEFT_BRACE)?;
657 let arg = self.parse_obj(tb)?;
658 tb.skip_token(RIGHT_BRACE)?;
659 return Ok(Abs::new(arg).into());
660 }
661 if tok == SQRT {
662 tb.skip()?;
663 tb.skip_token(LEFT_BRACE)?;
664 let arg = self.parse_obj(tb)?;
665 tb.skip_token(RIGHT_BRACE)?;
666 return Ok(Sqrt::new(arg).into());
667 }
668 if tok == MAX {
669 tb.skip()?;
670 let args = self.parse_braced_objs(tb)?;
671 if args.len() != 2 {
672 return Err(RuntimeError::from(ParseRuntimeError(
673 RuntimeErrorStruct::new_with_msg_and_line_file(
674 "max expects 2 arguments".to_string(),
675 tb.line_file.clone(),
676 ),
677 )));
678 }
679 let mut it = args.into_iter();
680 let left = it.next().ok_or_else(|| {
681 RuntimeError::from(ParseRuntimeError(
682 RuntimeErrorStruct::new_with_msg_and_line_file(
683 "max expects 2 arguments".to_string(),
684 tb.line_file.clone(),
685 ),
686 ))
687 })?;
688 let right = it.next().ok_or_else(|| {
689 RuntimeError::from(ParseRuntimeError(
690 RuntimeErrorStruct::new_with_msg_and_line_file(
691 "max expects 2 arguments".to_string(),
692 tb.line_file.clone(),
693 ),
694 ))
695 })?;
696 return Ok(Max::new(left, right).into());
697 }
698 if tok == MIN {
699 tb.skip()?;
700 let args = self.parse_braced_objs(tb)?;
701 if args.len() != 2 {
702 return Err(RuntimeError::from(ParseRuntimeError(
703 RuntimeErrorStruct::new_with_msg_and_line_file(
704 "min expects 2 arguments".to_string(),
705 tb.line_file.clone(),
706 ),
707 )));
708 }
709 let mut it = args.into_iter();
710 let left = it.next().ok_or_else(|| {
711 RuntimeError::from(ParseRuntimeError(
712 RuntimeErrorStruct::new_with_msg_and_line_file(
713 "min expects 2 arguments".to_string(),
714 tb.line_file.clone(),
715 ),
716 ))
717 })?;
718 let right = it.next().ok_or_else(|| {
719 RuntimeError::from(ParseRuntimeError(
720 RuntimeErrorStruct::new_with_msg_and_line_file(
721 "min expects 2 arguments".to_string(),
722 tb.line_file.clone(),
723 ),
724 ))
725 })?;
726 return Ok(Min::new(left, right).into());
727 }
728 if tok == LOG {
729 tb.skip()?;
730 let args = self.parse_braced_objs(tb)?;
731 if args.len() != 2 {
732 return Err(RuntimeError::from(ParseRuntimeError(
733 RuntimeErrorStruct::new_with_msg_and_line_file(
734 "log expects 2 arguments (base, argument)".to_string(),
735 tb.line_file.clone(),
736 ),
737 )));
738 }
739 let mut it = args.into_iter();
740 let base = it.next().ok_or_else(|| {
741 RuntimeError::from(ParseRuntimeError(
742 RuntimeErrorStruct::new_with_msg_and_line_file(
743 "log expects 2 arguments (base, argument)".to_string(),
744 tb.line_file.clone(),
745 ),
746 ))
747 })?;
748 let arg = it.next().ok_or_else(|| {
749 RuntimeError::from(ParseRuntimeError(
750 RuntimeErrorStruct::new_with_msg_and_line_file(
751 "log expects 2 arguments (base, argument)".to_string(),
752 tb.line_file.clone(),
753 ),
754 ))
755 })?;
756 return Ok(Log::new(base, arg).into());
757 }
758
759 if tok == UNION {
761 tb.skip()?;
762 let args = self.parse_braced_objs(tb)?;
763 if args.len() != 2 {
764 return Err(RuntimeError::from(ParseRuntimeError(
765 RuntimeErrorStruct::new_with_msg_and_line_file(
766 "union expects 2 arguments".to_string(),
767 tb.line_file.clone(),
768 ),
769 )));
770 }
771 let mut it = args.into_iter();
772 let left = it.next().ok_or_else(|| {
773 RuntimeError::from(ParseRuntimeError(
774 RuntimeErrorStruct::new_with_msg_and_line_file(
775 "union expects 2 arguments".to_string(),
776 tb.line_file.clone(),
777 ),
778 ))
779 })?;
780 let right = it.next().ok_or_else(|| {
781 RuntimeError::from(ParseRuntimeError(
782 RuntimeErrorStruct::new_with_msg_and_line_file(
783 "union expects 2 arguments".to_string(),
784 tb.line_file.clone(),
785 ),
786 ))
787 })?;
788 return Ok(Union::new(left, right).into());
789 }
790 if tok == INTERSECT {
791 tb.skip()?;
792 let args = self.parse_braced_objs(tb)?;
793 if args.len() != 2 {
794 return Err(RuntimeError::from(ParseRuntimeError(
795 RuntimeErrorStruct::new_with_msg_and_line_file(
796 "intersect expects 2 arguments".to_string(),
797 tb.line_file.clone(),
798 ),
799 )));
800 }
801 let mut it = args.into_iter();
802 let left = it.next().ok_or_else(|| {
803 RuntimeError::from(ParseRuntimeError(
804 RuntimeErrorStruct::new_with_msg_and_line_file(
805 "intersect expects 2 arguments".to_string(),
806 tb.line_file.clone(),
807 ),
808 ))
809 })?;
810 let right = it.next().ok_or_else(|| {
811 RuntimeError::from(ParseRuntimeError(
812 RuntimeErrorStruct::new_with_msg_and_line_file(
813 "intersect expects 2 arguments".to_string(),
814 tb.line_file.clone(),
815 ),
816 ))
817 })?;
818 return Ok(Intersect::new(left, right).into());
819 }
820 if tok == SET_MINUS {
821 tb.skip()?;
822 let args = self.parse_braced_objs(tb)?;
823 if args.len() != 2 {
824 return Err(RuntimeError::from(ParseRuntimeError(
825 RuntimeErrorStruct::new_with_msg_and_line_file(
826 "set_minus expects 2 arguments".to_string(),
827 tb.line_file.clone(),
828 ),
829 )));
830 }
831 let mut it = args.into_iter();
832 let left = it.next().ok_or_else(|| {
833 RuntimeError::from(ParseRuntimeError(
834 RuntimeErrorStruct::new_with_msg_and_line_file(
835 "set_minus expects 2 arguments".to_string(),
836 tb.line_file.clone(),
837 ),
838 ))
839 })?;
840 let right = it.next().ok_or_else(|| {
841 RuntimeError::from(ParseRuntimeError(
842 RuntimeErrorStruct::new_with_msg_and_line_file(
843 "set_minus expects 2 arguments".to_string(),
844 tb.line_file.clone(),
845 ),
846 ))
847 })?;
848 return Ok(SetMinus::new(left, right).into());
849 }
850 if tok == SET_DIFF {
851 tb.skip()?;
852 let args = self.parse_braced_objs(tb)?;
853 if args.len() != 2 {
854 return Err(RuntimeError::from(ParseRuntimeError(
855 RuntimeErrorStruct::new_with_msg_and_line_file(
856 "disjoint_union expects 2 arguments".to_string(),
857 tb.line_file.clone(),
858 ),
859 )));
860 }
861 let mut it = args.into_iter();
862 let left = it.next().ok_or_else(|| {
863 RuntimeError::from(ParseRuntimeError(
864 RuntimeErrorStruct::new_with_msg_and_line_file(
865 "disjoint_union expects 2 arguments".to_string(),
866 tb.line_file.clone(),
867 ),
868 ))
869 })?;
870 let right = it.next().ok_or_else(|| {
871 RuntimeError::from(ParseRuntimeError(
872 RuntimeErrorStruct::new_with_msg_and_line_file(
873 "disjoint_union expects 2 arguments".to_string(),
874 tb.line_file.clone(),
875 ),
876 ))
877 })?;
878 return Ok(SetDiff::new(left, right).into());
879 }
880 if tok == CAP {
881 tb.skip()?;
882 let args = self.parse_braced_objs(tb)?;
883 if args.len() != 1 {
884 return Err(RuntimeError::from(ParseRuntimeError(
885 RuntimeErrorStruct::new_with_msg_and_line_file(
886 "cap expects 1 argument".to_string(),
887 tb.line_file.clone(),
888 ),
889 )));
890 }
891 let mut it = args.into_iter();
892 let value = it.next().ok_or_else(|| {
893 RuntimeError::from(ParseRuntimeError(
894 RuntimeErrorStruct::new_with_msg_and_line_file(
895 "cap expects 1 argument".to_string(),
896 tb.line_file.clone(),
897 ),
898 ))
899 })?;
900 return Ok(Cap::new(value).into());
901 }
902 if tok == CUP {
903 tb.skip()?;
904 let args = self.parse_braced_objs(tb)?;
905 if args.len() != 1 {
906 return Err(RuntimeError::from(ParseRuntimeError(
907 RuntimeErrorStruct::new_with_msg_and_line_file(
908 "cup expects 1 argument".to_string(),
909 tb.line_file.clone(),
910 ),
911 )));
912 }
913 let mut it = args.into_iter();
914 let value = it.next().ok_or_else(|| {
915 RuntimeError::from(ParseRuntimeError(
916 RuntimeErrorStruct::new_with_msg_and_line_file(
917 "cup expects 1 argument".to_string(),
918 tb.line_file.clone(),
919 ),
920 ))
921 })?;
922 return Ok(Cup::new(value).into());
923 }
924 if tok == CHOOSE {
925 tb.skip()?;
926 let args = self.parse_braced_objs(tb)?;
927 if args.len() != 1 {
928 return Err(RuntimeError::from(ParseRuntimeError(
929 RuntimeErrorStruct::new_with_msg_and_line_file(
930 "choice expects 1 argument".to_string(),
931 tb.line_file.clone(),
932 ),
933 )));
934 }
935 let mut it = args.into_iter();
936 let value = it.next().ok_or_else(|| {
937 RuntimeError::from(ParseRuntimeError(
938 RuntimeErrorStruct::new_with_msg_and_line_file(
939 "choice expects 1 argument".to_string(),
940 tb.line_file.clone(),
941 ),
942 ))
943 })?;
944 return Ok(Choose::new(value).into());
945 }
946 if tok == PROJ {
947 tb.skip()?;
948 let args = self.parse_braced_objs(tb)?;
949 if args.len() != 2 {
950 return Err(RuntimeError::from(ParseRuntimeError(
951 RuntimeErrorStruct::new_with_msg_and_line_file(
952 "proj expects 2 arguments".to_string(),
953 tb.line_file.clone(),
954 ),
955 )));
956 }
957 let mut it = args.into_iter();
958 let left = it.next().ok_or_else(|| {
959 RuntimeError::from(ParseRuntimeError(
960 RuntimeErrorStruct::new_with_msg_and_line_file(
961 "proj expects 2 arguments".to_string(),
962 tb.line_file.clone(),
963 ),
964 ))
965 })?;
966 let right = it.next().ok_or_else(|| {
967 RuntimeError::from(ParseRuntimeError(
968 RuntimeErrorStruct::new_with_msg_and_line_file(
969 "proj expects 2 arguments".to_string(),
970 tb.line_file.clone(),
971 ),
972 ))
973 })?;
974 return Ok(Proj::new(left, right).into());
975 }
976 if tok == RANGE {
977 tb.skip()?;
978 let args = self.parse_braced_objs(tb)?;
979 if args.len() != 2 {
980 return Err(RuntimeError::from(ParseRuntimeError(
981 RuntimeErrorStruct::new_with_msg_and_line_file(
982 "range expects 2 arguments".to_string(),
983 tb.line_file.clone(),
984 ),
985 )));
986 }
987 let mut it = args.into_iter();
988 let left = it.next().ok_or_else(|| {
989 RuntimeError::from(ParseRuntimeError(
990 RuntimeErrorStruct::new_with_msg_and_line_file(
991 "range expects 2 arguments".to_string(),
992 tb.line_file.clone(),
993 ),
994 ))
995 })?;
996 let right = it.next().ok_or_else(|| {
997 RuntimeError::from(ParseRuntimeError(
998 RuntimeErrorStruct::new_with_msg_and_line_file(
999 "range expects 2 arguments".to_string(),
1000 tb.line_file.clone(),
1001 ),
1002 ))
1003 })?;
1004 return Ok(Range::new(left, right).into());
1005 }
1006 if tok == CLOSED_RANGE {
1007 tb.skip()?;
1008 let args = self.parse_braced_objs(tb)?;
1009 if args.len() != 2 {
1010 return Err(RuntimeError::from(ParseRuntimeError(
1011 RuntimeErrorStruct::new_with_msg_and_line_file(
1012 "closed_range expects 2 arguments".to_string(),
1013 tb.line_file.clone(),
1014 ),
1015 )));
1016 }
1017 let mut it = args.into_iter();
1018 let left = it.next().ok_or_else(|| {
1019 RuntimeError::from(ParseRuntimeError(
1020 RuntimeErrorStruct::new_with_msg_and_line_file(
1021 "closed_range expects 2 arguments".to_string(),
1022 tb.line_file.clone(),
1023 ),
1024 ))
1025 })?;
1026 let right = it.next().ok_or_else(|| {
1027 RuntimeError::from(ParseRuntimeError(
1028 RuntimeErrorStruct::new_with_msg_and_line_file(
1029 "closed_range expects 2 arguments".to_string(),
1030 tb.line_file.clone(),
1031 ),
1032 ))
1033 })?;
1034 return Ok(ClosedRange::new(left, right).into());
1035 }
1036 if tok == FINITE_SEQ {
1037 tb.skip()?;
1038 let args = self.parse_braced_objs(tb)?;
1039 if args.len() != 2 {
1040 return Err(RuntimeError::from(ParseRuntimeError(
1041 RuntimeErrorStruct::new_with_msg_and_line_file(
1042 "finite_seq expects 2 arguments".to_string(),
1043 tb.line_file.clone(),
1044 ),
1045 )));
1046 }
1047 let mut it = args.into_iter();
1048 let set = it.next().ok_or_else(|| {
1049 RuntimeError::from(ParseRuntimeError(
1050 RuntimeErrorStruct::new_with_msg_and_line_file(
1051 "finite_seq expects 2 arguments".to_string(),
1052 tb.line_file.clone(),
1053 ),
1054 ))
1055 })?;
1056 let n = it.next().ok_or_else(|| {
1057 RuntimeError::from(ParseRuntimeError(
1058 RuntimeErrorStruct::new_with_msg_and_line_file(
1059 "finite_seq expects 2 arguments".to_string(),
1060 tb.line_file.clone(),
1061 ),
1062 ))
1063 })?;
1064 return Ok(FiniteSeqSet::new(set, n).into());
1065 }
1066 if tok == SEQ {
1067 tb.skip()?;
1068 let args = self.parse_braced_objs(tb)?;
1069 if args.len() != 1 {
1070 return Err(RuntimeError::from(ParseRuntimeError(
1071 RuntimeErrorStruct::new_with_msg_and_line_file(
1072 "seq expects 1 argument".to_string(),
1073 tb.line_file.clone(),
1074 ),
1075 )));
1076 }
1077 let set = args.into_iter().next().ok_or_else(|| {
1078 RuntimeError::from(ParseRuntimeError(
1079 RuntimeErrorStruct::new_with_msg_and_line_file(
1080 "seq expects 1 argument".to_string(),
1081 tb.line_file.clone(),
1082 ),
1083 ))
1084 })?;
1085 return Ok(SeqSet::new(set).into());
1086 }
1087 if tok == MATRIX {
1088 tb.skip()?;
1089 let args = self.parse_braced_objs(tb)?;
1090 if args.len() != 3 {
1091 return Err(RuntimeError::from(ParseRuntimeError(
1092 RuntimeErrorStruct::new_with_msg_and_line_file(
1093 "matrix expects 3 arguments".to_string(),
1094 tb.line_file.clone(),
1095 ),
1096 )));
1097 }
1098 let mut it = args.into_iter();
1099 let set = it.next().ok_or_else(|| {
1100 RuntimeError::from(ParseRuntimeError(
1101 RuntimeErrorStruct::new_with_msg_and_line_file(
1102 "matrix expects 3 arguments".to_string(),
1103 tb.line_file.clone(),
1104 ),
1105 ))
1106 })?;
1107 let row_len = it.next().ok_or_else(|| {
1108 RuntimeError::from(ParseRuntimeError(
1109 RuntimeErrorStruct::new_with_msg_and_line_file(
1110 "matrix expects 3 arguments".to_string(),
1111 tb.line_file.clone(),
1112 ),
1113 ))
1114 })?;
1115 let col_len = it.next().ok_or_else(|| {
1116 RuntimeError::from(ParseRuntimeError(
1117 RuntimeErrorStruct::new_with_msg_and_line_file(
1118 "matrix expects 3 arguments".to_string(),
1119 tb.line_file.clone(),
1120 ),
1121 ))
1122 })?;
1123 return Ok(MatrixSet::new(set, row_len, col_len).into());
1124 }
1125
1126 if tok == CUP {
1127 tb.skip()?;
1128 let args = self.parse_braced_objs(tb)?;
1129 if args.len() != 1 {
1130 return Err(RuntimeError::from(ParseRuntimeError(
1131 RuntimeErrorStruct::new_with_msg_and_line_file(
1132 "cup expects 1 argument".to_string(),
1133 tb.line_file.clone(),
1134 ),
1135 )));
1136 }
1137 let mut it = args.into_iter();
1138 let value = it.next().ok_or_else(|| {
1139 RuntimeError::from(ParseRuntimeError(
1140 RuntimeErrorStruct::new_with_msg_and_line_file(
1141 "cup expects 1 argument".to_string(),
1142 tb.line_file.clone(),
1143 ),
1144 ))
1145 })?;
1146 return Ok(Cup::new(value).into());
1147 }
1148 if tok == POWER_SET {
1149 tb.skip()?;
1150 let args = self.parse_braced_objs(tb)?;
1151 if args.len() != 1 {
1152 return Err(RuntimeError::from(ParseRuntimeError(
1153 RuntimeErrorStruct::new_with_msg_and_line_file(
1154 "power_set expects 1 argument".to_string(),
1155 tb.line_file.clone(),
1156 ),
1157 )));
1158 }
1159 let mut it = args.into_iter();
1160 let value = it.next().ok_or_else(|| {
1161 RuntimeError::from(ParseRuntimeError(
1162 RuntimeErrorStruct::new_with_msg_and_line_file(
1163 "power_set expects 1 argument".to_string(),
1164 tb.line_file.clone(),
1165 ),
1166 ))
1167 })?;
1168 return Ok(PowerSet::new(value).into());
1169 }
1170 if tok == CART_DIM {
1171 tb.skip()?;
1172 let args = self.parse_braced_objs(tb)?;
1173 if args.len() != 1 {
1174 return Err(RuntimeError::from(ParseRuntimeError(
1175 RuntimeErrorStruct::new_with_msg_and_line_file(
1176 "set_dim expects 1 argument".to_string(),
1177 tb.line_file.clone(),
1178 ),
1179 )));
1180 }
1181 let mut it = args.into_iter();
1182 let value = it.next().ok_or_else(|| {
1183 RuntimeError::from(ParseRuntimeError(
1184 RuntimeErrorStruct::new_with_msg_and_line_file(
1185 "set_dim expects 1 argument".to_string(),
1186 tb.line_file.clone(),
1187 ),
1188 ))
1189 })?;
1190 return Ok(CartDim::new(value).into());
1191 }
1192 if tok == COUNT {
1193 tb.skip()?;
1194 let args = self.parse_braced_objs(tb)?;
1195 if args.len() != 1 {
1196 return Err(RuntimeError::from(ParseRuntimeError(
1197 RuntimeErrorStruct::new_with_msg_and_line_file(
1198 "count expects 1 argument".to_string(),
1199 tb.line_file.clone(),
1200 ),
1201 )));
1202 }
1203 let mut it = args.into_iter();
1204 let value = it.next().ok_or_else(|| {
1205 RuntimeError::from(ParseRuntimeError(
1206 RuntimeErrorStruct::new_with_msg_and_line_file(
1207 "count expects 1 argument".to_string(),
1208 tb.line_file.clone(),
1209 ),
1210 ))
1211 })?;
1212 return Ok(Count::new(value).into());
1213 }
1214 if tok == SUM {
1215 tb.skip()?;
1216 let args = self.parse_braced_objs(tb)?;
1217 if args.len() != 3 {
1218 return Err(RuntimeError::from(ParseRuntimeError(
1219 RuntimeErrorStruct::new_with_msg_and_line_file(
1220 "sum expects 3 arguments (start, end, function)".to_string(),
1221 tb.line_file.clone(),
1222 ),
1223 )));
1224 }
1225 let mut it = args.into_iter();
1226 let start = it.next().ok_or_else(|| {
1227 RuntimeError::from(ParseRuntimeError(
1228 RuntimeErrorStruct::new_with_msg_and_line_file(
1229 "sum expects 3 arguments (start, end, function)".to_string(),
1230 tb.line_file.clone(),
1231 ),
1232 ))
1233 })?;
1234 let end = it.next().ok_or_else(|| {
1235 RuntimeError::from(ParseRuntimeError(
1236 RuntimeErrorStruct::new_with_msg_and_line_file(
1237 "sum expects 3 arguments (start, end, function)".to_string(),
1238 tb.line_file.clone(),
1239 ),
1240 ))
1241 })?;
1242 let func = it.next().ok_or_else(|| {
1243 RuntimeError::from(ParseRuntimeError(
1244 RuntimeErrorStruct::new_with_msg_and_line_file(
1245 "sum expects 3 arguments (start, end, function)".to_string(),
1246 tb.line_file.clone(),
1247 ),
1248 ))
1249 })?;
1250 return Ok(Sum::new(start, end, func).into());
1251 }
1252 if tok == PRODUCT {
1253 tb.skip()?;
1254 let args = self.parse_braced_objs(tb)?;
1255 if args.len() != 3 {
1256 return Err(RuntimeError::from(ParseRuntimeError(
1257 RuntimeErrorStruct::new_with_msg_and_line_file(
1258 "product expects 3 arguments (start, end, function)".to_string(),
1259 tb.line_file.clone(),
1260 ),
1261 )));
1262 }
1263 let mut it = args.into_iter();
1264 let start = it.next().ok_or_else(|| {
1265 RuntimeError::from(ParseRuntimeError(
1266 RuntimeErrorStruct::new_with_msg_and_line_file(
1267 "product expects 3 arguments (start, end, function)".to_string(),
1268 tb.line_file.clone(),
1269 ),
1270 ))
1271 })?;
1272 let end = it.next().ok_or_else(|| {
1273 RuntimeError::from(ParseRuntimeError(
1274 RuntimeErrorStruct::new_with_msg_and_line_file(
1275 "product expects 3 arguments (start, end, function)".to_string(),
1276 tb.line_file.clone(),
1277 ),
1278 ))
1279 })?;
1280 let func = it.next().ok_or_else(|| {
1281 RuntimeError::from(ParseRuntimeError(
1282 RuntimeErrorStruct::new_with_msg_and_line_file(
1283 "product expects 3 arguments (start, end, function)".to_string(),
1284 tb.line_file.clone(),
1285 ),
1286 ))
1287 })?;
1288 return Ok(Product::new(start, end, func).into());
1289 }
1290 if tok == CART {
1291 tb.skip()?;
1292 let args = self.parse_braced_objs(tb)?;
1293 if args.len() < 2 {
1294 return Err(RuntimeError::from(ParseRuntimeError(
1295 RuntimeErrorStruct::new_with_msg_and_line_file(
1296 "cart expects at least 2 arguments".to_string(),
1297 tb.line_file.clone(),
1298 ),
1299 )));
1300 }
1301 return Ok(Cart::new(args).into());
1302 }
1303
1304 if tok == TUPLE_DIM {
1305 tb.skip()?;
1306 let args = self.parse_braced_obj(tb)?;
1307 return Ok(TupleDim::new(args).into());
1308 }
1309
1310 if tok == CART_DIM {
1311 tb.skip()?;
1312 let args = self.parse_braced_obj(tb)?;
1313 return Ok(CartDim::new(args).into());
1314 }
1315
1316 self.parse_and_reclassify_atom_as_free_param_obj(tb)
1318 }
1319
1320 fn parse_and_reclassify_atom_as_free_param_obj(
1322 &mut self,
1323 tb: &mut TokenBlock,
1324 ) -> Result<Obj, RuntimeError> {
1325 let atom = self.parse_identifier_or_identifier_with_mod(tb)?;
1326 self.reclassify_atom_as_free_param_obj(atom)
1327 }
1328
1329 fn reclassify_atom_as_free_param_obj(&self, obj: Obj) -> Result<Obj, RuntimeError> {
1330 match obj {
1331 Obj::Atom(AtomObj::Identifier(id)) => {
1332 if let Some(standard) = standard_set_from_bare_identifier_name(&id.name) {
1333 return Ok(standard);
1334 }
1335 Ok(self
1336 .parsing_free_param_collection
1337 .resolve_identifier_to_free_param_obj(&id.name))
1338 }
1339 Obj::Atom(AtomObj::IdentifierWithMod(m)) => {
1340 Ok(Obj::Atom(AtomObj::IdentifierWithMod(m)))
1341 }
1342 _ => Err(RuntimeError::from(ParseRuntimeError(
1343 RuntimeErrorStruct::new_with_just_msg(
1344 "internal: atom position was not a name form".to_string(),
1345 ),
1346 ))),
1347 }
1348 }
1349
1350 pub fn parse_braced_objs(&mut self, tb: &mut TokenBlock) -> Result<Vec<Obj>, RuntimeError> {
1351 tb.skip_token(LEFT_BRACE)?;
1352 if tb.current_token_is_equal_to(RIGHT_BRACE) {
1353 tb.skip_token(RIGHT_BRACE)?;
1354 return Ok(vec![]);
1355 }
1356 let mut objs = vec![self.parse_obj(tb)?];
1357 while tb.current_token_is_equal_to(COMMA) {
1358 tb.skip_token(COMMA)?;
1359 objs.push(self.parse_obj(tb)?);
1360 }
1361 tb.skip_token(RIGHT_BRACE)?;
1362 Ok(objs)
1363 }
1364
1365 fn parse_fn_obj_arg_group(&mut self, tb: &mut TokenBlock) -> Result<Vec<Obj>, RuntimeError> {
1366 let args = self.parse_braced_objs(tb)?;
1367 if args.is_empty() {
1368 return Err(RuntimeError::from(ParseRuntimeError(
1369 RuntimeErrorStruct::new_with_msg_and_line_file(
1370 "function application expects at least one argument".to_string(),
1371 tb.line_file.clone(),
1372 ),
1373 )));
1374 }
1375 Ok(args)
1376 }
1377
1378 pub fn parse_braced_obj(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
1379 let mut parsed_args = self.parse_braced_objs(tb)?;
1380 if parsed_args.len() != 1 {
1381 return Err(RuntimeError::from(ParseRuntimeError(
1382 RuntimeErrorStruct::new_with_msg_and_line_file(
1383 "expected exactly 1 argument".to_string(),
1384 tb.line_file.clone(),
1385 ),
1386 )));
1387 }
1388 let parsed_obj = parsed_args.remove(0);
1389 Ok(parsed_obj)
1390 }
1391
1392 pub fn parse_obj_list(&mut self, tb: &mut TokenBlock) -> Result<Vec<Obj>, RuntimeError> {
1394 let mut objs = vec![self.parse_obj(tb)?];
1395 while tb.current_token_is_equal_to(COMMA) {
1396 tb.skip_token(COMMA)?;
1397 objs.push(self.parse_obj(tb)?);
1398 }
1399 Ok(objs)
1400 }
1401
1402 fn parse_set_builder_or_set_list(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
1403 tb.skip_token(LEFT_CURLY_BRACE)?;
1404 if tb.current_token_is_equal_to(RIGHT_CURLY_BRACE) {
1405 tb.skip_token(RIGHT_CURLY_BRACE)?;
1406 return Ok(ListSet::new(vec![]).into());
1407 }
1408
1409 let left = self.parse_obj(tb)?;
1410 let name_for_set_builder = match &left {
1413 Obj::Atom(AtomObj::Identifier(a)) => Some(a.name.as_str()),
1414 Obj::Atom(AtomObj::IdentifierWithMod(m)) => Some(m.name.as_str()),
1415 Obj::Atom(AtomObj::Forall(p)) => Some(p.name.as_str()),
1416 Obj::Atom(AtomObj::Def(p)) => Some(p.name.as_str()),
1417 Obj::Atom(AtomObj::Exist(p)) => Some(p.name.as_str()),
1418 Obj::Atom(AtomObj::SetBuilder(p)) => Some(p.name.as_str()),
1419 Obj::Atom(AtomObj::FnSet(p)) => Some(p.name.as_str()),
1420 Obj::Atom(AtomObj::Induc(p)) => Some(p.name.as_str()),
1421 Obj::Atom(AtomObj::DefAlgo(p)) => Some(p.name.as_str()),
1422 _ => None,
1423 };
1424 if let Some(name) = name_for_set_builder {
1425 if tb.current_token_is_equal_to(COMMA) || tb.current()? == RIGHT_CURLY_BRACE {
1426 self.parse_list_set_obj_with_leftmost_obj(tb, left)
1427 } else {
1428 self.parse_set_builder(tb, Identifier::new(name.to_string()))
1429 }
1430 } else {
1431 self.parse_list_set_obj_with_leftmost_obj(tb, left)
1432 }
1433 }
1434
1435 fn parse_instantiated_template_obj(
1436 &mut self,
1437 tb: &mut TokenBlock,
1438 ) -> Result<Obj, RuntimeError> {
1439 tb.skip_token(TEMPLATE_INSTANCE_PREFIX)?;
1440 let template_name = tb.advance()?;
1441 is_valid_litex_name(&template_name).map_err(|msg| {
1442 RuntimeError::from(ParseRuntimeError(
1443 RuntimeErrorStruct::new_with_msg_and_line_file(msg, tb.line_file.clone()),
1444 ))
1445 })?;
1446 tb.skip_token(LEFT_CURLY_BRACE)?;
1447 let mut args = Vec::new();
1448 if !tb.current_token_is_equal_to(RIGHT_CURLY_BRACE) {
1449 args.push(self.parse_obj(tb)?);
1450 while tb.current_token_is_equal_to(COMMA) {
1451 tb.skip_token(COMMA)?;
1452 args.push(self.parse_obj(tb)?);
1453 }
1454 }
1455 tb.skip_token(RIGHT_CURLY_BRACE)?;
1456 Ok(InstantiatedTemplateObj::new(template_name, args).into())
1457 }
1458
1459 fn parse_set_builder(
1461 &mut self,
1462 tb: &mut TokenBlock,
1463 a: Identifier,
1464 ) -> Result<Obj, RuntimeError> {
1465 self.run_in_local_parsing_time_name_scope(|this| {
1466 let set_builder_param = [a.name.clone()];
1467 this.parsing_free_param_collection.begin_scope(
1468 ParamObjType::SetBuilder,
1469 &set_builder_param,
1470 tb.line_file.clone(),
1471 )?;
1472 let parsed = (|| -> Result<Obj, RuntimeError> {
1473 let second = this.parse_obj(tb)?;
1474 if tb.current()? == COLON {
1475 tb.skip_token(COLON)?;
1476
1477 let user_names = vec![a.name.clone()];
1478 this.validate_user_fn_param_names_for_parse(&user_names, tb.line_file.clone())?;
1479 let empty: HashMap<String, Obj> = HashMap::new();
1480 let second_inst = this.inst_obj(&second, &empty, ParamObjType::SetBuilder)?;
1481
1482 let mut facts_inst = Vec::new();
1483 while tb.current()? != RIGHT_CURLY_BRACE {
1484 let f = this.parse_or_and_chain_atomic_fact(tb)?;
1485 facts_inst.push(this.inst_or_and_chain_atomic_fact(
1486 &f,
1487 &empty,
1488 ParamObjType::SetBuilder,
1489 None,
1490 )?);
1491 }
1492 tb.skip_token(RIGHT_CURLY_BRACE)?;
1493
1494 Ok(SetBuilder::new(a.name.clone(), second_inst, facts_inst)?.into())
1495 } else {
1496 Err(RuntimeError::from(ParseRuntimeError(
1497 RuntimeErrorStruct::new_with_msg_and_line_file(
1498 "expected colon after first argument".to_string(),
1499 tb.line_file.clone(),
1500 ),
1501 )))
1502 }
1503 })();
1504 this.parsing_free_param_collection
1505 .end_scope(ParamObjType::SetBuilder, &set_builder_param);
1506 parsed
1507 })
1508 }
1509
1510 fn parse_list_set_obj_with_leftmost_obj(
1512 &mut self,
1513 tb: &mut TokenBlock,
1514 left_most_obj: Obj,
1515 ) -> Result<Obj, RuntimeError> {
1516 let mut objs = vec![left_most_obj];
1517 while tb.current()? != RIGHT_CURLY_BRACE {
1518 if tb.current_token_is_equal_to(COMMA) {
1519 tb.skip_token(COMMA)?;
1520 }
1521 objs.push(self.parse_obj(tb)?);
1522 }
1523 tb.skip_token(RIGHT_CURLY_BRACE)?;
1524 Ok(ListSet::new(objs).into())
1525 }
1526
1527 pub fn parse_list_set_obj(&mut self, tb: &mut TokenBlock) -> Result<ListSet, RuntimeError> {
1528 let mut objs = vec![];
1529 tb.skip_token(LEFT_CURLY_BRACE)?;
1530 while tb.current()? != RIGHT_CURLY_BRACE {
1531 objs.push(self.parse_obj(tb)?);
1532 if tb.current_token_is_equal_to(COMMA) {
1533 tb.skip_token(COMMA)?;
1534 }
1535 }
1536 tb.skip_token(RIGHT_CURLY_BRACE)?;
1537 Ok(ListSet::new(objs))
1538 }
1539
1540 pub fn parse_identifier(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
1541 let left = parse_synthetically_correct_identifier_string(tb)?;
1542 Ok(Identifier::new(left).into())
1543 }
1544
1545 fn parse_mod_qualified_atom(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
1546 let left = parse_synthetically_correct_identifier_string(tb)?;
1547 tb.skip_token(MOD_SIGN)?;
1548 let right = parse_synthetically_correct_identifier_string(tb)?;
1549 if !tb.exceed_end_of_head() && tb.current()? == DOT_AKA_FIELD_ACCESS_SIGN {
1550 return Err(RuntimeError::from(ParseRuntimeError(
1551 RuntimeErrorStruct::new_with_msg_and_line_file(
1552 "unexpected `.` after module-qualified name".to_string(),
1553 tb.line_file.clone(),
1554 ),
1555 )));
1556 }
1557 Ok(IdentifierWithMod::new(left, right).into())
1558 }
1559
1560 pub fn parse_identifier_or_identifier_with_mod(
1562 &mut self,
1563 tb: &mut TokenBlock,
1564 ) -> Result<Obj, RuntimeError> {
1565 let next_is_mod = tb.token_at_add_index(1) == MOD_SIGN;
1566 if next_is_mod {
1567 self.parse_mod_qualified_atom(tb)
1568 } else {
1569 self.parse_identifier(tb)
1570 }
1571 }
1572
1573 pub fn parse_predicate(&mut self, tb: &mut TokenBlock) -> Result<AtomicName, RuntimeError> {
1574 self.parse_atomic_name(tb)
1575 }
1576
1577 pub fn parse_struct_view_obj(&mut self, tb: &mut TokenBlock) -> Result<Obj, RuntimeError> {
1578 tb.skip_token(STRUCT_VIEW_PREFIX)?;
1579 let name = self.parse_name_with_or_without_mod(tb)?;
1580 let params = if !tb.exceed_end_of_head() && tb.current()? == LEFT_BRACE {
1581 self.parse_braced_objs(tb)?
1582 } else {
1583 vec![]
1584 };
1585 let struct_obj = StructObj::new(name, params);
1586
1587 if tb.exceed_end_of_head() || tb.current()? != LEFT_CURLY_BRACE {
1588 return Ok(struct_obj.into());
1589 }
1590
1591 tb.skip_token(LEFT_CURLY_BRACE)?;
1592 let obj = self.parse_obj(tb)?;
1593 tb.skip_token(RIGHT_CURLY_BRACE)?;
1594 tb.skip_token(DOT_AKA_FIELD_ACCESS_SIGN)?;
1595 let field_name = parse_synthetically_correct_identifier_string(tb)?;
1596 Ok(ObjAsStructInstanceWithFieldAccess::new(struct_obj, obj, field_name).into())
1597 }
1598
1599 fn parse_name_with_or_without_mod(
1600 &mut self,
1601 tb: &mut TokenBlock,
1602 ) -> Result<NameWithOrWithoutMod, RuntimeError> {
1603 let name = self.parse_atomic_name(tb)?;
1604 Ok(match name {
1605 AtomicName::WithoutMod(name) => NameWithOrWithoutMod::WithoutMod(name),
1606 AtomicName::WithMod(mod_name, name) => NameWithOrWithoutMod::WithMod(mod_name, name),
1607 })
1608 }
1609
1610 pub fn parse_atomic_name(&mut self, tb: &mut TokenBlock) -> Result<AtomicName, RuntimeError> {
1612 let left = parse_synthetically_correct_identifier_string(tb)?;
1613 if !tb.exceed_end_of_head() && tb.current()? == MOD_SIGN {
1614 tb.skip()?;
1615 let right = parse_synthetically_correct_identifier_string(tb)?;
1616 Ok(AtomicName::WithMod(left, right))
1617 } else {
1618 Ok(AtomicName::WithoutMod(left))
1619 }
1620 }
1621}
1622
1623fn starts_with_digit(s: &str) -> bool {
1624 s.chars()
1625 .next()
1626 .map(|c| c.is_ascii_digit())
1627 .unwrap_or(false)
1628}
1629
1630fn minus_token_is_standalone_operator_obj(tb: &TokenBlock) -> bool {
1631 let next = tb.token_at_add_index(1);
1632 next == FACT_PREFIX
1633 || next == EQUAL
1634 || next == NOT_EQUAL
1635 || next == LESS
1636 || next == GREATER
1637 || next == LESS_EQUAL
1638 || next == GREATER_EQUAL
1639}
1640
1641fn is_number(s: &str) -> bool {
1642 if s.is_empty() {
1643 return false;
1644 }
1645
1646 let mut dot_count = 0;
1647
1648 for c in s.chars() {
1649 if c == '.' {
1650 dot_count += 1;
1651 if dot_count > 1 {
1652 return false;
1653 }
1654 } else if !c.is_ascii_digit() {
1655 return false;
1656 }
1657 }
1658
1659 s != "."
1660}
1661
1662enum FnSetOrFnSetClause {
1663 FnSet(FnSet),
1664 FnSetClause(FnSetClause),
1665}
1666
1667fn parse_synthetically_correct_identifier_string(
1668 tb: &mut TokenBlock,
1669) -> Result<String, RuntimeError> {
1670 let cur = tb.advance()?;
1671
1672 if cur == SET || cur == NONEMPTY_SET || cur == FINITE_SET {
1673 return Err(RuntimeError::from(ParseRuntimeError(
1674 RuntimeErrorStruct::new_with_msg_and_line_file(
1675 format!("{} is not a valid identifier", cur),
1676 tb.line_file.clone(),
1677 ),
1678 )));
1679 }
1680
1681 Ok(cur)
1682}
1683
1684fn standard_set_from_bare_identifier_name(name: &str) -> Option<Obj> {
1686 match name {
1687 N_POS => Some(StandardSet::NPos.into()),
1688 N => Some(StandardSet::N.into()),
1689 Q => Some(StandardSet::Q.into()),
1690 Z => Some(StandardSet::Z.into()),
1691 R => Some(StandardSet::R.into()),
1692 Q_POS => Some(StandardSet::QPos.into()),
1693 R_POS => Some(StandardSet::RPos.into()),
1694 Q_NEG => Some(StandardSet::QNeg.into()),
1695 Z_NEG => Some(StandardSet::ZNeg.into()),
1696 R_NEG => Some(StandardSet::RNeg.into()),
1697 Q_NZ => Some(StandardSet::QNz.into()),
1698 Z_NZ => Some(StandardSet::ZNz.into()),
1699 R_NZ => Some(StandardSet::RNz.into()),
1700 _ => None,
1701 }
1702}