1#![allow(clippy::unwrap_used)]
2#![allow(clippy::expect_used)]
3use std::sync::{Arc, RwLock};
4use ustr::Ustr;
5
6use serde_json::Map as JsonMap;
7use serde_json::Value;
8use serde_json::Value as JsonValue;
9
10use crate::ast::Moo;
11use crate::ast::abstract_comprehension::AbstractComprehensionBuilder;
12use crate::ast::ac_operators::ACOperatorKind;
13use crate::ast::comprehension::ComprehensionBuilder;
14use crate::ast::records::RecordValue;
15use crate::ast::{
16 AbstractLiteral, Atom, DeclarationPtr, Domain, Expression, FuncAttr, IntVal, JectivityAttr,
17 Literal, MSetAttr, Name, PartialityAttr, Range, RecordEntry, SetAttr, SymbolTable,
18 SymbolTablePtr,
19};
20use crate::ast::{DomainPtr, Metadata};
21use crate::context::Context;
22use crate::error::{Error, Result};
23use crate::{Model, bug, error, into_matrix_expr, throw_error};
24
25#[allow(unused_macros)]
26macro_rules! parser_trace {
27 ($($arg:tt)+) => {
28 log::trace!(target:"jsonparser",$($arg)+)
29 };
30}
31
32#[allow(unused_macros)]
33macro_rules! parser_debug {
34 ($($arg:tt)+) => {
35 log::debug!(target:"jsonparser",$($arg)+)
36 };
37}
38
39pub fn model_from_json(str: &str, context: Arc<RwLock<Context<'static>>>) -> Result<Model> {
40 let mut m = Model::new(context);
41 let v: JsonValue = serde_json::from_str(str)?;
42 let statements = v["mStatements"]
43 .as_array()
44 .ok_or(error!("mStatements is not an array"))?;
45
46 for statement in statements {
47 let entry = statement
48 .as_object()
49 .ok_or(error!("mStatements contains a non-object"))?
50 .iter()
51 .next()
52 .ok_or(error!("mStatements contains an empty object"))?;
53
54 match entry.0.as_str() {
55 "Declaration" => {
56 let decl = entry
57 .1
58 .as_object()
59 .ok_or(error!("Declaration is not an object".to_owned()))?;
60
61 let mut valid_decl: bool = false;
68 let scope = m.symbols_ptr_unchecked().clone();
69 let model = &mut m;
70 for (kind, value) in decl {
71 match kind.as_str() {
72 "FindOrGiven" => {
73 parse_variable(value, &mut model.symbols_mut())?;
74 valid_decl = true;
75 break;
76 }
77 "Letting" => {
78 parse_letting(value, &scope)?;
79 valid_decl = true;
80 break;
81 }
82 _ => continue,
83 }
84 }
85
86 if !valid_decl {
87 throw_error!("Declaration is not a valid kind")?;
88 }
89 }
90 "SuchThat" => {
91 let constraints_arr = match entry.1.as_array() {
92 Some(x) => x,
93 None => bug!("SuchThat is not a vector"),
94 };
95
96 let constraints: Vec<Expression> = constraints_arr
97 .iter()
98 .map(|x| parse_expression(x, m.symbols_ptr_unchecked()))
99 .collect::<Result<Vec<_>>>()?;
100 m.add_constraints(constraints);
101 }
102 otherwise => bug!("Unhandled Statement {:#?}", otherwise),
103 }
104 }
105 Ok(m)
106}
107
108fn parse_variable(v: &JsonValue, symtab: &mut SymbolTable) -> Result<()> {
109 let arr = v.as_array().ok_or(error!("FindOrGiven is not an array"))?;
110
111 let variable_type = arr[0]
112 .as_str()
113 .ok_or(error!("FindOrGiven[0] is not a string"))?;
114
115 let name = arr[1]
116 .as_object()
117 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
118 .as_str()
119 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
120
121 let name = Name::User(Ustr::from(name));
122
123 let domain = arr[2]
124 .as_object()
125 .ok_or(error!("FindOrGiven[2] is not an object"))?
126 .iter()
127 .next()
128 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
129
130 let domain = parse_domain(domain.0, domain.1, symtab)?;
131
132 let decl = match variable_type {
133 "Find" => DeclarationPtr::new_find(name.clone(), domain),
134 "Given" => DeclarationPtr::new_given(name.clone(), domain),
135 _ => {
136 return Err(error!("FindOrGiven[0] is not 'Find' or 'Given'"));
137 }
138 };
139
140 symtab.insert(decl).ok_or(Error::Parse(format!(
141 "Could not add {name} to symbol table as it already exists"
142 )))
143}
144
145fn parse_letting(v: &JsonValue, scope: &SymbolTablePtr) -> Result<()> {
146 let arr = v.as_array().ok_or(error!("Letting is not an array"))?;
147 let name = arr[0]
148 .as_object()
149 .ok_or(error!("Letting[0] is not an object"))?["Name"]
150 .as_str()
151 .ok_or(error!("Letting[0].Name is not a string"))?;
152 let name = Name::User(Ustr::from(name));
153 if let Ok(value) = parse_expression(&arr[1], scope) {
155 let mut symtab = scope.write();
156 symtab
157 .insert(DeclarationPtr::new_value_letting(name.clone(), value))
158 .ok_or(Error::Parse(format!(
159 "Could not add {name} to symbol table as it already exists"
160 )))
161 } else {
162 let domain = &arr[1]
164 .as_object()
165 .ok_or(error!("Letting[1] is not an object".to_owned()))?["Domain"]
166 .as_object()
167 .ok_or(error!("Letting[1].Domain is not an object"))?
168 .iter()
169 .next()
170 .ok_or(error!("Letting[1].Domain is an empty object"))?;
171
172 let mut symtab = scope.write();
173 let domain = parse_domain(domain.0, domain.1, &mut symtab)?;
174
175 symtab
176 .insert(DeclarationPtr::new_domain_letting(name.clone(), domain))
177 .ok_or(Error::Parse(format!(
178 "Could not add {name} to symbol table as it already exists"
179 )))
180 }
181}
182
183fn parse_domain(
184 domain_name: &str,
185 domain_value: &JsonValue,
186 symbols: &mut SymbolTable,
187) -> Result<DomainPtr> {
188 match domain_name {
189 "DomainInt" => Ok(parse_int_domain(domain_value, symbols)?),
190 "DomainBool" => Ok(Domain::bool()),
191 "DomainReference" => {
192 let name = Name::user(
193 domain_value
194 .as_array()
195 .ok_or(error!("DomainReference is not an array"))?[0]
196 .as_object()
197 .ok_or(error!("DomainReference[0] is not an object"))?["Name"]
198 .as_str()
199 .ok_or(error!("DomainReference[0].Name is not a string"))?,
200 );
201 let ptr = symbols
202 .lookup(&name)
203 .ok_or(error!(format!("Name {name} not found")))?;
204 let dom =
205 Domain::reference(ptr).ok_or(error!("Could not construct reference domain"))?;
206 Ok(dom)
207 }
208 "DomainSet" => {
209 let dom = domain_value.get(2).and_then(|v| v.as_object());
210 let domain_obj = dom.ok_or(error!("DomainSet is missing domain object"))?;
211 let domain = domain_obj
212 .iter()
213 .next()
214 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
215 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
216 let size = domain_value
217 .get(1)
218 .and_then(|v| v.as_object())
219 .ok_or(error!("Set size attributes is not an object"))?;
220 let size = parse_size_attr(size, symbols)?;
221 let attr: SetAttr<IntVal> = SetAttr { size };
222 Ok(Domain::set(attr, domain))
223 }
224 "DomainMSet" => {
225 let dom = domain_value
226 .get(2)
227 .and_then(|v| v.as_object())
228 .expect("domain object exists");
229 let domain = dom
230 .iter()
231 .next()
232 .ok_or(Error::Parse("DomainMSet is an empty object".to_owned()))?;
233 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
234
235 let attributes = domain_value
237 .get(1)
238 .and_then(|v| v.as_array())
239 .ok_or(error!("MSet attributes is not a json array"))?;
240
241 let size = attributes
242 .first()
243 .and_then(|v| v.as_object())
244 .ok_or(error!("MSet size attributes is not an object"))?;
245 let size = parse_size_attr(size, symbols)?;
246
247 let occurrence = attributes
248 .get(1)
249 .and_then(|v| v.as_object())
250 .ok_or(error!("MSet occurrence attributes is not an object"))?;
251 let occurrence = parse_occur_attr(occurrence, symbols)?;
252
253 let attr: MSetAttr<IntVal> = MSetAttr { size, occurrence };
254 Ok(Domain::mset(attr, domain))
255 }
256
257 "DomainMatrix" => {
258 let domain_value = domain_value
259 .as_array()
260 .ok_or(error!("Domain matrix is not an array"))?;
261
262 let indexed_by_domain = domain_value[0].clone();
263 let (index_domain_name, index_domain_value) = indexed_by_domain
264 .as_object()
265 .ok_or(error!("DomainMatrix[0] is not an object"))?
266 .iter()
267 .next()
268 .ok_or(error!(""))?;
269
270 let (value_domain_name, value_domain_value) = domain_value[1]
271 .as_object()
272 .ok_or(error!(""))?
273 .iter()
274 .next()
275 .ok_or(error!(""))?;
276
277 let mut index_domains: Vec<DomainPtr> = vec![];
282
283 index_domains.push(parse_domain(
284 index_domain_name,
285 index_domain_value,
286 symbols,
287 )?);
288
289 let mut value_domain = parse_domain(value_domain_name, value_domain_value, symbols)?;
295 while let Some((new_value_domain, mut indices)) = value_domain.as_matrix() {
296 index_domains.append(&mut indices);
297 value_domain = new_value_domain.clone()
298 }
299
300 Ok(Domain::matrix(value_domain, index_domains))
301 }
302 "DomainTuple" => {
303 let domain_value = domain_value
304 .as_array()
305 .ok_or(error!("Domain tuple is not an array"))?;
306
307 let domain = domain_value
309 .iter()
310 .map(|x| {
311 let domain = x
312 .as_object()
313 .ok_or(error!("DomainTuple[0] is not an object"))?
314 .iter()
315 .next()
316 .ok_or(error!("DomainTuple[0] is an empty object"))?;
317 parse_domain(domain.0, domain.1, symbols)
318 })
319 .collect::<Result<Vec<DomainPtr>>>()?;
320
321 Ok(Domain::tuple(domain))
322 }
323 "DomainRecord" => {
324 let domain_value = domain_value
325 .as_array()
326 .ok_or(error!("Domain Record is not a json array"))?;
327
328 let mut record_entries = vec![];
329
330 for item in domain_value {
331 let name = item[0]
333 .as_object()
334 .ok_or(error!("FindOrGiven[1] is not an object"))?["Name"]
335 .as_str()
336 .ok_or(error!("FindOrGiven[1].Name is not a string"))?;
337
338 let name = Name::User(Ustr::from(name));
339 let domain = item[1]
341 .as_object()
342 .ok_or(error!("FindOrGiven[2] is not an object"))?
343 .iter()
344 .next()
345 .ok_or(error!("FindOrGiven[2] is an empty object"))?;
346
347 let domain = parse_domain(domain.0, domain.1, symbols)?;
348
349 let rec = RecordEntry { name, domain };
350
351 record_entries.push(rec);
352 }
353
354 for decl in record_entries
356 .iter()
357 .cloned()
358 .map(DeclarationPtr::new_record_field)
359 {
360 symbols.insert(decl).ok_or(error!(
361 "record field should not already be in the symbol table"
362 ))?;
363 }
364
365 Ok(Domain::record(record_entries))
366 }
367 "DomainFunction" => {
368 let domain = domain_value
369 .get(2)
370 .and_then(|v| v.as_object())
371 .ok_or(error!("Function domain is not an object"))?;
372 let domain = domain
373 .iter()
374 .next()
375 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
376 let domain = parse_domain(domain.0.as_str(), domain.1, symbols)?;
377
378 let codomain = domain_value
379 .get(3)
380 .and_then(|v| v.as_object())
381 .ok_or(error!("Function codomain is not an object"))?;
382 let codomain = codomain
383 .iter()
384 .next()
385 .ok_or(Error::Parse("DomainSet is an empty object".to_owned()))?;
386 let codomain = parse_domain(codomain.0.as_str(), codomain.1, symbols)?;
387
388 let attributes = domain_value
390 .get(1)
391 .and_then(|v| v.as_array())
392 .ok_or(error!("Function attributes is not a json array"))?;
393 let size = attributes
394 .first()
395 .and_then(|v| v.as_object())
396 .ok_or(error!("Function size attributes is not an object"))?;
397 let size = parse_size_attr(size, symbols)?;
398 let partiality = attributes
399 .get(1)
400 .and_then(|v| v.as_str())
401 .ok_or(error!("Function partiality is not a string"))?;
402 let partiality = match partiality {
403 "PartialityAttr_Partial" => Some(PartialityAttr::Partial),
404 "PartialityAttr_Total" => Some(PartialityAttr::Total),
405 _ => None,
406 };
407 let partiality =
408 partiality.ok_or(Error::Parse("Partiality is an unknown type".to_owned()))?;
409 let jectivity = attributes
410 .get(2)
411 .and_then(|v| v.as_str())
412 .ok_or(error!("Function jectivity is not a string"))?;
413 let jectivity = match jectivity {
414 "JectivityAttr_Injective" => Some(JectivityAttr::Injective),
415 "JectivityAttr_Surjective" => Some(JectivityAttr::Surjective),
416 "JectivityAttr_Bijective" => Some(JectivityAttr::Bijective),
417 "JectivityAttr_None" => Some(JectivityAttr::None),
418 _ => None,
419 };
420 let jectivity =
421 jectivity.ok_or(Error::Parse("Jectivity is an unknown type".to_owned()))?;
422
423 let attr: FuncAttr<IntVal> = FuncAttr {
424 size,
425 partiality,
426 jectivity,
427 };
428
429 Ok(Domain::function(attr, domain, codomain))
430 }
431 _ => Err(Error::Parse(
432 "FindOrGiven[2] is an unknown object".to_owned(), )),
434 }
435}
436
437fn parse_size_attr(
438 attr_map: &JsonMap<String, JsonValue>,
439 symbols: &mut SymbolTable,
440) -> Result<Range<IntVal>> {
441 let scope = SymbolTablePtr::new();
442 *scope.write() = symbols.clone();
443
444 let attr_obj = attr_map
445 .iter()
446 .next()
447 .ok_or(Error::Parse("SizeAttr is an empty object".to_owned()))?;
448 match attr_obj.0.as_str() {
449 "SizeAttr_None" => Ok(Range::Unbounded),
450 "SizeAttr_MinSize" => {
451 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
452 Ok(Range::UnboundedR(size))
453 }
454 "SizeAttr_MaxSize" => {
455 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
456 Ok(Range::UnboundedL(size))
457 }
458 "SizeAttr_MinMaxSize" => {
459 let min_max = attr_obj
460 .1
461 .as_array()
462 .ok_or(error!("SizeAttr MinMaxSize is not a json array"))?;
463 let min = min_max
464 .first()
465 .ok_or(error!("SizeAttr Min is not present"))?;
466 let min_int = parse_expression_to_int_val(min, &scope)?;
467 let max = min_max
468 .get(1)
469 .ok_or(error!("SizeAttr Max is not present"))?;
470 let max_int = parse_expression_to_int_val(max, &scope)?;
471 Ok(Range::Bounded(min_int, max_int))
472 }
473 "SizeAttr_Size" => {
474 let size = parse_expression_to_int_val(attr_obj.1, &scope)?;
475 Ok(Range::Single(size))
476 }
477 _ => Err(Error::Parse("SizeAttr is an unknown type".to_owned())),
478 }
479}
480
481fn parse_occur_attr(
482 attr_map: &JsonMap<String, JsonValue>,
483 symbols: &mut SymbolTable,
484) -> Result<Range<IntVal>> {
485 let scope = SymbolTablePtr::new();
486 *scope.write() = symbols.clone();
487 let attr_obj = attr_map
488 .iter()
489 .next()
490 .ok_or(Error::Parse("OccurAttr is an empty object".to_owned()))?;
491 match attr_obj.0.as_str() {
492 "OccurAttr_None" => Ok(Range::Unbounded),
493 "OccurAttr_MinOccur" => {
494 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
495 Ok(Range::UnboundedR(size_int))
496 }
497 "OccurAttr_MaxOccur" => {
498 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
499 Ok(Range::UnboundedL(size_int))
500 }
501 "OccurAttr_MinMaxOccur" => {
502 let min_max = attr_obj
503 .1
504 .as_array()
505 .ok_or(error!("OccurAttr MinMaxOccur is not a json array"))?;
506 let min = min_max
507 .first()
508 .ok_or(error!("OccurAttr Min is not present"))?;
509 let min_int = parse_expression_to_int_val(min, &scope)?;
510 let max = min_max
511 .get(1)
512 .ok_or(error!("OccurAttr Max is not present"))?;
513 let max_int = parse_expression_to_int_val(max, &scope)?;
514 Ok(Range::Bounded(min_int, max_int))
515 }
516 "OccurAttr_Size" => {
517 let size_int = parse_expression_to_int_val(attr_obj.1, &scope)?;
518 Ok(Range::Single(size_int))
519 }
520 _ => Err(Error::Parse("OccurAttr is an unknown type".to_owned())),
521 }
522}
523
524fn parse_int_domain(v: &JsonValue, symbols: &SymbolTable) -> Result<DomainPtr> {
525 let scope = SymbolTablePtr::new();
526 *scope.write() = symbols.clone();
527
528 let mut ranges = Vec::new();
529 let arr = v
530 .as_array()
531 .ok_or(error!("DomainInt is not an array".to_owned()))?[1]
532 .as_array()
533 .ok_or(error!("DomainInt[1] is not an array".to_owned()))?;
534 for range in arr {
535 let range = range
536 .as_object()
537 .ok_or(error!("DomainInt[1] contains a non-object"))?
538 .iter()
539 .next()
540 .ok_or(error!("DomainInt[1] contains an empty object"))?;
541 match range.0.as_str() {
542 "RangeBounded" => {
543 let arr = range
544 .1
545 .as_array()
546 .ok_or(error!("RangeBounded is not an array".to_owned()))?;
547 let mut nums = Vec::new();
548 for item in arr.iter() {
549 let num = parse_expression_to_int_val(item, &scope)?;
550 nums.push(num);
551 }
552 let lower = nums
553 .first()
554 .cloned()
555 .ok_or(error!("RangeBounded lower bound missing"))?;
556 let upper = nums
557 .get(1)
558 .cloned()
559 .ok_or(error!("RangeBounded upper bound missing"))?;
560 ranges.push(Range::Bounded(lower, upper));
561 }
562 "RangeSingle" => {
563 let num = parse_expression_to_int_val(range.1, &scope)?;
564 ranges.push(Range::Single(num));
565 }
566 _ => return throw_error!("DomainInt[1] contains an unknown object"),
567 }
568 }
569 Ok(Domain::int(ranges))
570}
571
572fn parse_expression_to_int_val(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<IntVal> {
573 parser_trace!("trying to parse domain value as expression: {}", obj);
574 let expr = parse_expression(obj, scope)?;
575
576 if let Some(Literal::Int(i)) = expr.clone().into_literal() {
577 return Ok(IntVal::Const(i));
578 }
579
580 if let Expression::Atomic(_, Atom::Reference(reference)) = &expr
581 && let Some(reference_val) = IntVal::new_ref(reference)
582 {
583 return Ok(reference_val);
584 }
585
586 IntVal::new_expr(Moo::new(expr)).ok_or(error!("Could not parse integer expression"))
587}
588
589type BinOp = fn(Metadata, Moo<Expression>, Moo<Expression>) -> Expression;
590type UnaryOp = fn(Metadata, Moo<Expression>) -> Expression;
591
592fn binary_operator(op_name: &str) -> Option<BinOp> {
593 match op_name {
594 "MkOpIn" => Some(Expression::In),
595 "MkOpUnion" => Some(Expression::Union),
596 "MkOpIntersect" => Some(Expression::Intersect),
597 "MkOpSupset" => Some(Expression::Supset),
598 "MkOpSupsetEq" => Some(Expression::SupsetEq),
599 "MkOpSubset" => Some(Expression::Subset),
600 "MkOpSubsetEq" => Some(Expression::SubsetEq),
601 "MkOpEq" => Some(Expression::Eq),
602 "MkOpNeq" => Some(Expression::Neq),
603 "MkOpGeq" => Some(Expression::Geq),
604 "MkOpLeq" => Some(Expression::Leq),
605 "MkOpGt" => Some(Expression::Gt),
606 "MkOpLt" => Some(Expression::Lt),
607 "MkOpLexLt" => Some(Expression::LexLt),
608 "MkOpLexGt" => Some(Expression::LexGt),
609 "MkOpLexLeq" => Some(Expression::LexLeq),
610 "MkOpLexGeq" => Some(Expression::LexGeq),
611 "MkOpDiv" => Some(Expression::UnsafeDiv),
612 "MkOpMod" => Some(Expression::UnsafeMod),
613 "MkOpMinus" => Some(Expression::Minus),
614 "MkOpImply" => Some(Expression::Imply),
615 "MkOpIff" => Some(Expression::Iff),
616 "MkOpPow" => Some(Expression::UnsafePow),
617 "MkOpImage" => Some(Expression::Image),
618 "MkOpImageSet" => Some(Expression::ImageSet),
619 "MkOpPreImage" => Some(Expression::PreImage),
620 "MkOpInverse" => Some(Expression::Inverse),
621 "MkOpRestrict" => Some(Expression::Restrict),
622 _ => None,
623 }
624}
625
626fn unary_operator(op_name: &str) -> Option<UnaryOp> {
627 match op_name {
628 "MkOpNot" => Some(Expression::Not),
629 "MkOpNegate" => Some(Expression::Neg),
630 "MkOpTwoBars" => Some(Expression::Abs),
631 "MkOpAnd" => Some(Expression::And),
632 "MkOpSum" => Some(Expression::Sum),
633 "MkOpProduct" => Some(Expression::Product),
634 "MkOpOr" => Some(Expression::Or),
635 "MkOpMin" => Some(Expression::Min),
636 "MkOpMax" => Some(Expression::Max),
637 "MkOpAllDiff" => Some(Expression::AllDiff),
638 "MkOpToInt" => Some(Expression::ToInt),
639 "MkOpDefined" => Some(Expression::Defined),
640 "MkOpRange" => Some(Expression::Range),
641 _ => None,
642 }
643}
644
645pub fn parse_expression(obj: &JsonValue, scope: &SymbolTablePtr) -> Result<Expression> {
646 let fail = |stage: &str| -> Error {
647 Error::Parse(format!(
648 "Could not parse expression at stage `{stage}` for json `{obj}`"
649 ))
650 };
651
652 match obj {
653 Value::Object(op) if op.contains_key("Op") => {
654 let op_obj = op
655 .get("Op")
656 .and_then(Value::as_object)
657 .ok_or_else(|| fail("Op.as_object"))?;
658 let (op_name, _) = op_obj.iter().next().ok_or_else(|| fail("Op.iter().next"))?;
659
660 if op_obj.contains_key("MkOpFlatten") {
661 parse_flatten_op(op_obj, scope)
662 } else if op_obj.contains_key("MkOpTable") {
663 parse_table_op(op_obj, scope)
664 } else if op_obj.contains_key("MkOpIndexing") || op_obj.contains_key("MkOpSlicing") {
665 parse_indexing_slicing_op(op_obj, scope)
666 } else if binary_operator(op_name).is_some() {
667 parse_bin_op(op_obj, scope)
668 } else if unary_operator(op_name).is_some() {
669 parse_unary_op(op_obj, scope)
670 } else {
671 Err(fail("Op.unknown"))
672 }
673 }
674 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
675 parse_comprehension(comprehension, scope.clone(), None)
676 }
677 Value::Object(refe) if refe.contains_key("Reference") => {
678 let ref_arr = refe["Reference"]
679 .as_array()
680 .ok_or_else(|| fail("Reference.as_array"))?;
681 let ref_obj = ref_arr
682 .first()
683 .and_then(|x| x.as_object())
684 .ok_or_else(|| fail("Reference[0].as_object"))?;
685 let name = ref_obj
686 .get("Name")
687 .and_then(|x| x.as_str())
688 .ok_or_else(|| fail("Reference[0].Name.as_str"))?;
689 let user_name = Name::User(Ustr::from(name));
690
691 let declaration: DeclarationPtr = scope
692 .read()
693 .lookup(&user_name)
694 .ok_or_else(|| fail("Reference.lookup"))?;
695
696 Ok(Expression::Atomic(
697 Metadata::new(),
698 Atom::Reference(crate::ast::Reference::new(declaration)),
699 ))
700 }
701 Value::Object(abslit) if abslit.contains_key("AbstractLiteral") => {
702 let abstract_literal = abslit["AbstractLiteral"]
703 .as_object()
704 .ok_or_else(|| fail("AbstractLiteral.as_object"))?;
705
706 if abstract_literal.contains_key("AbsLitSet") {
707 parse_abs_lit(&abslit["AbstractLiteral"]["AbsLitSet"], scope)
708 } else if abstract_literal.contains_key("AbsLitFunction") {
709 parse_abs_function(&abslit["AbstractLiteral"]["AbsLitFunction"], scope)
710 } else if abstract_literal.contains_key("AbsLitMSet") {
711 parse_abs_mset(&abslit["AbstractLiteral"]["AbsLitMSet"], scope)
712 } else {
713 parse_abstract_matrix_as_expr(obj, scope)
714 }
715 }
716
717 Value::Object(constant) if constant.contains_key("Constant") => {
718 parse_constant(constant, scope).or_else(|_| parse_abstract_matrix_as_expr(obj, scope))
719 }
720
721 Value::Object(constant) if constant.contains_key("ConstantAbstract") => {
722 parse_abstract_matrix_as_expr(obj, scope)
723 }
724
725 Value::Object(constant) if constant.contains_key("ConstantInt") => {
726 parse_constant(constant, scope)
727 }
728 Value::Object(constant) if constant.contains_key("ConstantBool") => {
729 parse_constant(constant, scope)
730 }
731
732 _ => Err(fail("no_match")),
733 }
734}
735
736fn parse_abs_lit(abs_set: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
737 let values = abs_set
738 .as_array()
739 .ok_or(error!("AbsLitSet is not an array"))?;
740 let expressions = values
741 .iter()
742 .map(|values| parse_expression(values, scope))
743 .collect::<Result<Vec<_>>>()?;
744
745 Ok(Expression::AbstractLiteral(
746 Metadata::new(),
747 AbstractLiteral::Set(expressions),
748 ))
749}
750
751fn parse_abs_mset(abs_mset: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
752 let values = abs_mset
753 .as_array()
754 .ok_or(error!("AbsLitMSet is not an array"))?;
755 let expressions = values
756 .iter()
757 .map(|values| parse_expression(values, scope))
758 .collect::<Result<Vec<_>>>()?;
759
760 Ok(Expression::AbstractLiteral(
761 Metadata::new(),
762 AbstractLiteral::MSet(expressions),
763 ))
764}
765
766fn parse_abs_tuple(abs_tuple: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
767 let values = abs_tuple
768 .as_array()
769 .ok_or(error!("AbsLitTuple is not an array"))?;
770 let expressions = values
771 .iter()
772 .map(|values| parse_expression(values, scope))
773 .collect::<Result<Vec<_>>>()?;
774
775 Ok(Expression::AbstractLiteral(
776 Metadata::new(),
777 AbstractLiteral::Tuple(expressions),
778 ))
779}
780
781fn parse_abs_record(abs_record: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
783 let entries = abs_record
784 .as_array()
785 .ok_or(error!("AbsLitRecord is not an array"))?;
786 let mut rec = vec![];
787
788 for entry in entries {
789 let entry = entry
790 .as_array()
791 .ok_or(error!("AbsLitRecord entry is not an array"))?;
792 let name = entry[0]
793 .as_object()
794 .ok_or(error!("AbsLitRecord field name is not an object"))?["Name"]
795 .as_str()
796 .ok_or(error!("AbsLitRecord field name is not a string"))?;
797
798 let value = parse_expression(&entry[1], scope)?;
799
800 let name = Name::User(Ustr::from(name));
801 let rec_entry = RecordValue {
802 name: name.clone(),
803 value,
804 };
805 rec.push(rec_entry);
806 }
807
808 Ok(Expression::AbstractLiteral(
809 Metadata::new(),
810 AbstractLiteral::Record(rec),
811 ))
812}
813
814fn parse_abs_function(abs_function: &Value, scope: &SymbolTablePtr) -> Result<Expression> {
816 let entries = abs_function
817 .as_array()
818 .ok_or(error!("AbsLitFunction is not an array"))?;
819 let mut assignments = vec![];
820
821 for entry in entries {
822 let entry = entry
823 .as_array()
824 .ok_or(error!("Explicit function assignment is not an array"))?;
825 let expression = entry
826 .iter()
827 .map(|values| parse_expression(values, scope))
828 .collect::<Result<Vec<_>>>()?;
829 let domain_value = expression
830 .first()
831 .ok_or(error!("Invalid function domain"))?;
832 let codomain_value = expression
833 .get(1)
834 .ok_or(error!("Invalid function codomain"))?;
835 let tuple = (domain_value.clone(), codomain_value.clone());
836 assignments.push(tuple);
837 }
838 Ok(Expression::AbstractLiteral(
839 Metadata::new(),
840 AbstractLiteral::Function(assignments),
841 ))
842}
843
844fn parse_comprehension(
845 comprehension: &serde_json::Map<String, Value>,
846 scope: SymbolTablePtr,
847 comprehension_kind: Option<ACOperatorKind>,
848) -> Result<Expression> {
849 let fail = |stage: &str| -> Error {
850 Error::Parse(format!("Could not parse comprehension at stage `{stage}`"))
851 };
852
853 let value = &comprehension["Comprehension"];
854 let mut comprehension = ComprehensionBuilder::new(scope.clone());
855 let generator_symboltable = comprehension.generator_symboltable();
856 let return_expr_symboltable = comprehension.return_expr_symboltable();
857
858 let generators_and_guards_array = value
859 .pointer("/1")
860 .and_then(Value::as_array)
861 .ok_or_else(|| fail("Comprehension.pointer(/1).as_array"))?;
862 let generators_and_guards = generators_and_guards_array.iter();
863
864 for gen_or_guard in generators_and_guards {
865 let gen_or_guard_obj = gen_or_guard
866 .as_object()
867 .ok_or_else(|| fail("generator_or_guard.as_object"))?;
868 let (name, inner) = gen_or_guard_obj
869 .iter()
870 .next()
871 .ok_or_else(|| fail("generator_or_guard.iter().next"))?;
872 comprehension = match name.as_str() {
873 "Generator" => {
874 let generator_obj = inner
876 .as_object()
877 .ok_or_else(|| fail("Generator.inner.as_object"))?;
878 let (name, gen_inner) = generator_obj
879 .iter()
880 .next()
881 .ok_or_else(|| fail("Generator.inner.iter().next"))?;
882 match name.as_str() {
883 "GenDomainNoRepr" => {
884 let name = gen_inner
885 .pointer("/0/Single/Name")
886 .and_then(Value::as_str)
887 .ok_or_else(|| {
888 fail("GenDomainNoRepr.pointer(/0/Single/Name).as_str")
889 })?;
890 let domain_obj = gen_inner
891 .pointer("/1")
892 .and_then(Value::as_object)
893 .ok_or_else(|| fail("GenDomainNoRepr.pointer(/1).as_object"))?;
894 let (domain_name, domain_value) = domain_obj
895 .iter()
896 .next()
897 .ok_or_else(|| fail("GenDomainNoRepr.domain.iter().next"))?;
898 let domain = parse_domain(
899 domain_name,
900 domain_value,
901 &mut generator_symboltable.write(),
902 )?;
903 comprehension.generator(DeclarationPtr::new_find(name.into(), domain))
904 }
905 "GenInExpr" => return parse_in_expr_comprehension(scope, value, gen_inner),
908 _ => {
909 bug!("unknown generator type inside comprehension {name}");
910 }
911 }
912 }
913
914 "Condition" => {
915 let expr = parse_expression(inner, &generator_symboltable)
916 .map_err(|_| fail("Condition.parse_expression"))?;
917 comprehension.guard(expr)
918 }
919
920 x => {
921 bug!("unknown field inside comprehension {x}");
922 }
923 }
924 }
925
926 let return_expr_value = value
927 .pointer("/0")
928 .ok_or_else(|| fail("Comprehension.pointer(/0)"))?;
929 let expr = parse_expression(return_expr_value, &return_expr_symboltable)
930 .map_err(|_| fail("Comprehension.return_expr.parse_expression"))?;
931
932 Ok(Expression::Comprehension(
933 Metadata::new(),
934 Moo::new(comprehension.with_return_value(expr, comprehension_kind)),
935 ))
936}
937
938fn parse_in_expr_comprehension(
939 scope: SymbolTablePtr,
940 comprehension_value: &Value,
941 gen_inner: &Value,
942) -> Result<Expression> {
943 let fail = |stage: &str| -> Error {
944 Error::Parse(format!(
945 "Could not parse GenInExpr comprehension at stage `{stage}`"
946 ))
947 };
948
949 let name = gen_inner
950 .pointer("/0/Single/Name")
951 .and_then(Value::as_str)
952 .ok_or_else(|| fail("GenInExpr.pointer(/0/Single/Name).as_str"))?;
953 let generator_expr = gen_inner
954 .pointer("/1")
955 .ok_or_else(|| fail("GenInExpr.pointer(/1)"))?;
956 let expr =
957 parse_expression(generator_expr, &scope).map_err(|_| fail("GenInExpr.parse_expression"))?;
958
959 let comprehension =
960 AbstractComprehensionBuilder::new(&scope).new_expression_generator(expr, name.into());
961 let return_expr_value = comprehension_value
962 .pointer("/0")
963 .ok_or_else(|| fail("comprehension_value.pointer(/0)"))?;
964 let expr = parse_expression(return_expr_value, &comprehension.return_expr_symbols())
965 .map_err(|_| fail("GenInExpr.return_expr.parse_expression"))?;
966
967 Ok(Expression::AbstractComprehension(
968 Metadata::new(),
969 Moo::new(comprehension.with_return_value(expr)),
970 ))
971}
972
973fn parse_bin_op(
974 bin_op: &serde_json::Map<String, Value>,
975 scope: &SymbolTablePtr,
976) -> Result<Expression> {
977 let (key, value) = bin_op
980 .into_iter()
981 .next()
982 .ok_or(error!("Binary op object is empty"))?;
983
984 let constructor = binary_operator(key.as_str())
985 .ok_or(error!(format!("Unknown binary operator `{}`", key)))?;
986
987 match &value {
988 Value::Array(bin_op_args) if bin_op_args.len() == 2 => {
989 let arg1 = parse_expression(&bin_op_args[0], scope)?;
990 let arg2 = parse_expression(&bin_op_args[1], scope)?;
991 Ok(constructor(Metadata::new(), Moo::new(arg1), Moo::new(arg2)))
992 }
993 _ => Err(error!("Binary operator arguments are not a 2-array")),
994 }
995}
996
997fn parse_table_op(
998 op: &serde_json::Map<String, Value>,
999 scope: &SymbolTablePtr,
1000) -> Result<Expression> {
1001 let args = op
1002 .get("MkOpTable")
1003 .ok_or(error!("MkOpTable missing"))?
1004 .as_array()
1005 .ok_or(error!("MkOpTable is not an array"))?;
1006
1007 if args.len() != 2 {
1008 return Err(error!("MkOpTable arguments are not a 2-array"));
1009 }
1010
1011 let tuple_expr = parse_expression(&args[0], scope)?;
1012 let allowed_rows_expr = parse_expression(&args[1], scope)?;
1013
1014 let (tuple_elems, _) = tuple_expr
1015 .clone()
1016 .unwrap_matrix_unchecked()
1017 .ok_or(error!("MkOpTable first argument is not a matrix"))?;
1018 let (allowed_rows, _) = allowed_rows_expr
1019 .clone()
1020 .unwrap_matrix_unchecked()
1021 .ok_or(error!("MkOpTable second argument is not a matrix"))?;
1022
1023 for row_expr in allowed_rows {
1024 let (row_elems, _) = row_expr
1025 .unwrap_matrix_unchecked()
1026 .ok_or(error!("MkOpTable row is not a matrix"))?;
1027
1028 if row_elems.len() != tuple_elems.len() {
1029 return Err(error!("MkOpTable row width does not match tuple width"));
1030 }
1031 }
1032
1033 Ok(Expression::Table(
1034 Metadata::new(),
1035 Moo::new(tuple_expr),
1036 Moo::new(allowed_rows_expr),
1037 ))
1038}
1039
1040fn parse_indexing_slicing_op(
1041 op: &serde_json::Map<String, Value>,
1042 scope: &SymbolTablePtr,
1043) -> Result<Expression> {
1044 let (key, value) = op
1047 .into_iter()
1048 .next()
1049 .ok_or(error!("Indexing/Slicing op object is empty"))?;
1050
1051 let mut target: Expression;
1060 let mut indices: Vec<Option<Expression>> = vec![];
1061
1062 let mut all_known = true;
1064
1065 match key.as_str() {
1066 "MkOpIndexing" => {
1067 match &value {
1068 Value::Array(op_args) if op_args.len() == 2 => {
1069 target = parse_expression(&op_args[0], scope)?;
1070 indices.push(Some(parse_expression(&op_args[1], scope)?));
1071 }
1072 _ => return Err(error!("Unknown object inside MkOpIndexing")),
1073 };
1074 }
1075
1076 "MkOpSlicing" => {
1077 all_known = false;
1078 match &value {
1079 Value::Array(op_args) if op_args.len() == 3 => {
1080 target = parse_expression(&op_args[0], scope)?;
1081 indices.push(None);
1082 }
1083 _ => return Err(error!("Unknown object inside MkOpSlicing")),
1084 };
1085 }
1086
1087 _ => return Err(error!("Unknown indexing/slicing operator")),
1088 }
1089
1090 loop {
1091 match &mut target {
1092 Expression::UnsafeIndex(_, new_target, new_indices) => {
1093 indices.extend(new_indices.iter().cloned().rev().map(Some));
1094 target = Moo::unwrap_or_clone(new_target.clone());
1095 }
1096
1097 Expression::UnsafeSlice(_, new_target, new_indices) => {
1098 all_known = false;
1099 indices.extend(new_indices.iter().cloned().rev());
1100 target = Moo::unwrap_or_clone(new_target.clone());
1101 }
1102
1103 _ => {
1104 break;
1106 }
1107 }
1108 }
1109
1110 indices.reverse();
1111
1112 if all_known {
1113 Ok(Expression::UnsafeIndex(
1114 Metadata::new(),
1115 Moo::new(target),
1116 indices
1117 .into_iter()
1118 .collect::<Option<Vec<_>>>()
1119 .ok_or(error!("Missing index in fully-known indexing operation"))?,
1120 ))
1121 } else {
1122 Ok(Expression::UnsafeSlice(
1123 Metadata::new(),
1124 Moo::new(target),
1125 indices,
1126 ))
1127 }
1128}
1129
1130fn parse_flatten_op(
1131 op: &serde_json::Map<String, Value>,
1132 scope: &SymbolTablePtr,
1133) -> Result<Expression> {
1134 let args = op
1135 .get("MkOpFlatten")
1136 .ok_or(error!("MkOpFlatten missing"))?
1137 .as_array()
1138 .ok_or(error!("MkOpFlatten is not an array"))?;
1139
1140 let first = args
1141 .first()
1142 .ok_or(error!("MkOpFlatten missing first argument"))?;
1143 let second = args
1144 .get(1)
1145 .ok_or(error!("MkOpFlatten missing second argument"))?;
1146 let n = parse_expression(first, scope).ok();
1147 let matrix = parse_expression(second, scope)?;
1148
1149 if let Some(n) = n {
1150 Ok(Expression::Flatten(
1151 Metadata::new(),
1152 Some(Moo::new(n)),
1153 Moo::new(matrix),
1154 ))
1155 } else {
1156 Ok(Expression::Flatten(Metadata::new(), None, Moo::new(matrix)))
1157 }
1158}
1159
1160fn parse_unary_op(
1161 un_op: &serde_json::Map<String, Value>,
1162 scope: &SymbolTablePtr,
1163) -> Result<Expression> {
1164 let fail = |stage: &str| -> Error {
1165 Error::Parse(format!("Could not parse unary op at stage `{stage}`"))
1166 };
1167
1168 let (key, value) = un_op
1169 .iter()
1170 .next()
1171 .ok_or_else(|| fail("un_op.iter().next"))?;
1172 let constructor = unary_operator(key.as_str()).ok_or_else(|| fail("unary_operator"))?;
1173
1174 let arg = match value {
1178 Value::Object(comprehension) if comprehension.contains_key("Comprehension") => {
1179 let comprehension_kind = match key.as_str() {
1180 "MkOpOr" => Some(ACOperatorKind::Or),
1181 "MkOpAnd" => Some(ACOperatorKind::And),
1182 "MkOpSum" => Some(ACOperatorKind::Sum),
1183 "MkOpProduct" => Some(ACOperatorKind::Product),
1184 _ => None,
1185 };
1186 parse_comprehension(comprehension, scope.clone(), comprehension_kind)
1187 .map_err(|_| fail("value.Comprehension.parse_comprehension"))
1188 }
1189 _ => parse_expression(value, scope).map_err(|_| fail("value.parse_expression")),
1190 }
1191 .map_err(|_| fail("arg"))?;
1192
1193 Ok(constructor(Metadata::new(), Moo::new(arg)))
1194}
1195
1196fn parse_abstract_matrix_as_expr(
1198 value: &serde_json::Value,
1199 scope: &SymbolTablePtr,
1200) -> Result<Expression> {
1201 parser_trace!("trying to parse an abstract literal matrix");
1202 let (values, domain_name, domain_value) =
1203 if let Some(abs_lit_matrix) = value.pointer("/AbstractLiteral/AbsLitMatrix") {
1204 parser_trace!(".. found JSON pointer /AbstractLiteral/AbstractLitMatrix");
1205 let (domain_name, domain_value) = abs_lit_matrix
1206 .pointer("/0")
1207 .and_then(Value::as_object)
1208 .and_then(|x| x.iter().next())
1209 .ok_or(error!("AbsLitMatrix missing domain"))?;
1210 let values = abs_lit_matrix
1211 .pointer("/1")
1212 .ok_or(error!("AbsLitMatrix missing values"))?;
1213
1214 Some((values, domain_name, domain_value))
1215 }
1216 else if let Some(const_abs_lit_matrix) =
1218 value.pointer("/Constant/ConstantAbstract/AbsLitMatrix")
1219 {
1220 parser_trace!(".. found JSON pointer /Constant/ConstantAbstract/AbsLitMatrix");
1221 let (domain_name, domain_value) = const_abs_lit_matrix
1222 .pointer("/0")
1223 .and_then(Value::as_object)
1224 .and_then(|x| x.iter().next())
1225 .ok_or(error!("ConstantAbstract AbsLitMatrix missing domain"))?;
1226 let values = const_abs_lit_matrix
1227 .pointer("/1")
1228 .ok_or(error!("ConstantAbstract AbsLitMatrix missing values"))?;
1229
1230 Some((values, domain_name, domain_value))
1231 } else if let Some(const_abs_lit_matrix) = value.pointer("/ConstantAbstract/AbsLitMatrix") {
1232 parser_trace!(".. found JSON pointer /ConstantAbstract/AbsLitMatrix");
1233 let (domain_name, domain_value) = const_abs_lit_matrix
1234 .pointer("/0")
1235 .and_then(Value::as_object)
1236 .and_then(|x| x.iter().next())
1237 .ok_or(error!("ConstantAbstract/AbsLitMatrix missing domain"))?;
1238 let values = const_abs_lit_matrix
1239 .pointer("/1")
1240 .ok_or(error!("ConstantAbstract/AbsLitMatrix missing values"))?;
1241 Some((values, domain_name, domain_value))
1242 } else {
1243 None
1244 }
1245 .ok_or(error!("Could not parse abstract literal matrix"))?;
1246
1247 parser_trace!(".. found in domain and values in JSON:");
1248 parser_trace!(".. .. index domain name {domain_name}");
1249 parser_trace!(".. .. values {value}");
1250
1251 let args_parsed = values
1252 .as_array()
1253 .ok_or(error!("Matrix values are not an array"))?
1254 .iter()
1255 .map(|x| parse_expression(x, scope))
1256 .collect::<Result<Vec<Expression>>>()?;
1257
1258 if !args_parsed.is_empty() {
1259 parser_trace!(
1260 ".. successfully parsed values as expressions: {}, ... ",
1261 args_parsed[0]
1262 );
1263 } else {
1264 parser_trace!(".. successfully parsed empty values ",);
1265 }
1266
1267 let mut symbols = scope.write();
1268 match parse_domain(domain_name, domain_value, &mut symbols) {
1269 Ok(domain) => {
1270 parser_trace!("... sucessfully parsed domain as {domain}");
1271 Ok(into_matrix_expr![args_parsed;domain])
1272 }
1273 Err(_) => {
1274 parser_trace!("... failed to parse domain, creating a matrix without one.");
1275 Ok(into_matrix_expr![args_parsed])
1276 }
1277 }
1278}
1279
1280fn parse_constant(
1281 constant: &serde_json::Map<String, Value>,
1282 scope: &SymbolTablePtr,
1283) -> Result<Expression> {
1284 match &constant.get("Constant") {
1285 Some(Value::Object(int)) if int.contains_key("ConstantInt") => {
1286 let int_32: i32 = match int["ConstantInt"]
1287 .as_array()
1288 .ok_or(error!("ConstantInt is not an array"))?[1]
1289 .as_i64()
1290 .ok_or(error!("ConstantInt does not contain int"))?
1291 .try_into()
1292 {
1293 Ok(x) => x,
1294 Err(_) => return Err(error!("ConstantInt cannot be represented as i32")),
1295 };
1296
1297 Ok(Expression::Atomic(
1298 Metadata::new(),
1299 Atom::Literal(Literal::Int(int_32)),
1300 ))
1301 }
1302
1303 Some(Value::Object(b)) if b.contains_key("ConstantBool") => {
1304 let b: bool = b["ConstantBool"]
1305 .as_bool()
1306 .ok_or(error!("ConstantBool does not contain bool"))?;
1307 Ok(Expression::Atomic(
1308 Metadata::new(),
1309 Atom::Literal(Literal::Bool(b)),
1310 ))
1311 }
1312
1313 Some(Value::Object(int)) if int.contains_key("ConstantAbstract") => {
1314 if let Some(Value::Object(obj)) = int.get("ConstantAbstract") {
1315 if let Some(arr) = obj.get("AbsLitSet") {
1316 return parse_abs_lit(arr, scope);
1317 } else if let Some(arr) = obj.get("AbsLitMSet") {
1318 return parse_abs_mset(arr, scope);
1319 } else if let Some(arr) = obj.get("AbsLitMatrix") {
1320 return parse_abstract_matrix_as_expr(arr, scope);
1321 } else if let Some(arr) = obj.get("AbsLitTuple") {
1322 return parse_abs_tuple(arr, scope);
1323 } else if let Some(arr) = obj.get("AbsLitRecord") {
1324 return parse_abs_record(arr, scope);
1325 } else if let Some(arr) = obj.get("AbsLitFunction") {
1326 return parse_abs_function(arr, scope);
1327 }
1328 }
1329 Err(error!("Unhandled ConstantAbstract literal type"))
1330 }
1331
1332 None => {
1335 let int_expr = constant
1336 .get("ConstantInt")
1337 .and_then(|x| x.as_array())
1338 .and_then(|x| x[1].as_i64())
1339 .and_then(|x| x.try_into().ok())
1340 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Int(x))));
1341
1342 if let Some(expr) = int_expr {
1343 return Ok(expr);
1344 }
1345
1346 let bool_expr = constant
1347 .get("ConstantBool")
1348 .and_then(|x| x.as_bool())
1349 .map(|x| Expression::Atomic(Metadata::new(), Atom::Literal(Literal::Bool(x))));
1350
1351 if let Some(expr) = bool_expr {
1352 return Ok(expr);
1353 }
1354
1355 Err(error!(format!("Unhandled parse_constant {constant:#?}")))
1356 }
1357 otherwise => Err(error!(format!("Unhandled parse_constant {otherwise:#?}"))),
1358 }
1359}