1use crate::ast::*;
3use crate::semantics::Value;
4use num_bigint::BigInt;
5use num_traits::Num;
6use std::rc::Rc;
7use tree_sitter::{Language, Node, Parser};
8use tree_sitter_language::LanguageFn;
9
10extern "C" {
11 fn tree_sitter_decl() -> *const ();
12}
13pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_decl) };
14
15#[derive(Clone)]
16pub struct ParseResult {
17 pub decls: Vec<Decl>,
18 pub errors: Vec<(usize, usize)>,
19}
20
21thread_local! {
26 static PARSE_CACHE: std::cell::RefCell<Vec<(String, ParseResult)>> = const { std::cell::RefCell::new(Vec::new()) };
27}
28
29struct Lower<'a> {
30 src: &'a [u8],
31}
32
33pub fn parse_source(src: &str) -> ParseResult {
34 if let Some(hit) = PARSE_CACHE.with(|c| {
35 c.borrow()
36 .iter()
37 .find(|(k, _)| k == src)
38 .map(|(_, r)| r.clone())
39 }) {
40 return hit;
41 }
42 let r = parse_source_uncached(src);
43 PARSE_CACHE.with(|c| {
44 let mut c = c.borrow_mut();
45 if c.len() >= 64 {
46 c.remove(0);
47 }
48 c.push((src.to_string(), r.clone()));
49 });
50 r
51}
52fn parse_source_uncached(src: &str) -> ParseResult {
53 let mut parser = Parser::new();
54 let lang: Language = LANGUAGE.into();
55 parser.set_language(&lang).expect("grammar");
56 let tree = parser.parse(src, None).expect("parse");
57 let root = tree.root_node();
58 let mut errors = Vec::new();
59 collect_errors(root, &mut errors);
60 let lw = Lower {
61 src: src.as_bytes(),
62 };
63 let mut decls = Vec::new();
64 let mut cur = root.walk();
65 for c in root.named_children(&mut cur) {
66 if c.kind() == "ERROR" {
67 continue;
68 }
69 match lw.decl(c) {
70 Ok(Some(mut d)) => {
71 let export_kw = c.prev_sibling().filter(|p| lw.text(*p) == "export");
72 let exported = export_kw.is_some() || matches!(d.body, DeclBody::ReExport { .. });
73 d.exported = exported;
74 let start = export_kw
77 .map(|p| p.start_position())
78 .unwrap_or_else(|| c.start_position());
79 let start_byte = export_kw
80 .map(|p| p.start_byte())
81 .unwrap_or_else(|| c.start_byte());
82 d.loc = Some(Loc {
83 sl: start.row,
84 sc: lw.col16(start_byte),
85 el: c.end_position().row,
86 ec: lw.col16(c.end_byte()),
87 });
88 decls.push(d);
89 }
90 Ok(None) => {}
91 Err(_) => {
92 if errors.is_empty() {
93 errors.push((c.start_position().row, c.start_position().column));
94 }
95 }
96 }
97 }
98 ParseResult { decls, errors }
99}
100
101fn collect_errors(n: Node, out: &mut Vec<(usize, usize)>) {
102 if n.kind() == "ERROR" || n.is_missing() {
103 out.push((n.start_position().row, n.start_position().column));
104 }
105 if n.has_error() {
106 let mut cur = n.walk();
107 for c in n.children(&mut cur) {
108 collect_errors(c, out);
109 }
110 }
111}
112
113type LR<T> = Result<T, String>;
114
115impl<'a> Lower<'a> {
116 fn text(&self, n: Node) -> String {
117 n.utf8_text(self.src).unwrap_or("").to_string()
118 }
119 fn field<'b>(&self, n: Node<'b>, name: &str) -> Option<Node<'b>> {
120 n.child_by_field_name(name)
121 }
122 fn req<'b>(&self, n: Node<'b>, name: &str) -> LR<Node<'b>> {
123 n.child_by_field_name(name)
124 .ok_or_else(|| format!("missing field {name}"))
125 }
126 fn named<'b>(&self, n: Node<'b>) -> Vec<Node<'b>> {
127 let mut cur = n.walk();
128 n.named_children(&mut cur).collect()
129 }
130 fn all<'b>(&self, n: Node<'b>) -> Vec<Node<'b>> {
131 let mut cur = n.walk();
132 n.children(&mut cur).collect()
133 }
134 fn kids<'b>(&self, n: Node<'b>, kind: &str) -> Vec<Node<'b>> {
135 self.named(n)
136 .into_iter()
137 .filter(|c| c.kind() == kind)
138 .collect()
139 }
140 fn kid<'b>(&self, n: Node<'b>, kind: &str) -> Option<Node<'b>> {
141 self.named(n).into_iter().find(|c| c.kind() == kind)
142 }
143 fn is_lit_keyword(&self, c: Node) -> bool {
147 !c.is_named() && ["true", "false", "null"].contains(&self.text(c).as_str())
148 }
149 fn operands<'b>(&self, n: Node<'b>) -> Vec<Node<'b>> {
150 self.all(n)
151 .into_iter()
152 .filter(|c| c.is_named() || self.is_lit_keyword(*c))
153 .collect()
154 }
155 fn first<'b>(&self, n: Node<'b>) -> LR<Node<'b>> {
158 self.named(n)
159 .into_iter()
160 .next()
161 .ok_or_else(|| format!("{}: missing child", n.kind()))
162 }
163 fn first_operand<'b>(&self, n: Node<'b>) -> LR<Node<'b>> {
164 self.operands(n)
165 .into_iter()
166 .next()
167 .ok_or_else(|| format!("{}: missing operand", n.kind()))
168 }
169 fn at<'b>(&self, v: &[Node<'b>], i: usize) -> LR<Node<'b>> {
170 v.get(i)
171 .copied()
172 .ok_or_else(|| format!("missing operand {i}"))
173 }
174 fn json_string(&self, n: Node) -> LR<String> {
175 json_unquote(&self.text(n).replace('\n', "\\n"))
176 }
177
178 fn decl(&self, n: Node) -> LR<Option<Decl>> {
180 let body = match n.kind() {
181 "type_declaration" => {
182 let params = match self.kid(n, "type_parameters") {
183 Some(ps) => self
184 .kids(ps, "type_parameter")
185 .into_iter()
186 .map(|p| {
187 let nc = self.named(p);
188 Ok(Param {
189 name: self.text(self.at(&nc, 0)?),
190 ty: if nc.len() > 1 {
191 Some(self.ty(nc[1])?)
192 } else {
193 None
194 },
195 })
196 })
197 .collect::<LR<Vec<_>>>()?,
198 None => vec![],
199 };
200 DeclBody::Type {
201 name: self.text(self.req(n, "name")?),
202 params,
203 ty: self.ty(self.req(n, "type")?)?,
204 tail: self.maybe_tail(n)?,
205 }
206 }
207 "const_declaration" => DeclBody::Const {
208 name: self.text(self.req(n, "name")?),
209 ty: match self.field(n, "type") {
210 Some(t) => Some(self.ty(t)?),
211 None => None,
212 },
213 expr: self.expr(self.req(n, "value")?)?,
214 },
215 "func_declaration" => DeclBody::Func {
216 name: self.text(self.req(n, "name")?),
217 params: self.params(n)?,
218 ret: match self.field(n, "return_type") {
219 Some(t) => Some(self.ty(t)?),
220 None => None,
221 },
222 body: self.expr(self.req(n, "body")?)?,
223 },
224 "output_declaration" => DeclBody::Output {
225 name: self.text(self.req(n, "name")?),
226 ty: self.ty(self.req(n, "type")?)?,
227 expr: self.expr(self.req(n, "value")?)?,
228 },
229 "input_declaration" => DeclBody::Input {
230 name: self.text(self.req(n, "name")?),
231 ty: self.ty(self.req(n, "type")?)?,
232 fallback: match self.field(n, "fallback") {
233 Some(f) => Some(self.expr(f)?),
234 None => None,
235 },
236 },
237 "diagnostic_declaration" => DeclBody::Diagnostic {
238 name: self.text(self.req(n, "name")?),
239 params: self.params(n)?,
240 severity: self.text(self.kid(n, "severity").ok_or("severity")?),
241 template: self.template_parts(self.kid(n, "template_string").ok_or("template")?)?,
242 },
243 "dimension_declaration" => DeclBody::Dimension {
244 name: self.text(self.req(n, "name")?),
245 terms: self
246 .kid(n, "dimension_expression")
247 .map(|e| self.dim_expr(e)),
248 },
249 "unit_declaration" => match self.field(n, "dimension") {
250 Some(d) => DeclBody::Unit {
251 name: self.text(self.req(n, "name")?),
252 dim: Some(self.text(d)),
253 factor: None,
254 base: None,
255 },
256 None => DeclBody::Unit {
257 name: self.text(self.req(n, "name")?),
258 dim: None,
259 factor: Some(self.expr(self.req(n, "factor")?)?),
260 base: Some(self.text(self.req(n, "base")?)),
261 },
262 },
263 "import_declaration" => {
264 let from = self.json_string(self.kid(n, "string").ok_or("from")?)?;
265 match self.kid(n, "named_imports") {
266 Some(ni) => DeclBody::Import {
267 from,
268 names: Some(self.import_items(ni)?),
269 ns: None,
270 },
271 None => DeclBody::Import {
272 from,
273 names: None,
274 ns: Some(self.text(self.kid(n, "identifier").ok_or("ns")?)),
275 },
276 }
277 }
278 "re_export_declaration" => DeclBody::ReExport {
279 from: self.json_string(self.kid(n, "string").ok_or("from")?)?,
280 names: self.import_items(n)?,
281 },
282 _ => return Ok(None),
283 };
284 Ok(Some(Decl {
285 body,
286 exported: false,
287 loc: None,
288 }))
289 }
290 fn params(&self, n: Node) -> LR<Vec<Param>> {
291 self.kids(n, "parameter")
292 .into_iter()
293 .map(|p| {
294 let nc = self.named(p);
295 Ok(Param {
296 name: self.text(self.at(&nc, 0)?),
297 ty: Some(self.ty(self.at(&nc, 1)?)?),
298 })
299 })
300 .collect()
301 }
302 fn import_items(&self, n: Node) -> LR<Vec<ImportItem>> {
303 self.kids(n, "import_item")
304 .into_iter()
305 .map(|it| {
306 let ids = self.named(it);
307 Ok(ImportItem {
308 name: self.text(self.at(&ids, 0)?),
309 alias: ids.get(1).map(|a| self.text(*a)),
310 })
311 })
312 .collect()
313 }
314 fn maybe_tail(&self, n: Node) -> LR<Option<Tail>> {
315 match self.kid(n, "else_clause") {
316 Some(t) => Ok(Some(self.tail(t)?)),
317 None => Ok(None),
318 }
319 }
320 fn tail(&self, n: Node) -> LR<Tail> {
321 if let Some(sev) = self.kid(n, "severity") {
322 return Ok(Tail::Inline {
323 severity: self.text(sev),
324 template: self.template_parts(self.kid(n, "template_string").ok_or("tmpl")?)?,
325 });
326 }
327 let name = self.text(self.kid(n, "qualified_name").ok_or("name")?);
328 let args = self
329 .named(n)
330 .into_iter()
331 .filter(|c| c.kind() != "qualified_name")
332 .map(|c| self.expr(c))
333 .collect::<LR<Vec<_>>>()?;
334 Ok(Tail::Ref { name, args })
335 }
336 fn template_parts(&self, n: Node) -> LR<Vec<TPart>> {
337 let mut parts = Vec::new();
338 for c in self.named(n) {
339 match c.kind() {
340 "template_chars" => parts.push(TPart::Text(self.text(c))),
341 "template_escape" => {
342 let t = self.text(c);
343 let s = match t.as_str() {
344 "\\n" => "\n",
345 "\\t" => "\t",
346 "\\r" => "\r",
347 other => &other[1..],
348 };
349 parts.push(TPart::Text(s.to_string()));
350 }
351 "interpolation" => parts.push(TPart::Expr(self.expr(self.first_operand(c)?)?)),
352 _ => {}
353 }
354 }
355 Ok(parts)
356 }
357
358 fn col16(&self, byte: usize) -> usize {
360 let start = self.src[..byte]
361 .iter()
362 .rposition(|&b| b == b'\n')
363 .map(|i| i + 1)
364 .unwrap_or(0);
365 String::from_utf8_lossy(&self.src[start..byte])
366 .encode_utf16()
367 .count()
368 }
369 fn loc_of(&self, n: Node) -> Loc {
370 Loc {
371 sl: n.start_position().row,
372 sc: self.col16(n.start_byte()),
373 el: n.end_position().row,
374 ec: self.col16(n.end_byte()),
375 }
376 }
377
378 fn ty(&self, n: Node) -> LR<TypeAst> {
380 let mut t = self.ty0(n)?;
381 t.set_loc(self.loc_of(n));
382 Ok(t)
383 }
384 fn ty0(&self, n: Node) -> LR<TypeAst> {
385 Ok(match n.kind() {
386 "union_type" => TypeAst::Union {
387 arms: self
388 .named(n)
389 .into_iter()
390 .map(|c| self.ty(c))
391 .collect::<LR<_>>()?,
392 loc: None,
393 },
394 "intersection_type" => TypeAst::Isect {
395 arms: self
396 .named(n)
397 .into_iter()
398 .map(|c| self.ty(c))
399 .collect::<LR<_>>()?,
400 loc: None,
401 },
402 "nullable_type" => TypeAst::Union {
403 arms: vec![
404 self.ty(self.first(n)?)?,
405 TypeAst::Prim {
406 name: "null".into(),
407 loc: None,
408 },
409 ],
410 loc: None,
411 },
412 "array_type" => {
413 let elem = Box::new(self.ty(self.first(n)?)?);
414 let range = self.kid(n, "array_size_range").or_else(|| {
415 self.field(n, "size")
416 .filter(|s| s.kind() == "range_expression")
417 });
418 if let Some(r) = range {
419 let ends: Vec<Value> = self
420 .named(r)
421 .into_iter()
422 .map(|c| self.const_num(c))
423 .collect::<LR<_>>()?;
424 let excl = self
425 .all(r)
426 .iter()
427 .any(|c| !c.is_named() && self.text(*c) == "..<");
428 let lo = num_or_name(ends.first().ok_or("range endpoint")?);
429 let hi = num_or_name(ends.get(1).ok_or("range endpoint")?);
430 return Ok(match hi {
431 Value::Int(h) => TypeAst::Array {
432 elem,
433 lo: Some(lo),
434 hi: Some(Value::Int(if excl { h - 1 } else { h })),
435 excl: false,
436 loc: None,
437 },
438 other => TypeAst::Array {
439 elem,
440 lo: Some(lo),
441 hi: Some(other),
442 excl,
443 loc: None,
444 },
445 });
446 }
447 if let Some(size) = self.field(n, "size") {
448 let v = num_or_name(&self.const_num(size)?);
449 return Ok(TypeAst::Array {
450 elem,
451 lo: Some(v.clone()),
452 hi: Some(v),
453 excl: false,
454 loc: None,
455 });
456 }
457 TypeAst::Array {
458 elem,
459 lo: None,
460 hi: None,
461 excl: false,
462 loc: None,
463 }
464 }
465 "range_type" => {
466 let nc = self.named(n);
467 TypeAst::Range {
468 lo: self.const_num(self.at(&nc, 0)?)?,
469 hi: self.const_num(self.at(&nc, 1)?)?,
470 excl: self.text(n).contains("..<"),
471 loc: None,
472 }
473 }
474 "number_literal" => TypeAst::Lit {
475 v: self.const_num(n)?,
476 loc: None,
477 },
478 "string" => TypeAst::Lit {
479 v: Value::Str(self.json_string(n)?),
480 loc: None,
481 },
482 "pattern" => {
483 let t = self.text(n);
484 TypeAst::Pattern {
485 re: t[1..t.len() - 1].to_string(),
486 loc: None,
487 }
488 }
489 "paren_type" => self.ty(self.first(n)?)?,
490 "record_type" => {
491 let mut open = false;
492 let mut members = Vec::new();
493 for c in self.named(n) {
494 if c.kind() == "open_marker" {
495 open = true;
496 continue;
497 }
498 if let Some(m) = self.member(c)? {
499 members.push(m);
500 }
501 }
502 TypeAst::Record {
503 members,
504 open,
505 loc: None,
506 }
507 }
508 "map_type" => TypeAst::Map {
509 key: Box::new(self.ty(self.req(n, "key")?)?),
510 val: Box::new(self.ty(self.req(n, "value")?)?),
511 loc: None,
512 },
513 "function_type" => {
514 let mut cs: Vec<TypeAst> = self
515 .named(n)
516 .into_iter()
517 .map(|c| self.ty(c))
518 .collect::<LR<_>>()?;
519 let ret = cs.pop().ok_or("func type")?;
520 TypeAst::Func {
521 params: cs,
522 ret: Box::new(ret),
523 loc: None,
524 }
525 }
526 "named_type" => {
527 let name = self.text(self.kid(n, "qualified_name").ok_or("name")?);
528 let args = match self.kid(n, "type_arguments") {
529 Some(a) => self
530 .named(a)
531 .into_iter()
532 .map(|c| self.ty(c))
533 .collect::<LR<_>>()?,
534 None => vec![],
535 };
536 let preds = match self.field(n, "predicates") {
537 Some(p) => Some(
538 self.named(p)
539 .into_iter()
540 .map(|c| self.expr(c))
541 .collect::<LR<_>>()?,
542 ),
543 None => None,
544 };
545 let ext = match self.field(n, "extension") {
546 Some(e) => Some(Box::new(self.ty(e)?)),
547 None => None,
548 };
549 if ["int", "uint", "float", "bool", "string"].contains(&name.as_str())
550 && args.is_empty()
551 && preds.is_none()
552 && ext.is_none()
553 {
554 return Ok(TypeAst::Prim { name, loc: None });
555 }
556 TypeAst::Named {
557 name,
558 args,
559 preds,
560 ext,
561 loc: None,
562 }
563 }
564 _ => match self.text(n).as_str() {
565 "true" => TypeAst::Lit {
566 v: Value::Bool(true),
567 loc: None,
568 },
569 "false" => TypeAst::Lit {
570 v: Value::Bool(false),
571 loc: None,
572 },
573 "null" => TypeAst::Prim {
574 name: "null".into(),
575 loc: None,
576 },
577 other => return Err(format!("lower_type: unhandled {} '{}'", n.kind(), other)),
578 },
579 })
580 }
581 fn dim_expr(&self, n: Node) -> Vec<(String, i32)> {
582 let mut out = Vec::new();
583 let mut sign = 1;
584 for c in self.all(n) {
585 if !c.is_named() {
586 match self.text(c).as_str() {
587 "/" => sign = -1,
588 "*" => sign = 1,
589 _ => {}
590 }
591 continue;
592 }
593 if c.kind() == "dimension_term" {
594 let nc = self.named(c);
595 let Some(ident) = nc.iter().find(|x| x.kind() == "identifier") else {
596 continue;
597 };
598 let num = nc.iter().find(|x| x.kind() == "int");
599 let mut exp: i32 = num.map(|x| self.text(*x).parse().unwrap_or(1)).unwrap_or(1);
600 if self
601 .all(c)
602 .iter()
603 .any(|x| !x.is_named() && self.text(*x) == "-")
604 {
605 exp = -exp;
606 }
607 out.push((self.text(*ident), exp * sign));
608 sign = 1;
609 }
610 }
611 out
612 }
613 fn const_num(&self, n: Node) -> LR<Value> {
614 match n.kind() {
615 "number_literal" => {
616 let neg = self.text(n).trim_start().starts_with('-');
617 let v = self.const_num(self.first(n)?)?;
618 Ok(if neg { neg_value(v) } else { v })
619 }
620 "int" => Ok(Value::Int(parse_int(&self.text(n))?)),
621 "float" => Ok(Value::Float(
622 self.text(n)
623 .replace('_', "")
624 .parse::<f64>()
625 .map_err(|e| e.to_string())?,
626 )),
627 "qualified_name" | "identifier" => Ok(Value::Str(self.text(n))),
628 k => Err(format!("const_num: {k}")),
629 }
630 }
631
632 fn member(&self, n: Node) -> LR<Option<MemberAst>> {
634 let mut m = self.member0(n)?;
635 if let Some(m) = m.as_mut() {
636 m.set_loc(self.loc_of(n));
637 }
638 Ok(m)
639 }
640 fn member0(&self, n: Node) -> LR<Option<MemberAst>> {
641 Ok(Some(match n.kind() {
642 "value_member" => {
645 let name_n = self.req(n, "name")?;
646 let name = if name_n.kind() == "string" {
647 self.json_string(name_n)?
648 } else {
649 self.text(name_n)
650 };
651 let opt = self.field(n, "optional").is_some();
652 let dflt = match self.field(n, "default") {
653 Some(d) => Some(self.expr(d)?),
654 None => None,
655 };
656 match dflt {
657 Some(expr) if !opt => MemberAst::Derived {
658 name,
659 ty: Some(self.ty(self.req(n, "type")?)?),
660 expr,
661 hidden: false,
662 loc: None,
663 },
664 dflt => MemberAst::Value {
665 name,
666 opt,
667 ty: self.ty(self.req(n, "type")?)?,
668 dflt,
669 loc: None,
670 },
671 }
672 }
673 "derived_member" => {
674 let name_n = self.req(n, "name")?;
675 MemberAst::Derived {
676 name: if name_n.kind() == "string" {
677 self.json_string(name_n)?
678 } else {
679 self.text(name_n)
680 },
681 ty: None,
682 expr: self.expr(self.req(n, "value")?)?,
683 hidden: false,
684 loc: None,
685 }
686 }
687 "hidden_member" => MemberAst::Derived {
689 name: self.text(self.req(n, "name")?),
690 ty: match self.field(n, "type") {
691 Some(t) => Some(self.ty(t)?),
692 None => None,
693 },
694 expr: self.expr(self.req(n, "value")?)?,
695 hidden: true,
696 loc: None,
697 },
698 "context_declaration" => MemberAst::Context {
699 variable: self.text(self.req(n, "variable")?),
700 ty: self.ty(self.req(n, "type")?)?,
701 loc: None,
702 },
703 "assert_member" => MemberAst::Assert {
704 name: self.text(self.req(n, "name")?),
705 cond: self.expr(self.req(n, "condition")?)?,
706 tail: self.maybe_tail(n)?,
707 loc: None,
708 },
709 "when_member" => {
710 let mut body = Vec::new();
711 for c in self.named(n).into_iter().skip(1) {
712 if let Some(m) = self.member(c)? {
713 body.push(m);
714 }
715 }
716 MemberAst::When {
717 cond: self.expr(self.req(n, "condition")?)?,
718 body,
719 loc: None,
720 }
721 }
722 _ => return Ok(None),
723 }))
724 }
725
726 fn expr(&self, n: Node) -> LR<Rc<Expr>> {
728 let e = Rc::new(self.expr_inner(n)?);
729 set_expr_loc(&e, self.loc_of(n));
730 Ok(e)
731 }
732 fn expr_inner(&self, n: Node) -> LR<Expr> {
733 const BIN: [&str; 13] = [
734 "pipe_expression",
735 "nullish_expression",
736 "binary_expression_or",
737 "binary_expression_and",
738 "bit_or_expression",
739 "bit_xor_expression",
740 "bit_and_expression",
741 "equality_expression",
742 "relational_expression",
743 "range_expression",
744 "shift_expression",
745 "additive_expression",
746 "multiplicative_expression",
747 ];
748 Ok(match n.kind() {
749 "int" => Expr::Lit(Value::Int(parse_int(&self.text(n))?)),
750 "float" => Expr::Lit(Value::Float(
751 self.text(n)
752 .replace('_', "")
753 .parse::<f64>()
754 .map_err(|e| e.to_string())?,
755 )),
756 "unit_literal" => {
757 let t = self.text(n);
758 let re =
759 regex::Regex::new(r"^([0-9._]+(?:[eE][+-]?[0-9]+)?)([A-Za-z][A-Za-z0-9]*)$")
760 .unwrap();
761 let caps = re.captures(&t).ok_or("unit literal")?;
762 Expr::UnitLit {
763 num: caps[1]
764 .replace('_', "")
765 .parse::<f64>()
766 .map_err(|e| e.to_string())?,
767 unit: caps[2].to_string(),
768 }
769 }
770 "string" => Expr::Lit(Value::Str(self.json_string(n)?)),
771 "template_string" => Expr::Template(self.template_parts(n)?),
772 "identifier" | "hidden_name" => Expr::Name(self.text(n)),
773 "context_variable" => Expr::Ctx(self.text(n)),
774 "referrers_expression" => Expr::Referrers {
775 ty: self.text(self.req(n, "type")?),
776 member: self.json_string(self.req(n, "member")?)?,
777 },
778 "paren_expression" => Expr::Paren(self.expr(self.first_operand(n)?)?),
779 "unary_expression" => Expr::Un {
780 op: self.text(self.all(n).into_iter().next().ok_or("operator")?),
781 x: self.expr(self.first_operand(n)?)?,
782 },
783 "if_expression" => Expr::If {
784 c: self.expr(self.req(n, "condition")?)?,
785 t: self.expr(self.req(n, "then")?)?,
786 f: self.expr(self.req(n, "else")?)?,
787 },
788 "lambda" => Expr::Lambda {
789 params: self
790 .kids(n, "lambda_parameter")
791 .into_iter()
792 .map(|p| self.first(p).map(|c| self.text(c)))
793 .collect::<LR<_>>()?,
794 body: self.expr(self.req(n, "body")?)?,
795 },
796 "with_expression" => {
797 let nc = self.operands(n);
798 Expr::With {
799 base: self.expr(self.at(&nc, 0)?)?,
800 patch: self.expr(self.at(&nc, 1)?)?,
801 }
802 }
803 "member_access" | "safe_access" => {
804 let nc = self.operands(n);
805 let name_n = self.at(&nc, 1)?;
806 Expr::Member {
807 x: self.expr(self.at(&nc, 0)?)?,
808 name: if name_n.kind() == "string" {
809 self.json_string(name_n)?
810 } else {
811 self.text(name_n)
812 },
813 safe: n.kind() == "safe_access",
814 }
815 }
816 "index_access" => {
817 let nc = self.operands(n);
818 Expr::Index {
819 x: self.expr(self.at(&nc, 0)?)?,
820 i: self.expr(self.at(&nc, 1)?)?,
821 }
822 }
823 "call" => {
824 let cs = self.operands(n);
825 Expr::Call {
826 fun: self.expr(self.at(&cs, 0)?)?,
827 args: cs
828 .iter()
829 .skip(1)
830 .map(|c| self.expr(*c))
831 .collect::<LR<_>>()?,
832 }
833 }
834 "object" => {
835 if let Some(comp) = self.kid(n, "map_comprehension") {
836 return self.expr_inner(comp);
837 }
838 let mut entries = Vec::new();
839 for en in self.kids(n, "object_entry") {
840 match self.field(en, "key") {
841 Some(k) => entries.push((
842 if k.kind() == "string" {
843 self.json_string(k)?
844 } else {
845 self.text(k)
846 },
847 self.expr(self.req(en, "value")?)?,
848 )),
849 None => entries.push(("...".to_string(), self.expr(self.first(en)?)?)),
850 }
851 }
852 Expr::Obj(entries)
853 }
854 "map_comprehension" => Expr::MapComp {
855 key: self.expr(self.req(n, "key")?)?,
856 val: self.expr(self.req(n, "value")?)?,
857 clauses: self
858 .kids(n, "for_clause")
859 .into_iter()
860 .map(|c| self.for_clause(c))
861 .collect::<LR<_>>()?,
862 },
863 "array" => {
864 if let Some(comp) = self.kid(n, "array_comprehension") {
865 return self.expr_inner(comp);
866 }
867 let mut items = Vec::new();
868 for en in self.kids(n, "array_entry") {
869 let spread = self.text(en).starts_with("...");
870 let inner = self
871 .named(en)
872 .into_iter()
873 .next()
874 .or_else(|| {
875 self.all(en).into_iter().find(|c| {
876 ["true", "false", "null"].contains(&self.text(*c).as_str())
877 })
878 })
879 .ok_or("entry")?;
880 items.push((spread, self.expr(inner)?));
881 }
882 Expr::Arr(items)
883 }
884 "array_comprehension" => Expr::Comp {
885 head: self.expr(self.req(n, "head")?)?,
886 clauses: self
887 .kids(n, "for_clause")
888 .into_iter()
889 .map(|c| self.for_clause(c))
890 .collect::<LR<_>>()?,
891 },
892 "matches_expression" => {
893 let nc = self.named(n);
894 Expr::Bin {
895 op: "matches".into(),
896 l: self.expr(self.at(&nc, 0)?)?,
897 r: self.expr(self.at(&nc, 1)?)?,
898 }
899 }
900 "pattern" => {
901 let t = self.text(n);
902 Expr::Pattern(t[1..t.len() - 1].to_string())
903 }
904 "match_expression" => {
905 let mut arms = Vec::new();
906 for a in self.kids(n, "match_arm") {
907 let body = self.req(a, "body")?;
908 let others: Vec<Node> = self
909 .named(a)
910 .into_iter()
911 .filter(|c| c.id() != body.id())
912 .collect();
913 arms.push(MatchArm {
914 v: self.text(self.at(&others, 0)?),
915 ty: if others.len() > 1 {
916 Some(self.ty(others[1])?)
917 } else {
918 None
919 },
920 body: self.expr(body)?,
921 });
922 }
923 Expr::Match {
924 subject: self.expr(self.req(n, "subject")?)?,
925 arms,
926 }
927 }
928 k if BIN.contains(&k) => {
929 let nc = self.operands(n);
930 let op = self
932 .all(n)
933 .into_iter()
934 .filter(|c| !c.is_named() && !self.is_lit_keyword(*c))
935 .map(|c| self.text(c))
936 .find(|t| !t.trim().is_empty())
937 .ok_or("op")?;
938 Expr::Bin {
939 op,
940 l: self.expr(self.at(&nc, 0)?)?,
941 r: self.expr(self.at(&nc, 1)?)?,
942 }
943 }
944 _ => match self.text(n).as_str() {
945 "true" => Expr::Lit(Value::Bool(true)),
946 "false" => Expr::Lit(Value::Bool(false)),
947 "null" => Expr::Lit(Value::Null),
948 other => return Err(format!("lower_expr: unhandled {} '{}'", n.kind(), other)),
949 },
950 })
951 }
952 fn for_clause(&self, n: Node) -> LR<ForClause> {
953 let mut cur = n.walk();
954 let filters = n
955 .children_by_field_name("filter", &mut cur)
956 .map(|c| self.expr(c))
957 .collect::<LR<Vec<_>>>()?;
958 Ok(ForClause {
959 v: self.text(self.req(n, "variable")?),
960 iter: self.expr(self.req(n, "iterable")?)?,
961 filters,
962 })
963 }
964}
965
966fn num_or_name(v: &Value) -> Value {
967 match v {
968 Value::Float(f) => Value::Int(BigInt::from(*f as i64)),
969 other => other.clone(),
970 }
971}
972fn neg_value(v: Value) -> Value {
973 match v {
974 Value::Int(i) => Value::Int(-i),
975 Value::Float(f) => Value::Float(-f),
976 other => other,
977 }
978}
979pub fn parse_int(text: &str) -> LR<BigInt> {
980 let t = text.replace('_', "");
981 let (radix, digits) = if let Some(h) = t.strip_prefix("0x").or_else(|| t.strip_prefix("0X")) {
982 (16, h.to_string())
983 } else if let Some(o) = t.strip_prefix("0o").or_else(|| t.strip_prefix("0O")) {
984 (8, o.to_string())
985 } else if let Some(b) = t.strip_prefix("0b").or_else(|| t.strip_prefix("0B")) {
986 (2, b.to_string())
987 } else {
988 (10, t.clone())
989 };
990 BigInt::from_str_radix(&digits, radix).map_err(|e| e.to_string())
991}
992
993pub fn json_unquote(s: &str) -> LR<String> {
995 let inner = &s[1..s.len() - 1];
996 let mut out = String::new();
997 let mut chars = inner.chars();
998 while let Some(c) = chars.next() {
999 if c != '\\' {
1000 out.push(c);
1001 continue;
1002 }
1003 match chars.next() {
1004 Some('n') => out.push('\n'),
1005 Some('t') => out.push('\t'),
1006 Some('r') => out.push('\r'),
1007 Some('b') => out.push('\u{8}'),
1008 Some('f') => out.push('\u{c}'),
1009 Some('u') => {
1010 let hex: String = chars.by_ref().take(4).collect();
1011 let cp = u32::from_str_radix(&hex, 16).map_err(|e| e.to_string())?;
1012 out.push(char::from_u32(cp).unwrap_or('\u{fffd}'));
1013 }
1014 Some(other) => out.push(other),
1015 None => {}
1016 }
1017 }
1018 Ok(out)
1019}