1use crate::{
2 expr::{
3 Arg, Bind, Expr, ExprId, ExprKind, Lambda, ModPath, ModuleKind, Pattern,
4 StructurePattern,
5 },
6 typ::{FnArgType, FnType, TVar, Type},
7};
8use anyhow::{bail, Result};
9use arcstr::{literal, ArcStr};
10use combine::{
11 attempt, between, chainl1, choice, eof, look_ahead, many, many1, none_of,
12 not_followed_by, optional,
13 parser::{
14 char::{alpha_num, digit, space, string},
15 combinator::recognize,
16 range::{take_while, take_while1},
17 },
18 position, sep_by, sep_by1, skip_many,
19 stream::{
20 position::{self, SourcePosition},
21 Range,
22 },
23 token, unexpected_any, value, EasyParser, ParseError, Parser, RangeStream,
24};
25use compact_str::CompactString;
26use fxhash::FxHashSet;
27use netidx::{
28 path::Path,
29 publisher::{Typ, Value},
30 utils::Either,
31};
32use netidx_value::parser::{escaped_string, int, value as parse_value, VAL_ESC};
33use parking_lot::RwLock;
34use smallvec::{smallvec, SmallVec};
35use std::sync::LazyLock;
36use triomphe::Arc;
37
38use super::Origin;
39
40#[cfg(test)]
41mod test;
42
43pub const GRAPHIX_ESC: [char; 4] = ['"', '\\', '[', ']'];
44pub const RESERVED: LazyLock<FxHashSet<&str>> = LazyLock::new(|| {
45 FxHashSet::from_iter([
46 "true", "false", "ok", "null", "mod", "let", "select", "pub", "type", "fn",
47 "cast", "if", "u32", "v32", "i32", "z32", "u64", "v64", "i64", "z64", "f32",
48 "f64", "decimal", "datetime", "duration", "bool", "string", "bytes", "result",
49 "null", "_", "?", "fn", "Array", "any", "Any", "use",
50 ])
51});
52
53fn spaces<I>() -> impl Parser<I, Output = ()>
54where
55 I: RangeStream<Token = char>,
56 I::Error: ParseError<I::Token, I::Range, I::Position>,
57 I::Range: Range,
58{
59 combine::parser::char::spaces().with(skip_many(attempt(
60 string("//")
61 .with(not_followed_by(token('/')))
62 .with(skip_many(none_of(['\n'])))
63 .with(combine::parser::char::spaces()),
64 )))
65}
66
67fn doc_comment<I>() -> impl Parser<I, Output = Option<ArcStr>>
68where
69 I: RangeStream<Token = char>,
70 I::Error: ParseError<I::Token, I::Range, I::Position>,
71 I::Range: Range,
72{
73 combine::parser::char::spaces()
74 .with(many(
75 string("///")
76 .with(many(none_of(['\n'])))
77 .skip(combine::parser::char::spaces()),
78 ))
79 .map(
80 |lines: SmallVec<[String; 8]>| {
81 if lines.len() == 0 {
82 None
83 } else {
84 Some(ArcStr::from(lines.join("\n")))
85 }
86 },
87 )
88}
89
90fn spstring<'a, I>(s: &'static str) -> impl Parser<I, Output = &'a str>
91where
92 I: RangeStream<Token = char>,
93 I::Error: ParseError<I::Token, I::Range, I::Position>,
94 I::Range: Range,
95{
96 spaces().with(string(s))
97}
98
99fn ident<I>(cap: bool) -> impl Parser<I, Output = ArcStr>
100where
101 I: RangeStream<Token = char>,
102 I::Error: ParseError<I::Token, I::Range, I::Position>,
103 I::Range: Range,
104{
105 recognize((
106 take_while1(move |c: char| c.is_alphabetic() && cap == c.is_uppercase()),
107 take_while(|c: char| c.is_alphanumeric() || c == '_'),
108 ))
109 .map(|s: CompactString| ArcStr::from(s.as_str()))
110}
111
112fn fname<I>() -> impl Parser<I, Output = ArcStr>
113where
114 I: RangeStream<Token = char>,
115 I::Error: ParseError<I::Token, I::Range, I::Position>,
116 I::Range: Range,
117{
118 ident(false).then(|s| {
119 if RESERVED.contains(&s.as_str()) {
120 unexpected_any("can't use keyword as a function or variable name").left()
121 } else {
122 value(s).right()
123 }
124 })
125}
126
127fn spfname<I>() -> impl Parser<I, Output = ArcStr>
128where
129 I: RangeStream<Token = char>,
130 I::Error: ParseError<I::Token, I::Range, I::Position>,
131 I::Range: Range,
132{
133 spaces().with(fname())
134}
135
136fn typname<I>() -> impl Parser<I, Output = ArcStr>
137where
138 I: RangeStream<Token = char>,
139 I::Error: ParseError<I::Token, I::Range, I::Position>,
140 I::Range: Range,
141{
142 ident(true).then(|s| {
143 if RESERVED.contains(&s.as_str()) {
144 unexpected_any("can't use keyword as a type name").left()
145 } else {
146 value(s).right()
147 }
148 })
149}
150
151fn sptypname<I>() -> impl Parser<I, Output = ArcStr>
152where
153 I: RangeStream<Token = char>,
154 I::Error: ParseError<I::Token, I::Range, I::Position>,
155 I::Range: Range,
156{
157 spaces().with(typname())
158}
159
160pub(crate) fn modpath<I>() -> impl Parser<I, Output = ModPath>
161where
162 I: RangeStream<Token = char>,
163 I::Error: ParseError<I::Token, I::Range, I::Position>,
164 I::Range: Range,
165{
166 sep_by1(fname(), string("::"))
167 .map(|v: SmallVec<[ArcStr; 4]>| ModPath(Path::from_iter(v)))
168}
169
170fn spmodpath<I>() -> impl Parser<I, Output = ModPath>
171where
172 I: RangeStream<Token = char>,
173 I::Error: ParseError<I::Token, I::Range, I::Position>,
174 I::Range: Range,
175{
176 spaces().with(modpath())
177}
178
179fn typath<I>() -> impl Parser<I, Output = ModPath>
180where
181 I: RangeStream<Token = char>,
182 I::Error: ParseError<I::Token, I::Range, I::Position>,
183 I::Range: Range,
184{
185 sep_by1(choice((attempt(spfname()), sptypname())), string("::")).then(
186 |parts: SmallVec<[ArcStr; 8]>| {
187 if parts.len() == 0 {
188 unexpected_any("empty type path").left()
189 } else {
190 match parts.last().unwrap().chars().next() {
191 None => unexpected_any("empty name").left(),
192 Some(c) if c.is_lowercase() => {
193 unexpected_any("type names must be capitalized").left()
194 }
195 Some(_) => value(ModPath::from(parts)).right(),
196 }
197 }
198 },
199 )
200}
201
202fn sptypath<I>() -> impl Parser<I, Output = ModPath>
203where
204 I: RangeStream<Token = char>,
205 I::Error: ParseError<I::Token, I::Range, I::Position>,
206 I::Range: Range,
207{
208 spaces().with(typath())
209}
210
211fn csep<I>() -> impl Parser<I, Output = char>
212where
213 I: RangeStream<Token = char>,
214 I::Error: ParseError<I::Token, I::Range, I::Position>,
215 I::Range: Range,
216{
217 attempt(spaces().with(token(',')))
218}
219
220fn sptoken<I>(t: char) -> impl Parser<I, Output = char>
221where
222 I: RangeStream<Token = char>,
223 I::Error: ParseError<I::Token, I::Range, I::Position>,
224 I::Range: Range,
225{
226 spaces().with(token(t))
227}
228
229parser! {
230 fn interpolated[I]()(I) -> Expr
231 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
232 {
233 #[derive(Debug, Clone)]
234 enum Intp {
235 Lit(SourcePosition, String),
236 Expr(Expr),
237 }
238 impl Intp {
239 fn to_expr(self) -> Expr {
240 match self {
241 Intp::Lit(pos, s) => Expr {
242 id: ExprId::new(),
243 pos,
244 kind: ExprKind::Constant(Value::from(s)),
245 },
246 Intp::Expr(s) => s,
247 }
248 }
249 }
250 (
251 position(),
252 between(
253 token('"'),
254 token('"'),
255 many(choice((
256 attempt(between(token('['), sptoken(']'), expr()).map(Intp::Expr)),
257 (position(), escaped_string(&GRAPHIX_ESC)).then(|(pos, s)| {
258 if s.is_empty() {
259 unexpected_any("empty string").right()
260 } else {
261 value(Intp::Lit(pos, s)).left()
262 }
263 }),
264 ))),
265 ),
266 )
267 .map(|(pos, toks): (_, SmallVec<[Intp; 8]>)| {
268 let mut argvec = vec![];
269 toks.into_iter()
270 .fold(None, |src, tok| -> Option<Expr> {
271 match (src, tok) {
272 (None, t @ Intp::Lit(_, _)) => Some(t.to_expr()),
273 (None, Intp::Expr(s)) => {
274 argvec.push(s);
275 Some(
276 ExprKind::StringInterpolate {
277 args: Arc::from_iter(argvec.clone().into_iter()),
278 }
279 .to_expr(pos),
280 )
281 }
282 (Some(src @ Expr { kind: ExprKind::Constant(_), .. }), s) => {
283 argvec.extend([src, s.to_expr()]);
284 Some(
285 ExprKind::StringInterpolate {
286 args: Arc::from_iter(argvec.clone().into_iter()),
287 }
288 .to_expr(pos),
289 )
290 }
291 (
292 Some(Expr {
293 kind: ExprKind::StringInterpolate { args: _ },
294 ..
295 }),
296 s,
297 ) => {
298 argvec.push(s.to_expr());
299 Some(
300 ExprKind::StringInterpolate {
301 args: Arc::from_iter(argvec.clone().into_iter()),
302 }
303 .to_expr(pos),
304 )
305 }
306 (Some(Expr { kind: ExprKind::Bind { .. }, .. }), _)
307 | (Some(Expr { kind: ExprKind::StructWith { .. }, .. }), _)
308 | (Some(Expr { kind: ExprKind::Array { .. }, .. }), _)
309 | (Some(Expr { kind: ExprKind::Any { .. }, .. }), _)
310 | (Some(Expr { kind: ExprKind::StructRef { .. }, .. }), _)
311 | (Some(Expr { kind: ExprKind::TupleRef { .. }, .. }), _)
312 | (Some(Expr { kind: ExprKind::Tuple { .. }, .. }), _)
313 | (Some(Expr { kind: ExprKind::Variant { .. }, .. }), _)
314 | (Some(Expr { kind: ExprKind::Struct { .. }, .. }), _)
315 | (Some(Expr { kind: ExprKind::Qop(_), .. }), _)
316 | (Some(Expr { kind: ExprKind::Do { .. }, .. }), _)
317 | (Some(Expr { kind: ExprKind::Module { .. }, .. }), _)
318 | (Some(Expr { kind: ExprKind::Use { .. }, .. }), _)
319 | (Some(Expr { kind: ExprKind::Connect { .. }, .. }), _)
320 | (Some(Expr { kind: ExprKind::Ref { .. }, .. }), _)
321 | (Some(Expr { kind: ExprKind::Eq { .. }, .. }), _)
322 | (Some(Expr { kind: ExprKind::Ne { .. }, .. }), _)
323 | (Some(Expr { kind: ExprKind::Lt { .. }, .. }), _)
324 | (Some(Expr { kind: ExprKind::Gt { .. }, .. }), _)
325 | (Some(Expr { kind: ExprKind::Gte { .. }, .. }), _)
326 | (Some(Expr { kind: ExprKind::Lte { .. }, .. }), _)
327 | (Some(Expr { kind: ExprKind::And { .. }, .. }), _)
328 | (Some(Expr { kind: ExprKind::Or { .. }, .. }), _)
329 | (Some(Expr { kind: ExprKind::Not { .. }, .. }), _)
330 | (Some(Expr { kind: ExprKind::Add { .. }, .. }), _)
331 | (Some(Expr { kind: ExprKind::Sub { .. }, .. }), _)
332 | (Some(Expr { kind: ExprKind::Mul { .. }, .. }), _)
333 | (Some(Expr { kind: ExprKind::Div { .. }, .. }), _)
334 | (Some(Expr { kind: ExprKind::Mod { .. }, .. }), _)
335 | (Some(Expr { kind: ExprKind::Select { .. }, .. }), _)
336 | (Some(Expr { kind: ExprKind::TypeCast { .. }, .. }), _)
337 | (Some(Expr { kind: ExprKind::TypeDef { .. }, .. }), _)
338 | (Some(Expr { kind: ExprKind::ArrayRef { .. }, .. }), _)
339 | (Some(Expr { kind: ExprKind::ArraySlice { .. }, .. }), _)
340 | (Some(Expr { kind: ExprKind::Apply { .. }, .. }), _)
341 | (Some(Expr { kind: ExprKind::ByRef(_), .. }), _)
342 | (Some(Expr { kind: ExprKind::Deref(_), .. }), _)
343 | (Some(Expr { kind: ExprKind::Sample { .. }, .. }), _)
344 | (Some(Expr { kind: ExprKind::Lambda { .. }, .. }), _) => {
345 unreachable!()
346 }
347 }
348 })
349 .unwrap_or_else(|| ExprKind::Constant(Value::from("")).to_expr(pos))
350 })
351 }
352}
353
354parser! {
355 fn module[I]()(I) -> Expr
356 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
357 {
358 (
359 position(),
360 optional(string("pub").skip(space())).map(|o| o.is_some()),
361 spstring("mod").with(space()).with(spfname()),
362 optional(attempt(between(sptoken('{'), sptoken('}'), sep_by(expr(), attempt(sptoken(';'))))))
363 .map(|m: Option<Vec<Expr>>| match m {
364 Some(m) => ModuleKind::Inline(Arc::from(m)),
365 None => ModuleKind::Unresolved
366 }),
367 )
368 .map(|(pos, export, name, value)| {
369 ExprKind::Module { name, export, value }.to_expr(pos)
370 })
371 }
372}
373
374fn use_module<I>() -> impl Parser<I, Output = Expr>
375where
376 I: RangeStream<Token = char, Position = SourcePosition>,
377 I::Error: ParseError<I::Token, I::Range, I::Position>,
378 I::Range: Range,
379{
380 (position(), string("use").with(space()).with(spmodpath()))
381 .map(|(pos, name)| ExprKind::Use { name }.to_expr(pos))
382}
383
384parser! {
385 fn do_block[I]()(I) -> Expr
386 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
387 {
388 (
389 position(),
390 between(token('{'), sptoken('}'), sep_by1(expr(), attempt(sptoken(';')))),
391 )
392 .then(|(pos, args): (_, Vec<Expr>)| {
393 if args.len() < 2 {
394 unexpected_any("do must contain at least 2 expressions").left()
395 } else {
396 value(ExprKind::Do { exprs: Arc::from(args) }.to_expr(pos)).right()
397 }
398 })
399 }
400}
401
402parser! {
403 fn array[I]()(I) -> Expr
404 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
405 {
406 (position(), between(token('['), sptoken(']'), sep_by(expr(), csep()))).map(
407 |(pos, args): (_, SmallVec<[Expr; 4]>)| {
408 ExprKind::Array { args: Arc::from_iter(args.into_iter()) }.to_expr(pos)
409 },
410 )
411 }
412}
413
414parser! {
415 fn apply_pexp[I]()(I) -> Expr
416 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
417 {
418 choice((
419 attempt(spaces().with(qop(reference()))),
420 between(sptoken('('), sptoken(')'), expr()),
421 ))
422 }
423}
424
425parser! {
426 fn ref_pexp[I]()(I) -> Expr
427 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
428 {
429 choice((
430 attempt(spaces().with(qop(reference()))),
431 between(sptoken('('), sptoken(')'), expr()),
432 ))
433 }
434}
435
436parser! {
437 fn structref[I]()(I) -> Expr
438 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
439 {
440 (position(), ref_pexp().skip(sptoken('.')), spfname()).map(|(pos, source, field)| {
441 ExprKind::StructRef { source: Arc::new(source), field }.to_expr(pos)
442 })
443 }
444}
445
446parser! {
447 fn tupleref[I]()(I) -> Expr
448 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
449 {
450 (position(), ref_pexp().skip(sptoken('.')), int::<_, usize>()).map(
451 |(pos, source, field)| {
452 ExprKind::TupleRef { source: Arc::new(source), field }.to_expr(pos)
453 },
454 )
455 }
456}
457
458parser! {
459 fn arrayref[I]()(I) -> Expr
460 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
461 {
462 (
463 position(),
464 ref_pexp(),
465 between(
466 token('['),
467 sptoken(']'),
468 choice((
469 attempt(
470 (
471 position(),
472 spaces().with(optional(many1(digit()))).skip(spstring("..")),
473 spaces().with(optional(many1(digit()))),
474 )
475 .skip(look_ahead(sptoken(']'))),
476 )
477 .map(
478 |(pos, start, end): (
479 _,
480 Option<CompactString>,
481 Option<CompactString>,
482 )| {
483 let start = start.map(|i| Value::U64(i.parse().unwrap()));
484 let start = start.map(|e| ExprKind::Constant(e).to_expr(pos));
485 let end = end.map(|i| Value::U64(i.parse().unwrap()));
486 let end = end.map(|e| ExprKind::Constant(e).to_expr(pos));
487 Either::Left((start, end))
488 },
489 ),
490 attempt((
491 optional(attempt(expr())).skip(spstring("..")),
492 optional(attempt(expr())),
493 ))
494 .map(|(start, end)| Either::Left((start, end))),
495 attempt(expr()).map(|e| Either::Right(e)),
496 )),
497 ),
498 )
499 .map(|(pos, a, args)| match args {
500 Either::Left((start, end)) => ExprKind::ArraySlice {
501 source: Arc::new(a),
502 start: start.map(Arc::new),
503 end: end.map(Arc::new),
504 }
505 .to_expr(pos),
506 Either::Right(i) => {
507 ExprKind::ArrayRef { source: Arc::new(a), i: Arc::new(i) }.to_expr(pos)
508 }
509 })
510 }
511}
512
513parser! {
514 fn apply[I]()(I) -> Expr
515 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
516 {
517 (
518 position(),
519 apply_pexp(),
520 between(
521 sptoken('('),
522 sptoken(')'),
523 sep_by(
524 choice((
525 attempt((sptoken('#').with(fname()).skip(token(':')), expr()))
526 .map(|(n, e)| (Some(n), e)),
527 attempt((
528 position(),
529 sptoken('#').with(fname()),
530 ))
531 .map(|(pos, n)| {
532 let e = ExprKind::Ref { name: [n.clone()].into() }.to_expr(pos);
533 (Some(n), e)
534 }),
535 expr().map(|e| (None, e)),
536 )),
537 csep(),
538 ),
539 ),
540 )
541 .then(|(pos, function, args): (_, Expr, Vec<(Option<ArcStr>, Expr)>)| {
542 let mut anon = false;
543 for (a, _) in &args {
544 if a.is_some() && anon {
545 return unexpected_any(
546 "labeled arguments must come before anonymous arguments",
547 )
548 .right();
549 }
550 anon |= a.is_none();
551 }
552 value((pos, function, args)).left()
553 })
554 .map(|(pos, function, args): (_, Expr, Vec<(Option<ArcStr>, Expr)>)| {
555 ExprKind::Apply { function: Arc::new(function), args: Arc::from(args) }
556 .to_expr(pos)
557 })
558 }
559}
560
561parser! {
562 fn any[I]()(I) -> Expr
563 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
564 {
565 (
566 position(),
567 string("any").with(between(sptoken('('), sptoken(')'), sep_by(expr(), csep()))),
568 )
569 .map(|(pos, args): (_, Vec<Expr>)| {
570 ExprKind::Any { args: Arc::from(args) }.to_expr(pos)
571 })
572 }
573}
574
575fn typeprim<I>() -> impl Parser<I, Output = Typ>
576where
577 I: RangeStream<Token = char>,
578 I::Error: ParseError<I::Token, I::Range, I::Position>,
579 I::Range: Range,
580{
581 choice((
582 attempt(spstring("u32").map(|_| Typ::U32)),
583 attempt(spstring("v32").map(|_| Typ::V32)),
584 attempt(spstring("i32").map(|_| Typ::I32)),
585 attempt(spstring("z32").map(|_| Typ::Z32)),
586 attempt(spstring("u64").map(|_| Typ::U64)),
587 attempt(spstring("v64").map(|_| Typ::V64)),
588 attempt(spstring("i64").map(|_| Typ::I64)),
589 attempt(spstring("z64").map(|_| Typ::Z64)),
590 attempt(spstring("f32").map(|_| Typ::F32)),
591 attempt(spstring("f64").map(|_| Typ::F64)),
592 attempt(spstring("decimal").map(|_| Typ::Decimal)),
593 attempt(spstring("datetime").map(|_| Typ::DateTime)),
594 attempt(spstring("duration").map(|_| Typ::Duration)),
595 attempt(spstring("bool").map(|_| Typ::Bool)),
596 attempt(spstring("string").map(|_| Typ::String)),
597 attempt(spstring("bytes").map(|_| Typ::Bytes)),
598 attempt(spstring("error").map(|_| Typ::Error)),
599 attempt(spstring("array").map(|_| Typ::Array)),
600 attempt(spstring("null").map(|_| Typ::Null)),
601 ))
602 .skip(not_followed_by(choice((alpha_num(), token('_')))))
603}
604
605parser! {
606 fn fntype[I]()(I) -> FnType
607 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
608 {
609 spstring("fn")
610 .with((
611 optional(attempt(between(
612 token('<'),
613 sptoken('>'),
614 sep_by1((tvar().skip(sptoken(':')), typexp()), csep()),
615 )))
616 .map(|cs: Option<SmallVec<[(TVar, Type); 4]>>| match cs {
617 Some(cs) => Arc::new(RwLock::new(cs.into_iter().collect())),
618 None => Arc::new(RwLock::new(vec![])),
619 }),
620 between(
621 token('('),
622 sptoken(')'),
623 sep_by(
624 choice((
625 attempt(
626 (
627 spaces()
628 .with(optional(token('?')).map(|o| o.is_some()))
629 .skip(token('#')),
630 fname().skip(token(':')),
631 typexp(),
632 )
633 .map(
634 |(optional, name, typ)| {
635 Either::Left(FnArgType {
636 label: Some((name.into(), optional)),
637 typ,
638 })
639 },
640 ),
641 ),
642 attempt(
643 typexp()
644 .map(|typ| Either::Left(FnArgType { label: None, typ })),
645 ),
646 attempt(
647 spstring("@args:").with(typexp()).map(|e| Either::Right(e)),
648 ),
649 )),
650 csep(),
651 ),
652 ),
653 spstring("->").with(typexp()),
654 ))
655 .then(
656 |(constraints, mut args, rtype): (
657 Arc<RwLock<Vec<(TVar, Type)>>>,
658 Vec<Either<FnArgType, Type>>,
659 Type,
660 )| {
661 let vargs = match args.pop() {
662 None => None,
663 Some(Either::Right(t)) => Some(t),
664 Some(Either::Left(t)) => {
665 args.push(Either::Left(t));
666 None
667 }
668 };
669 if !args.iter().all(|a| a.is_left()) {
670 return unexpected_any(
671 "vargs must appear once at the end of the args",
672 )
673 .left();
674 }
675 let args = Arc::from_iter(args.into_iter().map(|t| match t {
676 Either::Left(t) => t,
677 Either::Right(_) => unreachable!(),
678 }));
679 let mut anon = false;
680 for a in args.iter() {
681 if anon && a.label.is_some() {
682 return unexpected_any(
683 "anonymous args must appear after labeled args",
684 )
685 .left();
686 }
687 anon |= a.label.is_none();
688 }
689 value(FnType { args, vargs, rtype, constraints }).right()
690 },
691 )
692 }
693}
694
695fn tvar<I>() -> impl Parser<I, Output = TVar>
696where
697 I: RangeStream<Token = char>,
698 I::Error: ParseError<I::Token, I::Range, I::Position>,
699 I::Range: Range,
700{
701 sptoken('\'').with(fname()).map(TVar::empty_named)
702}
703
704parser! {
705 fn typexp[I]()(I) -> Type
706 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
707 {
708 choice((
709 attempt(sptoken('&').with(typexp()).map(|t| Type::ByRef(Arc::new(t)))),
710 attempt(sptoken('_').map(|_| Type::Bottom)),
711 attempt(
712 between(sptoken('['), sptoken(']'), sep_by(typexp(), csep()))
713 .map(|ts: SmallVec<[Type; 16]>| Type::flatten_set(ts)),
714 ),
715 attempt(between(sptoken('('), sptoken(')'), sep_by1(typexp(), csep())).then(
716 |exps: SmallVec<[Type; 16]>| {
717 if exps.len() < 2 {
718 unexpected_any("tuples must have at least 2 elements").left()
719 } else {
720 value(Type::Tuple(Arc::from_iter(exps))).right()
721 }
722 },
723 )),
724 attempt(
725 between(
726 sptoken('{'),
727 sptoken('}'),
728 sep_by1((spfname().skip(sptoken(':')), typexp()), csep()),
729 )
730 .then(|mut exps: SmallVec<[(ArcStr, Type); 16]>| {
731 let s = exps.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
732 if s.len() < exps.len() {
733 return unexpected_any("struct field names must be unique").left();
734 }
735 exps.sort_by_key(|(n, _)| n.clone());
736 value(Type::Struct(Arc::from_iter(exps))).right()
737 }),
738 ),
739 attempt(
740 (
741 sptoken('`').with(typname()),
742 optional(attempt(between(
743 token('('),
744 sptoken(')'),
745 sep_by1(typexp(), csep()),
746 ))),
747 )
748 .map(|(tag, typs): (ArcStr, Option<SmallVec<[Type; 5]>>)| {
749 let t = match typs {
750 None => smallvec![],
751 Some(v) => v,
752 };
753 Type::Variant(tag.clone(), Arc::from_iter(t))
754 }),
755 ),
756 attempt(fntype().map(|f| Type::Fn(Arc::new(f)))),
757 attempt(spstring("Array").with(between(sptoken('<'), sptoken('>'), typexp())))
758 .map(|t| Type::Array(Arc::new(t))),
759 attempt((
760 sptypath(),
761 optional(attempt(between(
762 sptoken('<'),
763 sptoken('>'),
764 sep_by1(typexp(), csep()),
765 ))),
766 ))
767 .map(|(n, params): (ModPath, Option<SmallVec<[Type; 8]>>)| {
768 let params = params
769 .map(|a| Arc::from_iter(a.into_iter()))
770 .unwrap_or_else(|| Arc::from_iter([]));
771 Type::Ref { scope: ModPath::root(), name: n, params }
772 }),
773 attempt(spstring("Any")).map(|_| Type::Any),
774 attempt(typeprim()).map(|typ| Type::Primitive(typ.into())),
775 attempt(tvar()).map(|tv| Type::TVar(tv)),
776 ))
777 }
778}
779
780parser! {
781 fn lambda_args[I]()(I) -> (Vec<Arg>, Option<Option<Type>>)
782 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
783 {
784 sep_by(
785 (
786 choice((
787 attempt(spaces().with(structure_pattern())).map(|p| (false, p)),
788 attempt(spaces().with(token('#').with(fname())))
789 .map(|b| (true, StructurePattern::Bind(b))),
790 attempt(spstring("@args"))
791 .map(|s| (false, StructurePattern::Bind(ArcStr::from(s)))),
792 )),
793 optional(attempt(sptoken(':').with(typexp()))),
794 optional(attempt(sptoken('=').with(expr()))),
795 ),
796 csep(),
797 )
798 .then(|v: Vec<((bool, StructurePattern), Option<Type>, Option<Expr>)>| {
799 let args = v
800 .into_iter()
801 .map(|((labeled, pattern), constraint, default)| {
802 if !labeled && default.is_some() {
803 bail!("labeled")
804 } else {
805 Ok(Arg { labeled: labeled.then_some(default), pattern, constraint })
806 }
807 })
808 .collect::<Result<Vec<_>>>();
809 match args {
810 Ok(a) => value(a).right(),
811 Err(_) => {
812 unexpected_any("only labeled arguments may have a default value").left()
813 }
814 }
815 })
816 .then(|mut v: Vec<Arg>| {
818 match v.iter().enumerate().find(|(_, a)| match &a.pattern {
819 StructurePattern::Bind(n) if n == "@args" => true,
820 _ => false,
821 }) {
822 None => value((v, None)).left(),
823 Some((i, _)) => {
824 if i == v.len() - 1 {
825 let a = v.pop().unwrap();
826 value((v, Some(a.constraint))).left()
827 } else {
828 unexpected_any("@args must be the last argument").right()
829 }
830 }
831 }
832 })
833 .then(|(v, vargs): (Vec<Arg>, Option<Option<Type>>)| {
835 let mut anon = false;
836 for a in &v {
837 if a.labeled.is_some() && anon {
838 return unexpected_any("labeled args must come before anon args").right();
839 }
840 anon |= a.labeled.is_none();
841 }
842 value((v, vargs)).left()
843 })
844 }
845}
846
847parser! {
848 fn lambda[I]()(I) -> Expr
849 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
850 {
851 (
852 position(),
853 attempt(sep_by((tvar().skip(sptoken(':')), typexp()), csep()))
854 .map(|tvs: SmallVec<[(TVar, Type); 4]>| Arc::from_iter(tvs)),
855 between(sptoken('|'), sptoken('|'), lambda_args()),
856 optional(attempt(spstring("->").with(typexp()).skip(space()))),
857 choice((
858 attempt(sptoken('\'').with(fname()).skip(not_followed_by(sptoken(':'))))
859 .map(Either::Right),
860 expr().map(|e| Either::Left(e)),
861 )),
862 )
863 .map(|(pos, constraints, (args, vargs), rtype, body)| {
864 let args = Arc::from_iter(args);
865 ExprKind::Lambda(Arc::new(Lambda { args, vargs, rtype, constraints, body }))
866 .to_expr(pos)
867 })
868 }
869}
870
871parser! {
872 fn letbind[I]()(I) -> Expr
873 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
874 {
875 (
876 position(),
877 doc_comment(),
878 optional(string("pub").skip(space())).map(|o| o.is_some()),
879 spstring("let")
880 .with(space())
881 .with((structure_pattern(), optional(attempt(sptoken(':').with(typexp())))))
882 .skip(spstring("=")),
883 expr(),
884 )
885 .map(|(pos, doc, export, (pattern, typ), value)| {
886 ExprKind::Bind(Arc::new(Bind { doc, export, pattern, typ, value }))
887 .to_expr(pos)
888 })
889 }
890}
891
892parser! {
893 fn connect[I]()(I) -> Expr
894 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
895 {
896 (position(), optional(token('*')), spmodpath().skip(spstring("<-")), expr()).map(
897 |(pos, deref, name, e)| {
898 ExprKind::Connect { name, value: Arc::new(e), deref: deref.is_some() }
899 .to_expr(pos)
900 },
901 )
902 }
903}
904
905fn literal<I>() -> impl Parser<I, Output = Expr>
906where
907 I: RangeStream<Token = char, Position = SourcePosition>,
908 I::Error: ParseError<I::Token, I::Range, I::Position>,
909 I::Range: Range,
910{
911 (position(), parse_value(&GRAPHIX_ESC).skip(not_followed_by(token('_'))))
912 .map(|(pos, v)| ExprKind::Constant(v).to_expr(pos))
913}
914
915fn reference<I>() -> impl Parser<I, Output = Expr>
916where
917 I: RangeStream<Token = char, Position = SourcePosition>,
918 I::Error: ParseError<I::Token, I::Range, I::Position>,
919 I::Range: Range,
920{
921 (position(), modpath()).map(|(pos, name)| ExprKind::Ref { name }.to_expr(pos))
922}
923
924parser! {
925 fn deref_arith[I]()(I) -> Expr
926 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
927 {
928 (position(), token('*').with(arith_term()))
929 .map(|(pos, expr)| ExprKind::Deref(Arc::new(expr)).to_expr(pos))
930 }
931}
932
933parser! {
934 fn qop[I, P](p: P)(I) -> Expr
935 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range, P: Parser<I, Output = Expr>]
936 {
937 (position(), p, optional(attempt(sptoken('?')))).map(|(pos, e, qop)| match qop {
938 None => e,
939 Some(_) => ExprKind::Qop(Arc::new(e)).to_expr(pos),
940 })
941 }
942}
943
944parser! {
945 fn arith_term[I]()(I) -> Expr
946 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
947 {
948 choice((
949 attempt(spaces().with(qop(deref_arith()))),
950 attempt(spaces().with(raw_string())),
951 attempt(spaces().with(array())),
952 attempt(spaces().with(byref_arith())),
953 attempt(spaces().with(tuple())),
954 attempt(spaces().with(structure())),
955 attempt(spaces().with(variant())),
956 attempt(spaces().with(qop(apply()))),
957 attempt(spaces().with(structwith())),
958 attempt(spaces().with(qop(arrayref()))),
959 attempt(spaces().with(qop(tupleref()))),
960 attempt(spaces().with(qop(structref()))),
961 attempt(spaces().with(qop(do_block()))),
962 attempt(spaces().with(qop(select()))),
963 attempt(spaces().with(qop(cast()))),
964 attempt(spaces().with(qop(any()))),
965 attempt(spaces().with(interpolated())),
966 attempt(spaces().with(literal())),
967 attempt(spaces().with(qop(reference()))),
968 attempt(
969 (position(), sptoken('!').with(arith()))
970 .map(|(pos, expr)| ExprKind::Not { expr: Arc::new(expr) }.to_expr(pos)),
971 ),
972 attempt(between(sptoken('('), sptoken(')'), arith())),
973 ))
974 .skip(spaces())
975 }
976}
977
978parser! {
979 fn arith[I]()(I) -> Expr
980 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
981 {
982 choice((
983 attempt(chainl1(
984 arith_term(),
985 choice((
986 attempt(spstring("+")),
987 attempt(spstring("-")),
988 attempt(spstring("*")),
989 attempt(spstring("/")),
990 attempt(spstring("%")),
991 attempt(spstring("==")),
992 attempt(spstring("!=")),
993 attempt(spstring(">=")),
994 attempt(spstring("<=")),
995 attempt(spstring(">")),
996 attempt(spstring("<")),
997 attempt(spstring("&&")),
998 attempt(spstring("||")),
999 attempt(spstring("~")),
1000 ))
1001 .map(|op: &str| match op {
1002 "+" => |lhs: Expr, rhs: Expr| {
1003 let pos = lhs.pos;
1004 ExprKind::Add { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1005 },
1006 "-" => |lhs: Expr, rhs: Expr| {
1007 let pos = lhs.pos;
1008 ExprKind::Sub { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1009 },
1010 "*" => |lhs: Expr, rhs: Expr| {
1011 let pos = lhs.pos;
1012 ExprKind::Mul { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1013 },
1014 "/" => |lhs: Expr, rhs: Expr| {
1015 let pos = lhs.pos;
1016 ExprKind::Div { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1017 },
1018 "%" => |lhs: Expr, rhs: Expr| {
1019 let pos = lhs.pos;
1020 ExprKind::Mod { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1021 },
1022 "==" => |lhs: Expr, rhs: Expr| {
1023 let pos = lhs.pos;
1024 ExprKind::Eq { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1025 },
1026 "!=" => |lhs: Expr, rhs: Expr| {
1027 let pos = lhs.pos;
1028 ExprKind::Ne { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1029 },
1030 ">" => |lhs: Expr, rhs: Expr| {
1031 let pos = lhs.pos;
1032 ExprKind::Gt { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1033 },
1034 "<" => |lhs: Expr, rhs: Expr| {
1035 let pos = lhs.pos;
1036 ExprKind::Lt { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1037 },
1038 ">=" => |lhs: Expr, rhs: Expr| {
1039 let pos = lhs.pos;
1040 ExprKind::Gte { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1041 },
1042 "<=" => |lhs: Expr, rhs: Expr| {
1043 let pos = lhs.pos;
1044 ExprKind::Lte { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1045 },
1046 "&&" => |lhs: Expr, rhs: Expr| {
1047 let pos = lhs.pos;
1048 ExprKind::And { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1049 },
1050 "||" => |lhs: Expr, rhs: Expr| {
1051 let pos = lhs.pos;
1052 ExprKind::Or { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }.to_expr(pos)
1053 },
1054 "~" => |lhs: Expr, rhs: Expr| {
1055 let pos = lhs.pos;
1056 ExprKind::Sample { lhs: Arc::new(lhs), rhs: Arc::new(rhs) }
1057 .to_expr(pos)
1058 },
1059 _ => unreachable!(),
1060 }),
1061 )),
1062 attempt((position(), sptoken('!').with(arith_term())))
1063 .map(|(pos, expr)| ExprKind::Not { expr: Arc::new(expr) }.to_expr(pos)),
1064 attempt(between(sptoken('('), sptoken(')'), arith())),
1065 ))
1066 }
1067}
1068
1069parser! {
1070 fn slice_pattern[I]()(I) -> StructurePattern
1071 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1072 {
1073 macro_rules! all_left {
1074 ($pats:expr) => {{
1075 let mut err = false;
1076 let pats: Arc<[StructurePattern]> =
1077 Arc::from_iter($pats.into_iter().map(|s| match s {
1078 Either::Left(s) => s,
1079 Either::Right(_) => {
1080 err = true;
1081 StructurePattern::Ignore
1082 }
1083 }));
1084 if err {
1085 return unexpected_any("invalid pattern").left();
1086 }
1087 pats
1088 }};
1089 }
1090 (
1091 optional(attempt(spfname().skip(sptoken('@')))),
1092 between(
1093 sptoken('['),
1094 sptoken(']'),
1095 sep_by(
1096 choice((
1097 attempt(spstring("..")).map(|_| Either::Right(None)),
1098 attempt(spfname().skip(spstring("..")))
1099 .map(|n| Either::Right(Some(n))),
1100 structure_pattern().map(|p| Either::Left(p)),
1101 )),
1102 csep(),
1103 ),
1104 ),
1105 )
1106 .then(
1107 |(all, mut pats): (
1108 Option<ArcStr>,
1109 SmallVec<[Either<StructurePattern, Option<ArcStr>>; 8]>,
1110 )| {
1111 if pats.len() == 0 {
1112 value(StructurePattern::Slice { all, binds: Arc::from_iter([]) })
1113 .right()
1114 } else if pats.len() == 1 {
1115 match pats.pop().unwrap() {
1116 Either::Left(s) => value(StructurePattern::Slice {
1117 all,
1118 binds: Arc::from_iter([s]),
1119 })
1120 .right(),
1121 Either::Right(_) => {
1122 unexpected_any("invalid singular range match").left()
1123 }
1124 }
1125 } else {
1126 match (&pats[0], &pats[pats.len() - 1]) {
1127 (Either::Right(_), Either::Right(_)) => {
1128 unexpected_any("invalid pattern").left()
1129 }
1130 (Either::Right(_), Either::Left(_)) => {
1131 let head = pats.remove(0).right().unwrap();
1132 let suffix = all_left!(pats);
1133 value(StructurePattern::SliceSuffix { all, head, suffix })
1134 .right()
1135 }
1136 (Either::Left(_), Either::Right(_)) => {
1137 let tail = pats.pop().unwrap().right().unwrap();
1138 let prefix = all_left!(pats);
1139 value(StructurePattern::SlicePrefix { all, tail, prefix })
1140 .right()
1141 }
1142 (Either::Left(_), Either::Left(_)) => {
1143 value(StructurePattern::Slice { all, binds: all_left!(pats) })
1144 .right()
1145 }
1146 }
1147 }
1148 },
1149 )
1150 }
1151}
1152
1153fn raw_string<I>() -> impl Parser<I, Output = Expr>
1154where
1155 I: RangeStream<Token = char, Position = SourcePosition>,
1156 I::Error: ParseError<I::Token, I::Range, I::Position>,
1157 I::Range: Range,
1158{
1159 const ESC: [char; 2] = ['\'', '\\'];
1160 (position(), between(string("r\'"), token('\''), escaped_string(&ESC))).map(
1161 |(pos, s): (_, String)| ExprKind::Constant(Value::String(s.into())).to_expr(pos),
1162 )
1163}
1164
1165parser! {
1166 fn tuple_pattern[I]()(I) -> StructurePattern
1167 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1168 {
1169 (
1170 optional(attempt(spfname().skip(sptoken('@')))),
1171 between(sptoken('('), sptoken(')'), sep_by1(structure_pattern(), csep())),
1172 )
1173 .then(|(all, binds): (Option<ArcStr>, SmallVec<[StructurePattern; 8]>)| {
1174 if binds.len() < 2 {
1175 unexpected_any("tuples must have at least 2 elements").left()
1176 } else {
1177 value(StructurePattern::Tuple { all, binds: Arc::from_iter(binds) })
1178 .right()
1179 }
1180 })
1181 }
1182}
1183
1184parser! {
1185 fn variant_pattern[I]()(I) -> StructurePattern
1186 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1187 {
1188 (
1189 optional(attempt(spfname().skip(sptoken('@')))),
1190 sptoken('`').with(typname()),
1191 optional(attempt(between(
1192 sptoken('('),
1193 sptoken(')'),
1194 sep_by1(structure_pattern(), csep()),
1195 ))),
1196 )
1197 .map(
1198 |(all, tag, binds): (
1199 Option<ArcStr>,
1200 ArcStr,
1201 Option<SmallVec<[StructurePattern; 8]>>,
1202 )| {
1203 let binds = match binds {
1204 None => smallvec![],
1205 Some(a) => a,
1206 };
1207 StructurePattern::Variant { all, tag, binds: Arc::from_iter(binds) }
1208 },
1209 )
1210 }
1211}
1212
1213parser! {
1214 fn struct_pattern[I]()(I) -> StructurePattern
1215 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1216 {
1217 (
1218 optional(attempt(spfname().skip(sptoken('@')))),
1219 between(
1220 sptoken('{'),
1221 sptoken('}'),
1222 sep_by1(
1223 choice((
1224 attempt((spfname().skip(sptoken(':')), structure_pattern()))
1225 .map(|(s, p)| (s, p, true)),
1226 attempt(spfname()).map(|s| {
1227 let p = StructurePattern::Bind(s.clone());
1228 (s, p, true)
1229 }),
1230 spstring("..")
1231 .map(|_| (literal!(""), StructurePattern::Ignore, false)),
1232 )),
1233 csep(),
1234 ),
1235 ),
1236 )
1237 .then(
1238 |(all, mut binds): (
1239 Option<ArcStr>,
1240 SmallVec<[(ArcStr, StructurePattern, bool); 8]>,
1241 )| {
1242 let mut exhaustive = true;
1243 binds.retain(|(_, _, ex)| {
1244 exhaustive &= *ex;
1245 *ex
1246 });
1247 binds.sort_by_key(|(s, _, _)| s.clone());
1248 let s = binds.iter().map(|(s, _, _)| s).collect::<FxHashSet<_>>();
1249 if s.len() < binds.len() {
1250 unexpected_any("struct fields must be unique").left()
1251 } else {
1252 let binds = Arc::from_iter(binds.into_iter().map(|(s, p, _)| (s, p)));
1253 value(StructurePattern::Struct { all, exhaustive, binds }).right()
1254 }
1255 },
1256 )
1257 }
1258}
1259
1260parser! {
1261 fn structure_pattern[I]()(I) -> StructurePattern
1262 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1263 {
1264 choice((
1265 attempt(slice_pattern()),
1266 attempt(tuple_pattern()),
1267 attempt(struct_pattern()),
1268 attempt(variant_pattern()),
1269 attempt(parse_value(&VAL_ESC).skip(not_followed_by(token('_'))))
1270 .map(|v| StructurePattern::Literal(v)),
1271 attempt(sptoken('_')).map(|_| StructurePattern::Ignore),
1272 spfname().map(|name| StructurePattern::Bind(name)),
1273 ))
1274 }
1275}
1276
1277parser! {
1278 fn pattern[I]()(I) -> Pattern
1279 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1280 {
1281 (
1282 optional(attempt(typexp().skip(space().with(spstring("as "))))),
1283 structure_pattern(),
1284 optional(attempt(space().with(spstring("if").with(space()).with(expr())))),
1285 )
1286 .map(
1287 |(type_predicate, structure_predicate, guard): (
1288 Option<Type>,
1289 StructurePattern,
1290 Option<Expr>,
1291 )| { Pattern { type_predicate, structure_predicate, guard } },
1292 )
1293 }
1294}
1295
1296parser! {
1297 fn select[I]()(I) -> Expr
1298 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1299 {
1300 (
1301 position(),
1302 string("select").with(space()).with((
1303 expr(),
1304 between(
1305 sptoken('{'),
1306 sptoken('}'),
1307 sep_by1((pattern(), spstring("=>").with(expr())), csep()),
1308 ),
1309 )),
1310 )
1311 .map(|(pos, (arg, arms)): (_, (Expr, Vec<(Pattern, Expr)>))| {
1312 ExprKind::Select { arg: Arc::new(arg), arms: Arc::from(arms) }.to_expr(pos)
1313 })
1314 }
1315}
1316
1317parser! {
1318 fn cast[I]()(I) -> Expr
1319 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1320 {
1321 (
1322 position(),
1323 string("cast").with(between(token('<'), sptoken('>'), typexp())),
1324 between(sptoken('('), sptoken(')'), expr()),
1325 )
1326 .map(|(pos, typ, e)| ExprKind::TypeCast { expr: Arc::new(e), typ }.to_expr(pos))
1327 }
1328}
1329
1330parser! {
1331 fn typedef[I]()(I) -> Expr
1332 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1333 {
1334 (
1335 position(),
1336 string("type").with(sptypname()),
1337 optional(attempt(between(
1338 sptoken('<'),
1339 sptoken('>'),
1340 sep_by1((tvar(), optional(attempt(sptoken(':').with(typexp())))), csep()),
1341 ))),
1342 sptoken('=').with(typexp()),
1343 )
1344 .map(|(pos, name, params, typ)| {
1345 let params = params
1346 .map(|ps: SmallVec<[(TVar, Option<Type>); 8]>| {
1347 Arc::from_iter(ps.into_iter())
1348 })
1349 .unwrap_or_else(|| Arc::<[(TVar, Option<Type>)]>::from(Vec::new()));
1350 ExprKind::TypeDef { name, params, typ }.to_expr(pos)
1351 })
1352 }
1353}
1354
1355parser! {
1356 fn tuple[I]()(I) -> Expr
1357 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1358 {
1359 (position(), between(token('('), sptoken(')'), sep_by1(expr(), csep()))).then(
1360 |(pos, exprs): (_, SmallVec<[Expr; 8]>)| {
1361 if exprs.len() < 2 {
1362 unexpected_any("tuples must have at least 2 elements").left()
1363 } else {
1364 value(ExprKind::Tuple { args: Arc::from_iter(exprs) }.to_expr(pos))
1365 .right()
1366 }
1367 },
1368 )
1369 }
1370}
1371
1372parser! {
1373 fn structure[I]()(I) -> Expr
1374 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1375 {
1376 (
1377 position(),
1378 between(
1379 token('{'),
1380 sptoken('}'),
1381 sep_by1((spfname(), optional(attempt(sptoken(':')).with(expr()))), csep()),
1382 ),
1383 )
1384 .then(|(pos, mut exprs): (_, SmallVec<[(ArcStr, Option<Expr>); 8]>)| {
1385 let s = exprs.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
1386 if s.len() < exprs.len() {
1387 return unexpected_any("struct fields must be unique").left();
1388 }
1389 exprs.sort_by_key(|(n, _)| n.clone());
1390 let args = exprs.into_iter().map(|(n, e)| match e {
1391 Some(e) => (n, e),
1392 None => {
1393 let e = ExprKind::Ref { name: [n.clone()].into() }.to_expr(pos);
1394 (n, e)
1395 }
1396 });
1397 value(ExprKind::Struct { args: Arc::from_iter(args) }.to_expr(pos)).right()
1398 })
1399 }
1400}
1401
1402parser! {
1403 fn variant[I]()(I) -> Expr
1404 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1405 {
1406 (
1407 position(),
1408 token('`').with(typname()),
1409 optional(attempt(between(token('('), sptoken(')'), sep_by1(expr(), csep())))),
1410 )
1411 .map(|(pos, tag, args): (_, ArcStr, Option<SmallVec<[Expr; 5]>>)| {
1412 let args = match args {
1413 None => smallvec![],
1414 Some(a) => a,
1415 };
1416 ExprKind::Variant { tag, args: Arc::from_iter(args.into_iter()) }.to_expr(pos)
1417 })
1418 }
1419}
1420
1421parser! {
1422 fn structwith[I]()(I) -> Expr
1423 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1424 {
1425 (
1426 position(),
1427 between(
1428 token('{'),
1429 sptoken('}'),
1430 (
1431 ref_pexp().skip(space()).skip(spstring("with")).skip(space()),
1432 sep_by1((spfname(), optional(attempt(sptoken(':').with(expr())))), csep()),
1433 ),
1434 ),
1435 )
1436 .then(
1437 |(pos, (source, mut exprs)): (_, (Expr, SmallVec<[(ArcStr, Option<Expr>); 8]>))| {
1438 let s = exprs.iter().map(|(n, _)| n).collect::<FxHashSet<_>>();
1439 if s.len() < exprs.len() {
1440 return unexpected_any("struct fields must be unique").left();
1441 }
1442 exprs.sort_by_key(|(n, _)| n.clone());
1443 let exprs = exprs.into_iter().map(|(name, e)| match e {
1444 Some(e) => (name, e),
1445 None => {
1446 let e = ExprKind::Ref { name: ModPath::from([name.clone()]) }.to_expr(pos);
1447 (name, e)
1448 }
1449 });
1450 let e = ExprKind::StructWith {
1451 source: Arc::new(source),
1452 replace: Arc::from_iter(exprs),
1453 }
1454 .to_expr(pos);
1455 value(e).right()
1456 },
1457 )
1458 }
1459}
1460
1461parser! {
1462 fn byref[I]()(I) -> Expr
1463 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1464 {
1465 (position(), token('&').with(expr()))
1466 .map(|(pos, expr)| ExprKind::ByRef(Arc::new(expr)).to_expr(pos))
1467 }
1468}
1469
1470parser! {
1471 fn byref_arith[I]()(I) -> Expr
1472 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1473 {
1474 (position(), token('&').with(arith_term()))
1475 .map(|(pos, expr)| ExprKind::ByRef(Arc::new(expr)).to_expr(pos))
1476 }
1477}
1478
1479parser! {
1480 fn deref[I]()(I) -> Expr
1481 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1482 {
1483 (position(), token('*').with(expr()))
1484 .map(|(pos, expr)| ExprKind::Deref(Arc::new(expr)).to_expr(pos))
1485 }
1486}
1487
1488parser! {
1489 fn expr[I]()(I) -> Expr
1490 where [I: RangeStream<Token = char, Position = SourcePosition>, I::Range: Range]
1491 {
1492 choice((
1493 attempt(choice((
1494 attempt(spaces().with(module())),
1495 attempt(spaces().with(use_module())),
1496 attempt(spaces().with(typedef())),
1497 attempt(spaces().with(raw_string())),
1498 attempt(spaces().with(array())),
1499 attempt(spaces().with(byref())),
1500 attempt(spaces().with(connect())),
1501 attempt(spaces().with(arith())),
1502 attempt(spaces().with(qop(deref()))),
1503 attempt(spaces().with(tuple())),
1504 attempt(spaces().with(between(token('('), sptoken(')'), expr()))),
1505 attempt(spaces().with(structure())),
1506 attempt(spaces().with(variant())),
1507 ))),
1508 attempt(spaces().with(qop(apply()))),
1509 attempt(spaces().with(structwith())),
1510 attempt(spaces().with(qop(arrayref()))),
1511 attempt(spaces().with(qop(tupleref()))),
1512 attempt(spaces().with(qop(structref()))),
1513 attempt(spaces().with(qop(do_block()))),
1514 attempt(spaces().with(lambda())),
1515 attempt(spaces().with(letbind())),
1516 attempt(spaces().with(qop(select()))),
1517 attempt(spaces().with(qop(cast()))),
1518 attempt(spaces().with(qop(any()))),
1519 attempt(spaces().with(interpolated())),
1520 attempt(spaces().with(literal())),
1521 attempt(spaces().with(qop(reference())))
1522 ))
1523 }
1524}
1525
1526pub fn parse(name: Option<ArcStr>, s: ArcStr) -> anyhow::Result<Origin> {
1531 let r: Vec<Expr> = sep_by1(expr(), attempt(sptoken(';')))
1532 .skip(spaces())
1533 .skip(eof())
1534 .easy_parse(position::Stream::new(&*s))
1535 .map(|(r, _)| r)
1536 .map_err(|e| anyhow::anyhow!(format!("{}", e)))?;
1537 Ok(Origin { name, source: s, exprs: Arc::from(r) })
1538}
1539
1540pub fn parse_one(s: &str) -> anyhow::Result<Expr> {
1542 expr()
1543 .skip(spaces())
1544 .skip(eof())
1545 .easy_parse(position::Stream::new(&*s))
1546 .map(|(r, _)| r)
1547 .map_err(|e| anyhow::anyhow!(format!("{e}")))
1548}
1549
1550pub fn parse_fn_type(s: &str) -> anyhow::Result<FnType> {
1552 fntype()
1553 .skip(spaces())
1554 .skip(eof())
1555 .easy_parse(position::Stream::new(s))
1556 .map(|(r, _)| r)
1557 .map_err(|e| anyhow::anyhow!(format!("{e}")))
1558}
1559
1560pub(super) fn parse_modpath(s: &str) -> anyhow::Result<ModPath> {
1561 modpath()
1562 .skip(spaces())
1563 .skip(eof())
1564 .easy_parse(position::Stream::new(s))
1565 .map(|(r, _)| r)
1566 .map_err(|e| anyhow::anyhow!(format!("{e}")))
1567}