1use crate::{
2 parser::{ParseError, SyntaxObject},
3 tokens::{NumberLiteral, ParenMod, RealLiteral, TokenType},
4};
5
6use core::{convert::TryFrom, fmt::Write};
7use thin_vec::ThinVec;
8
9use crate::tokens::IntLiteral;
10use core::fmt;
11use core::ops::Deref;
12use pretty::RcDoc;
13use serde::{Deserialize, Serialize};
14
15use thin_vec::thin_vec;
16
17use super::{interner::InternedString, parser::SyntaxObjectId, span::Span};
18
19macro_rules! define_symbols {
21 ($($name:tt => $str:expr,) * ) => {
22 $(
23 pub static $name: once_cell::sync::Lazy<InternedString> = once_cell::sync::Lazy::new(|| $str.into());
24 )*
25 };
26}
27
28define_symbols! {
29 UNREADABLE_MODULE_GET => "##__module-get",
30 STANDARD_MODULE_GET => "%module-get%",
31 PROTO_HASH_GET => "%proto-hash-get%",
32 PROVIDE => "provide",
33 DATUM_SYNTAX => "datum->syntax",
34 SYNTAX_SPAN => "#%syntax-span",
35 IF => "if",
36 DEFINE => "define",
37 LET => "let",
38 QUOTE =>"quote",
39 RETURN => "return!",
40 REQUIRE => "require",
41 SET => "set!",
42 PLAIN_LET => "%plain-let",
43 LAMBDA => "lambda",
44 LAMBDA_SYMBOL => "λ",
45 LAMBDA_FN => "fn",
46 BEGIN => "begin",
47 DOC_MACRO => "@doc",
48 REQUIRE_BUILTIN => "require-builtin",
49 REQUIRE_DYLIB => "#%require-dylib",
50 STRUCT_KEYWORD => "struct",
51 UNQUOTE => "unquote",
52 UNQUOTE_COMMA => "#%unquote-comma",
53 RAW_UNQUOTE => "#%unquote",
54 UNQUOTE_SPLICING => "unquote-splicing",
55 RAW_UNQUOTE_SPLICING => "#%unquote-splicing",
56 QUASIQUOTE => "quasiquote",
57 RAW_QUOTE => "#%quote",
58 QUASISYNTAX => "quasisyntax",
59 UNSYNTAX => "unsyntax",
60 RAW_UNSYNTAX => "#%unsyntax",
61 UNSYNTAX_SPLICING => "unsyntax-splicing",
62 RAW_UNSYNTAX_SPLICING => "#%unsyntax-splicing",
63 SYNTAX_QUOTE => "syntax",
64 DEFINE_SYNTAX => "define-syntax",
65 SYNTAX_RULES => "syntax-rules",
66 SYNTAX_CASE => "syntax-case",
67}
68
69pub trait AstTools {
70 fn pretty_print(&self);
71 fn pretty_print_log(&self);
72}
73
74impl AstTools for Vec<ExprKind> {
75 fn pretty_print(&self) {
76 println!("{}", self.iter().map(|x| x.to_pretty(60)).join("\n\n"))
77 }
78 fn pretty_print_log(&self) {
79 log::info!("{}", self.iter().map(|x| x.to_pretty(60)).join("\n\n"))
80 }
81}
82
83impl AstTools for Vec<&ExprKind> {
84 fn pretty_print(&self) {
85 println!("{}", self.iter().map(|x| x.to_pretty(60)).join("\n\n"))
86 }
87 fn pretty_print_log(&self) {
88 log::info!("{}", self.iter().map(|x| x.to_pretty(60)).join("\n\n"))
89 }
90}
91
92impl AstTools for &mut Vec<ExprKind> {
93 fn pretty_print(&self) {
94 println!("{}", self.iter().map(|x| x.to_pretty(60)).join("\n\n"))
95 }
96 fn pretty_print_log(&self) {
97 log::info!("{}", self.iter().map(|x| x.to_pretty(60)).join("\n\n"))
98 }
99}
100
101pub trait IteratorExtensions: Iterator {
102 fn join(&mut self, sep: &str) -> String
103 where
104 Self::Item: core::fmt::Display,
105 {
106 match self.next() {
107 None => String::new(),
108 Some(first_elt) => {
109 let (lower, _) = self.size_hint();
111 let mut result = String::with_capacity(sep.len() * lower);
112 write!(&mut result, "{}", first_elt).unwrap();
113 self.for_each(|elt| {
114 result.push_str(sep);
115 write!(&mut result, "{}", elt).unwrap();
116 });
117 result
118 }
119 }
120 }
121}
122
123impl<T> IteratorExtensions for T where T: Iterator {}
124
125#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
126pub enum ExprKind {
127 Atom(Atom),
128 If(Box<If>),
129 Let(Box<Let>),
130 Define(Box<Define>),
131 LambdaFunction(Box<LambdaFunction>),
132 Begin(Box<Begin>),
133 Return(Box<Return>),
134 Quote(Box<Quote>),
135 Macro(Box<Macro>),
136 SyntaxRules(Box<SyntaxRules>),
137 List(List),
138 Set(Box<Set>),
139 Require(Box<Require>),
140 Vector(Vector),
141}
142
143impl Default for ExprKind {
144 fn default() -> Self {
145 ExprKind::List(List::new(ThinVec::new()))
146 }
147}
148
149#[test]
150fn check_size() {
151 println!("ExprKind: {}", core::mem::size_of::<ExprKind>());
152 println!("SyntaxRules: {}", core::mem::size_of::<SyntaxRules>());
153 println!("Macro: {}", core::mem::size_of::<Macro>());
154 println!("List: {}", core::mem::size_of::<List>());
155 println!("Atom: {}", core::mem::size_of::<Atom>());
156 println!("Require: {}", core::mem::size_of::<Require>());
157 println!("Vector: {}", core::mem::size_of::<Vector>());
158}
159
160#[macro_export]
161macro_rules! expr_list {
162 () => { $crate::ast::ExprKind::List($crate::ast::List::new(vec![])) };
163
164 ( $($x:expr),* ) => {{
165 $crate::ast::ExprKind::List($crate::ast::List::new(thin_vec![$(
166 $x,
167 ) *]))
168 }};
169
170 ( $($x:expr ,)* ) => {{
171 $crate::ast::ExprKind::List($crate::ast::List::new(thin_vec![$($x, )*]))
172 }};
173}
174
175impl ExprKind {
176 pub fn span(&self) -> Span {
177 match self {
178 ExprKind::Atom(expr) => expr.syn.span,
179 ExprKind::If(expr) => expr.location.span,
180 ExprKind::Let(expr) => expr.location.span,
181 ExprKind::Define(expr) => expr.location.span,
182 ExprKind::LambdaFunction(expr) => expr.location.span,
183 ExprKind::Begin(expr) => expr.location.span,
184 ExprKind::Return(expr) => expr.location.span,
185 ExprKind::Quote(expr) => expr.location.span,
186 ExprKind::Macro(expr) => expr.location.span,
187 ExprKind::SyntaxRules(expr) => expr.location.span,
188 ExprKind::List(expr) => expr.location,
189 ExprKind::Set(expr) => expr.location.span,
190 ExprKind::Require(expr) => expr.location.span,
191 ExprKind::Vector(vec) => vec.span,
192 }
193 }
194
195 pub fn to_string_literal(&self) -> Option<String> {
196 if let ExprKind::Atom(a) = self {
197 if let TokenType::StringLiteral(s) = &a.syn.ty {
198 Some(s.resolve().to_string())
199 } else {
200 None
201 }
202 } else {
203 None
204 }
205 }
206
207 pub fn into_lambda_function(self) -> Option<Box<LambdaFunction>> {
208 if let ExprKind::LambdaFunction(func) = self {
209 Some(func)
210 } else {
211 None
212 }
213 }
214
215 pub fn quoted_list() -> ExprKind {
216 ExprKind::Quote(Box::new(Quote::new(
217 Self::empty(),
218 SyntaxObject::default(TokenType::QuoteTick),
219 )))
220 }
221
222 pub fn empty() -> ExprKind {
223 ExprKind::List(List::new(ThinVec::new()))
224 }
225
226 pub fn integer_literal(value: isize, span: Span) -> ExprKind {
227 ExprKind::Atom(crate::ast::Atom::new(SyntaxObject::new(
228 IntLiteral::Small(value).into(),
229 span,
230 )))
231 }
232
233 pub fn atom<T: Into<InternedString>>(name: T) -> ExprKind {
234 ExprKind::Atom(Atom::new(SyntaxObject::default(TokenType::Identifier(
235 name.into(),
236 ))))
237 }
238
239 pub fn ident(name: &str) -> ExprKind {
240 ExprKind::Atom(Atom::new(SyntaxObject::default(TokenType::Identifier(
241 name.into(),
242 ))))
243 }
244
245 pub fn ident_with_span(name: &str, span: Span) -> ExprKind {
246 ExprKind::Atom(Atom::new(SyntaxObject::new(
247 TokenType::Identifier(name.into()),
248 span,
249 )))
250 }
251
252 pub fn string_lit(input: String) -> ExprKind {
253 ExprKind::Atom(Atom::new(SyntaxObject::default(TokenType::StringLiteral(
254 input.into(),
255 ))))
256 }
257
258 pub fn bool_lit(b: bool) -> ExprKind {
259 ExprKind::Atom(Atom::new(SyntaxObject::default(TokenType::BooleanLiteral(
260 b,
261 ))))
262 }
263
264 pub fn default_if(test: ExprKind, then: ExprKind, els: ExprKind) -> ExprKind {
265 ExprKind::If(Box::new(If::new(
266 test,
267 then,
268 els,
269 SyntaxObject::default(TokenType::If),
270 )))
271 }
272
273 pub fn into_atom_syntax_object(self) -> Option<SyntaxObject> {
274 match self {
275 Self::Atom(Atom { syn }) => Some(syn),
276 _ => None,
277 }
278 }
279
280 pub fn atom_syntax_object(&self) -> Option<&SyntaxObject> {
281 match self {
282 Self::Atom(Atom { syn }) => Some(syn),
283 _ => None,
284 }
285 }
286
287 pub fn atom_syntax_object_mut(&mut self) -> Option<&mut SyntaxObject> {
288 match self {
289 Self::Atom(Atom { syn }) => Some(syn),
290 _ => None,
291 }
292 }
293
294 pub fn define_syntax_ident(&self) -> bool {
295 matches!(
296 self,
297 Self::Atom(Atom {
298 syn: SyntaxObject {
299 ty: TokenType::DefineSyntax,
300 ..
301 },
302 })
303 )
304 }
305
306 pub fn atom_identifier_mut(&mut self) -> Option<&mut InternedString> {
307 match self {
308 Self::Atom(Atom {
309 syn:
310 SyntaxObject {
311 ty: TokenType::Identifier(s),
312 ..
313 },
314 }) => Some(s),
315 _ => None,
316 }
317 }
318
319 pub fn lambda_function(&self) -> Option<&LambdaFunction> {
320 match self {
321 Self::LambdaFunction(l) => Some(l),
322 _ => None,
323 }
324 }
325
326 pub fn atom_identifier_or_else<E, F: FnOnce() -> E>(
327 &self,
328 err: F,
329 ) -> core::result::Result<&InternedString, E> {
330 match self {
331 Self::Atom(Atom {
332 syn:
333 SyntaxObject {
334 ty: TokenType::Identifier(s),
335 ..
336 },
337 }) => Ok(s),
338 _ => Err(err()),
339 }
340 }
341
342 pub fn atom_identifier(&self) -> Option<&InternedString> {
343 match self {
344 Self::Atom(Atom {
345 syn:
346 SyntaxObject {
347 ty: TokenType::Identifier(s),
348 ..
349 },
350 }) => Some(s),
351 _ => None,
352 }
353 }
354
355 pub fn string_literal(&self) -> Option<&str> {
356 match self {
357 Self::Atom(Atom {
358 syn:
359 SyntaxObject {
360 ty: TokenType::StringLiteral(s),
361 ..
362 },
363 }) => Some(s.resolve()),
364 _ => None,
365 }
366 }
367
368 pub fn list(&self) -> Option<&List> {
369 if let ExprKind::List(l) = self {
370 Some(l)
371 } else {
372 None
373 }
374 }
375
376 pub fn list_mut(&mut self) -> Option<&mut List> {
377 if let ExprKind::List(l) = self {
378 Some(l)
379 } else {
380 None
381 }
382 }
383
384 pub fn list_or_else<E, F: FnOnce() -> E>(&self, err: F) -> core::result::Result<&List, E> {
385 match self {
386 Self::List(l) => Ok(l),
387 _ => Err(err()),
388 }
389 }
390
391 pub fn list_mut_or_else<E, F: FnOnce() -> E>(
392 &mut self,
393 err: F,
394 ) -> core::result::Result<&mut List, E> {
395 match self {
396 Self::List(l) => Ok(l),
397 _ => Err(err()),
398 }
399 }
400
401 pub fn into_list_or_else<E, F: FnOnce() -> E>(self, err: F) -> core::result::Result<List, E> {
402 match self {
403 Self::List(l) => Ok(l),
404 _ => Err(err()),
405 }
406 }
407
408 pub fn into_list(self) -> List {
409 if let ExprKind::List(l) = self {
410 l
411 } else {
412 panic!("Attempted to coerce a non list to a list");
413 }
414 }
415
416 pub fn unwrap_function(self) -> Option<Box<LambdaFunction>> {
417 if let ExprKind::LambdaFunction(l) = self {
418 Some(l)
419 } else {
420 None
421 }
422 }
423
424 pub fn get_list(&self) -> Option<&List> {
425 if let ExprKind::List(l) = self {
426 Some(l)
427 } else {
428 None
429 }
430 }
431
432 pub fn update_string_in_atom(&mut self, ident: InternedString) {
433 if let ExprKind::Atom(Atom {
434 syn:
435 SyntaxObject {
436 ty: TokenType::Identifier(ref mut s),
437 ..
438 },
439 }) = self
440 {
441 *s = ident;
442 }
443 }
444}
445
446pub trait ToDoc {
447 fn to_doc(&self) -> RcDoc<'_, ()>;
448}
449
450impl ToDoc for ExprKind {
451 fn to_doc(&self) -> RcDoc<'_, ()> {
452 match self {
453 ExprKind::Atom(a) => a.to_doc(),
454 ExprKind::If(i) => i.to_doc(),
455 ExprKind::Define(d) => d.to_doc(),
456 ExprKind::LambdaFunction(l) => l.to_doc(),
457 ExprKind::Begin(b) => b.to_doc(),
458 ExprKind::Return(r) => r.to_doc(),
459 ExprKind::Let(l) => l.to_doc(),
460 ExprKind::Quote(q) => q.to_doc(),
461 ExprKind::Macro(m) => m.to_doc(),
462 ExprKind::SyntaxRules(s) => s.to_doc(),
463 ExprKind::List(l) => l.to_doc(),
464 ExprKind::Set(s) => s.to_doc(),
465 ExprKind::Require(r) => r.to_doc(),
466 ExprKind::Vector(v) => v.to_doc(),
467 }
468 }
469}
470
471impl ExprKind {
472 pub fn to_pretty(&self, width: usize) -> String {
473 let mut w = Vec::new();
474 self.to_doc().render(width, &mut w).unwrap();
475 String::from_utf8(w).unwrap()
476 }
477}
478
479impl fmt::Display for ExprKind {
480 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
481 match self {
482 ExprKind::Atom(a) => write!(f, "{a}"),
483 ExprKind::If(i) => write!(f, "{i}"),
484 ExprKind::Define(d) => write!(f, "{d}"),
485 ExprKind::LambdaFunction(l) => write!(f, "{l}"),
486 ExprKind::Begin(b) => write!(f, "{b}"),
487 ExprKind::Return(r) => write!(f, "{r}"),
488 ExprKind::Let(l) => write!(f, "{l}"),
489 ExprKind::Quote(q) => write!(f, "{q}"),
490 ExprKind::Macro(m) => write!(f, "{m}"),
491 ExprKind::SyntaxRules(s) => write!(f, "{s}"),
492 ExprKind::List(l) => write!(f, "{l}"),
493 ExprKind::Set(s) => write!(f, "{s}"),
494 ExprKind::Require(r) => write!(f, "{r}"),
495 ExprKind::Vector(v) => write!(f, "{v}"),
496 }
497 }
498}
499
500#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
501pub struct Atom {
502 pub syn: SyntaxObject,
503}
504
505impl Atom {
506 pub fn new(syn: SyntaxObject) -> Self {
507 Atom { syn }
508 }
509
510 pub fn ident(&self) -> Option<&InternedString> {
511 if let TokenType::Identifier(ref ident) = self.syn.ty {
512 Some(ident)
513 } else {
514 None
515 }
516 }
517
518 pub fn ident_mut(&mut self) -> Option<&mut InternedString> {
519 if let TokenType::Identifier(ref mut ident) = self.syn.ty {
520 Some(ident)
521 } else {
522 None
523 }
524 }
525
526 pub fn byte(&self) -> Option<u8> {
527 let TokenType::Number(number) = &self.syn.ty else {
529 return None;
530 };
531
532 match number.resolve() {
533 NumberLiteral::Real(RealLiteral::Int(int)) => match int {
534 IntLiteral::Small(int) => u8::try_from(int).ok(),
535 IntLiteral::Big(bigint) => u8::try_from(*bigint).ok(),
536 },
537 _ => None,
538 }
539 }
540}
541
542impl fmt::Display for Atom {
543 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
544 write!(f, "{}", self.syn.ty)
545 }
546}
547
548impl ToDoc for Atom {
549 fn to_doc(&self) -> RcDoc<'_, ()> {
550 RcDoc::text(self.syn.ty.to_string())
551 }
552}
553
554impl From<Atom> for ExprKind {
555 fn from(val: Atom) -> Self {
556 ExprKind::Atom(val)
557 }
558}
559
560#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
561pub struct Let {
562 pub bindings: Vec<(ExprKind, ExprKind)>,
563 pub body_expr: ExprKind,
564 pub location: SyntaxObject,
565 pub syntax_object_id: u32,
566}
567
568impl Let {
569 pub fn new(
570 bindings: Vec<(ExprKind, ExprKind)>,
571 body_expr: ExprKind,
572 location: SyntaxObject,
573 ) -> Self {
574 Let {
575 bindings,
576 body_expr,
577 location,
578 syntax_object_id: SyntaxObjectId::fresh().0,
579 }
580 }
581
582 pub fn local_bindings(&self) -> impl Iterator<Item = &'_ ExprKind> {
583 self.bindings.iter().map(|x| &x.0)
584 }
585
586 pub fn expression_arguments(&self) -> impl Iterator<Item = &'_ ExprKind> {
587 self.bindings.iter().map(|x| &x.1)
588 }
589}
590
591impl fmt::Display for Let {
592 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
593 write!(
594 f,
595 "(%plain-let ({}) {})",
596 self.bindings
597 .iter()
598 .map(|x| format!("({} {})", x.0, x.1))
599 .join(" "),
600 self.body_expr
601 )
602 }
603}
604
605impl ToDoc for Let {
606 fn to_doc(&self) -> RcDoc<'_, ()> {
607 RcDoc::text("(%plain-let")
608 .append(RcDoc::space())
609 .append(RcDoc::text("("))
610 .append(
611 RcDoc::intersperse(
612 self.bindings.iter().map(|x| {
613 RcDoc::text("(")
614 .append(x.0.to_doc())
615 .append(RcDoc::space())
616 .append(x.1.to_doc())
617 .append(RcDoc::text(")"))
618 }),
619 RcDoc::line(),
620 )
621 .nest(2)
622 .group(),
623 )
624 .append(RcDoc::text(")"))
625 .append(RcDoc::line())
626 .append(self.body_expr.to_doc())
627 .append(RcDoc::text(")"))
628 .nest(2)
629 }
630}
631
632impl From<Let> for ExprKind {
633 fn from(val: Let) -> Self {
634 ExprKind::Let(Box::new(val))
635 }
636}
637
638#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
639pub struct Set {
640 pub variable: ExprKind,
641 pub expr: ExprKind,
642 pub location: SyntaxObject,
643}
644
645impl Set {
646 pub fn new(variable: ExprKind, expr: ExprKind, location: SyntaxObject) -> Self {
647 Set {
648 variable,
649 expr,
650 location,
651 }
652 }
653}
654
655impl fmt::Display for Set {
656 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
657 write!(f, "(set! {} {})", self.variable, self.expr)
658 }
659}
660
661impl ToDoc for Set {
662 fn to_doc(&self) -> RcDoc<'_, ()> {
663 RcDoc::text("(set!")
664 .append(RcDoc::space())
665 .append(self.variable.to_doc())
666 .append(RcDoc::line())
667 .append(self.expr.to_doc())
668 .append(RcDoc::text(")"))
669 .nest(2)
670 .group()
671 }
672}
673
674impl From<Set> for ExprKind {
675 fn from(val: Set) -> Self {
676 ExprKind::Set(Box::new(val))
677 }
678}
679
680#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
681pub struct If {
682 pub test_expr: ExprKind,
683 pub then_expr: ExprKind,
684 pub else_expr: ExprKind,
685 pub location: SyntaxObject,
686}
687
688impl ToDoc for If {
689 fn to_doc(&self) -> RcDoc<'_, ()> {
690 RcDoc::text("(if")
691 .append(RcDoc::space())
692 .append(self.test_expr.to_doc())
693 .append(RcDoc::line())
694 .append(self.then_expr.to_doc())
695 .append(RcDoc::line())
696 .append(self.else_expr.to_doc())
697 .append(RcDoc::text(")"))
698 .nest(2)
699 .group()
700 }
701}
702
703impl fmt::Display for If {
704 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
705 write!(
706 f,
707 "(if {} {} {})",
708 self.test_expr, self.then_expr, self.else_expr
709 )
710 }
711}
712
713impl If {
714 pub fn new(
715 test_expr: ExprKind,
716 then_expr: ExprKind,
717 else_expr: ExprKind,
718 location: SyntaxObject,
719 ) -> Self {
720 If {
721 test_expr,
722 then_expr,
723 else_expr,
724 location,
725 }
726 }
727}
728
729impl From<If> for ExprKind {
730 fn from(val: If) -> Self {
731 ExprKind::If(Box::new(val))
732 }
733}
734
735#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
737pub struct Define {
738 pub name: ExprKind,
740 pub body: ExprKind,
741 pub location: SyntaxObject,
742}
743
744impl fmt::Display for Define {
745 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
746 write!(f, "(define {} {})", self.name, self.body)
747 }
748}
749
750impl ToDoc for Define {
751 fn to_doc(&self) -> RcDoc<'_, ()> {
752 RcDoc::text("(define")
753 .append(RcDoc::space())
754 .append(self.name.to_doc())
755 .append(RcDoc::line())
756 .append(self.body.to_doc())
757 .append(RcDoc::text(")"))
758 .nest(2)
759 }
760}
761
762impl Define {
763 pub fn new(name: ExprKind, body: ExprKind, location: SyntaxObject) -> Self {
764 Define {
765 name,
766 body,
767 location,
768 }
769 }
770
771 pub fn is_an_alias_definition(&self) -> Option<SyntaxObjectId> {
772 if let Some(atom) = self.body.atom_syntax_object() {
773 if let TokenType::Identifier(_) = atom.ty {
774 return Some(atom.syntax_object_id);
775 }
776 }
777
778 None
779 }
780
781 pub fn name_id(&self) -> Option<SyntaxObjectId> {
782 self.name.atom_syntax_object().map(|x| x.syntax_object_id)
783 }
784}
785
786impl From<Define> for ExprKind {
787 fn from(val: Define) -> Self {
788 ExprKind::Define(Box::new(val))
789 }
790}
791
792#[derive(Debug, Serialize, Deserialize)]
793pub struct LambdaFunction {
794 pub args: ThinVec<ExprKind>,
795 pub body: ExprKind,
796 pub location: SyntaxObject,
797 pub rest: bool,
798 pub syntax_object_id: u32,
799 pub kwargs: bool,
802}
803
804impl Clone for LambdaFunction {
805 fn clone(&self) -> Self {
806 Self {
807 args: self.args.clone(),
808 body: self.body.clone(),
809 location: self.location.clone(),
810 rest: self.rest,
811 syntax_object_id: SyntaxObjectId::fresh().0,
812 kwargs: self.kwargs,
813 }
814 }
815}
816
817impl PartialEq for LambdaFunction {
818 fn eq(&self, other: &Self) -> bool {
819 self.args == other.args
820 && self.body == other.body
821 && self.location == other.location
822 && self.rest == other.rest
823 }
824}
825
826impl fmt::Display for LambdaFunction {
827 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
828 write!(
829 f,
830 "(lambda ({}) {})",
831 self.args.iter().map(|x| x.to_string()).join(" "),
832 self.body
833 )
834 }
835}
836
837impl ToDoc for LambdaFunction {
838 fn to_doc(&self) -> RcDoc<'_, ()> {
839 if self.rest && self.args.len() == 1 {
840 RcDoc::text("(λ")
841 .append(RcDoc::space())
842 .append(self.args.first().unwrap().to_doc())
843 .append(RcDoc::line())
844 .append(self.body.to_doc())
845 .append(RcDoc::text(")"))
846 .nest(2)
847 } else {
848 RcDoc::text("(λ")
849 .append(RcDoc::space())
850 .append(RcDoc::text("("))
851 .append(
852 RcDoc::intersperse(self.args.iter().map(|x| x.to_doc()), RcDoc::line())
853 .nest(2)
854 .group(),
855 )
856 .append(RcDoc::text(")"))
857 .append(RcDoc::line())
858 .append(self.body.to_doc())
859 .append(RcDoc::text(")"))
860 .nest(2)
861 }
862 }
863}
864
865impl LambdaFunction {
866 pub fn new(args: ThinVec<ExprKind>, body: ExprKind, location: SyntaxObject) -> Self {
867 LambdaFunction {
868 args,
869 body,
870 location,
871 rest: false,
872 syntax_object_id: SyntaxObjectId::fresh().0,
873 kwargs: false,
874 }
875 }
876
877 pub fn new_with_rest_arg(
878 args: ThinVec<ExprKind>,
879 body: ExprKind,
880 location: SyntaxObject,
881 ) -> Self {
882 LambdaFunction {
883 args,
884 body,
885 location,
886 rest: true,
887 syntax_object_id: SyntaxObjectId::fresh().0,
888 kwargs: false,
889 }
890 }
891
892 pub fn new_maybe_rest(
893 args: ThinVec<ExprKind>,
894 body: ExprKind,
895 location: SyntaxObject,
896 rest: bool,
897 ) -> Self {
898 LambdaFunction {
899 args,
900 body,
901 location,
902 rest,
903 syntax_object_id: SyntaxObjectId::fresh().0,
904 kwargs: false,
905 }
906 }
907
908 pub fn arguments(&self) -> Option<Vec<&InternedString>> {
909 self.args.iter().map(|x| x.atom_identifier()).collect()
910 }
911
912 pub fn arguments_mut(&mut self) -> impl Iterator<Item = &mut InternedString> {
913 self.args.iter_mut().filter_map(|x| x.atom_identifier_mut())
914 }
915
916 pub fn syntax_objects_arguments_mut(&mut self) -> impl Iterator<Item = &mut SyntaxObject> {
917 self.args
918 .iter_mut()
919 .filter_map(|x| x.atom_syntax_object_mut())
920 }
921}
922
923impl From<LambdaFunction> for ExprKind {
924 fn from(val: LambdaFunction) -> Self {
925 ExprKind::LambdaFunction(Box::new(val))
926 }
927}
928
929#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
930pub struct Begin {
931 pub exprs: Vec<ExprKind>,
932 pub location: SyntaxObject,
933}
934
935impl fmt::Display for Begin {
936 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
937 write!(f, "(begin {})", self.exprs.iter().join(" "))
938 }
939}
940
941impl ToDoc for Begin {
942 fn to_doc(&self) -> RcDoc<'_, ()> {
943 RcDoc::text("(begin")
944 .append(RcDoc::line())
945 .nest(5)
946 .append(
947 RcDoc::intersperse(self.exprs.iter().map(|x| x.to_doc()), RcDoc::line())
948 .nest(5)
949 .group(),
950 )
951 .append(RcDoc::text(")"))
952 .nest(1)
953 .group()
954 }
955}
956
957impl Begin {
958 pub fn new(exprs: Vec<ExprKind>, location: SyntaxObject) -> Self {
959 Begin { exprs, location }
960 }
961}
962
963impl From<Begin> for ExprKind {
964 fn from(val: Begin) -> Self {
965 ExprKind::Begin(Box::new(val))
966 }
967}
968
969#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
970pub struct Return {
971 pub expr: ExprKind,
972 pub location: SyntaxObject,
973}
974
975impl Return {
976 pub fn new(expr: ExprKind, location: SyntaxObject) -> Self {
977 Return { expr, location }
978 }
979}
980
981impl ToDoc for Return {
982 fn to_doc(&self) -> RcDoc<'_, ()> {
983 RcDoc::text("(return")
984 .append(RcDoc::line())
985 .append(self.expr.to_doc())
986 .append(RcDoc::text(")"))
987 .nest(2)
988 }
989}
990
991impl fmt::Display for Return {
992 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
993 write!(f, "(return! {})", self.expr)
994 }
995}
996
997impl From<Return> for ExprKind {
998 fn from(val: Return) -> Self {
999 ExprKind::Return(Box::new(val))
1000 }
1001}
1002
1003#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1004pub struct Require {
1005 pub modules: Vec<ExprKind>,
1006 pub location: SyntaxObject,
1007}
1008
1009impl Require {
1010 pub fn new(modules: Vec<ExprKind>, location: SyntaxObject) -> Self {
1011 Require { modules, location }
1012 }
1013}
1014
1015impl ToDoc for Require {
1016 fn to_doc(&self) -> RcDoc<'_, ()> {
1017 RcDoc::text("(require")
1018 .append(RcDoc::line())
1019 .append(
1020 RcDoc::intersperse(self.modules.iter().map(|x| x.to_doc()), RcDoc::line())
1021 .nest(2)
1022 .group(),
1023 )
1024 .append(RcDoc::text(")"))
1025 .nest(2)
1026 }
1027}
1028
1029impl fmt::Display for Require {
1030 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1031 write!(f, "(require {})", self.modules.iter().join(" "))
1032 }
1033}
1034
1035impl From<Require> for ExprKind {
1036 fn from(val: Require) -> Self {
1037 ExprKind::Require(Box::new(val))
1038 }
1039}
1040
1041#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
1042pub struct Vector {
1043 pub args: ThinVec<ExprKind>,
1044 pub bytes: bool,
1045 pub span: Span,
1046}
1047
1048impl Vector {
1049 fn prefix(&self) -> ParenMod {
1050 if self.bytes {
1051 ParenMod::Bytes
1052 } else {
1053 ParenMod::Vector
1054 }
1055 }
1056
1057 pub fn as_bytes(&self) -> impl Iterator<Item = u8> + '_ {
1058 self.args.iter().flat_map(move |expr| {
1059 let byte = if let ExprKind::Atom(atom) = expr {
1060 atom.byte()
1061 } else {
1062 None
1063 };
1064
1065 debug_assert!(!(self.bytes && byte.is_none()));
1066
1067 byte
1068 })
1069 }
1070}
1071
1072impl fmt::Display for Vector {
1073 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1074 write!(f, "{}(", self.prefix())?;
1075
1076 if let Some((first, rest)) = self.args.split_first() {
1077 write!(f, "{first}")?;
1078
1079 for arg in rest {
1080 write!(f, " {arg}")?;
1081 }
1082 }
1083
1084 write!(f, ")")
1085 }
1086}
1087
1088impl ToDoc for Vector {
1089 fn to_doc(&self) -> RcDoc<'_, ()> {
1090 RcDoc::text(self.prefix().as_str())
1091 .append("(")
1092 .append(
1093 RcDoc::intersperse(self.args.iter().map(ToDoc::to_doc), RcDoc::line())
1094 .nest(1)
1095 .group(),
1096 )
1097 .append(RcDoc::text(")"))
1098 .nest(2)
1099 .group()
1100 }
1101}
1102
1103impl From<Vector> for ExprKind {
1104 fn from(value: Vector) -> Self {
1105 ExprKind::Vector(value)
1106 }
1107}
1108
1109#[derive(Clone, Debug, Serialize, Deserialize)]
1110pub struct List {
1111 pub args: ThinVec<ExprKind>,
1112 pub syntax_object_id: u32,
1113 pub improper: bool,
1114 pub location: Span,
1117}
1118
1119impl PartialEq for List {
1120 fn eq(&self, other: &Self) -> bool {
1121 self.args == other.args
1122 && self.improper == other.improper
1123 && self.location == other.location
1124 }
1125}
1126
1127impl List {
1128 pub fn empty() -> Self {
1129 Self::new(ThinVec::new())
1130 }
1131
1132 pub fn new(args: ThinVec<ExprKind>) -> Self {
1133 List {
1134 args,
1135 syntax_object_id: SyntaxObjectId::fresh().0 as _,
1136 improper: false,
1137 location: Span::default(),
1138 }
1139 }
1140
1141 pub fn new_maybe_improper(args: ThinVec<ExprKind>, improper: bool) -> Self {
1142 List {
1143 args,
1144 syntax_object_id: SyntaxObjectId::fresh().0 as _,
1145 improper,
1146 location: Span::default(),
1147 }
1148 }
1149
1150 pub fn with_spans(args: ThinVec<ExprKind>, open: Span, close: Span) -> Self {
1151 List {
1152 args,
1153 improper: false,
1154 location: Span::merge(open, close),
1155 syntax_object_id: SyntaxObjectId::fresh().0 as _,
1156 }
1157 }
1158
1159 pub fn make_improper(&mut self) {
1160 let Some(last) = self.args.pop() else {
1161 debug_assert!(false);
1162
1163 self.improper = true;
1164
1165 return;
1166 };
1167
1168 let ExprKind::List(l) = last else {
1169 self.args.push(last);
1170
1171 self.improper = true;
1172
1173 return;
1174 };
1175
1176 self.args.extend(l.args);
1177 self.improper = l.improper;
1178 }
1179
1180 pub fn is_empty(&self) -> bool {
1181 self.args.is_empty()
1182 }
1183
1184 pub fn rest_mut(&mut self) -> Option<&mut [ExprKind]> {
1185 self.args.split_first_mut().map(|x| x.1)
1186 }
1187
1188 pub fn args_proper(self, ty: TokenType<&str>) -> Result<ThinVec<ExprKind>, ParseError> {
1189 if self.improper {
1190 return Err(ParseError::SyntaxError(
1191 format!("{} expression requires a proper list", ty),
1192 self.location,
1193 None,
1194 ));
1195 }
1196
1197 Ok(self.args)
1198 }
1199
1200 pub fn first_ident_mut(&mut self) -> Option<&mut InternedString> {
1201 if let Some(ExprKind::Atom(Atom {
1202 syn:
1203 SyntaxObject {
1204 ty: TokenType::Identifier(s),
1205 ..
1206 },
1207 })) = self.args.first_mut()
1208 {
1209 Some(s)
1210 } else {
1211 None
1212 }
1213 }
1214
1215 pub fn is_require(&self) -> bool {
1216 matches!(
1217 self.args.first(),
1218 Some(ExprKind::Atom(Atom {
1219 syn: SyntaxObject {
1220 ty: TokenType::Require,
1221 ..
1222 },
1223 }))
1224 )
1225 }
1226
1227 pub fn is_begin(&self) -> bool {
1228 matches!(
1229 self.args.first(),
1230 Some(ExprKind::Atom(Atom {
1231 syn: SyntaxObject {
1232 ty: TokenType::Begin,
1233 ..
1234 },
1235 }))
1236 )
1237 }
1238
1239 pub fn is_define_syntax(&self) -> bool {
1240 if let Some(ExprKind::Atom(Atom {
1241 syn:
1242 SyntaxObject {
1243 ty: TokenType::DefineSyntax,
1244 ..
1245 },
1246 })) = self.args.first()
1247 {
1248 self.args.len() == 3
1249 } else {
1250 false
1251 }
1252 }
1253
1254 pub fn is_syntax_rules(&self) -> bool {
1255 if let Some(ExprKind::Atom(Atom {
1256 syn:
1257 SyntaxObject {
1258 ty: TokenType::SyntaxRules,
1259 ..
1260 },
1261 })) = self.args.first()
1262 {
1263 self.args.len() > 2
1264 } else {
1265 false
1266 }
1267 }
1268
1269 pub fn is_quote(&self) -> bool {
1270 matches!(
1271 self.args.first(),
1272 Some(ExprKind::Atom(Atom {
1273 syn: SyntaxObject {
1274 ty: TokenType::Quote,
1275 ..
1276 },
1277 }))
1278 )
1279 }
1280
1281 pub fn first_ident(&self) -> Option<&InternedString> {
1282 if let Some(ExprKind::Atom(Atom {
1283 syn:
1284 SyntaxObject {
1285 ty: TokenType::Identifier(s),
1286 ..
1287 },
1288 })) = self.args.first()
1289 {
1290 Some(s)
1291 } else {
1292 None
1293 }
1294 }
1295
1296 pub fn second_ident(&self) -> Option<&InternedString> {
1297 if let Some(ExprKind::Atom(Atom {
1298 syn:
1299 SyntaxObject {
1300 ty: TokenType::Identifier(s),
1301 ..
1302 },
1303 })) = self.args.get(1)
1304 {
1305 Some(s)
1306 } else {
1307 None
1308 }
1309 }
1310
1311 pub fn third_ident(&self) -> Option<&InternedString> {
1312 if let Some(ExprKind::Atom(Atom {
1313 syn:
1314 SyntaxObject {
1315 ty: TokenType::Identifier(s),
1316 ..
1317 },
1318 })) = self.args.get(2)
1319 {
1320 Some(s)
1321 } else {
1322 None
1323 }
1324 }
1325
1326 pub fn is_anonymous_function_call(&self) -> bool {
1327 matches!(self.args.first(), Some(ExprKind::LambdaFunction(_)))
1328 }
1329
1330 pub fn is_a_builtin_expr(&self) -> bool {
1331 matches!(self.first_ident(), Some(func) if *func == *UNREADABLE_MODULE_GET || *func == *STANDARD_MODULE_GET)
1332 }
1333
1334 pub fn first_func_mut(&mut self) -> Option<&mut LambdaFunction> {
1335 if let Some(ExprKind::LambdaFunction(l)) = self.args.first_mut() {
1336 Some(l)
1337 } else {
1338 None
1339 }
1340 }
1341
1342 pub fn first_func(&self) -> Option<&LambdaFunction> {
1343 if let Some(ExprKind::LambdaFunction(l)) = self.args.first() {
1344 Some(l)
1345 } else {
1346 None
1347 }
1348 }
1349
1350 pub fn split_improper(&self) -> Option<(&[ExprKind], &ExprKind)> {
1351 if self.improper {
1352 self.args.split_last().map(|(last, rest)| (rest, last))
1353 } else {
1354 None
1355 }
1356 }
1357}
1358
1359impl ToDoc for List {
1360 fn to_doc(&self) -> RcDoc<'_, ()> {
1361 if let Some(func) = self.first_func().filter(|_| !self.improper) {
1362 let mut args_iter = self.args.iter();
1363 args_iter.next();
1364
1365 let bindings = func.args.iter().zip(args_iter);
1366
1367 RcDoc::text("(let")
1368 .append(RcDoc::space())
1369 .append(RcDoc::text("("))
1370 .append(
1371 RcDoc::intersperse(
1372 bindings.map(|x| {
1373 RcDoc::text("(")
1374 .append(x.0.to_doc())
1375 .append(RcDoc::space())
1376 .append(x.1.to_doc())
1377 .append(RcDoc::text(")"))
1378 }),
1379 RcDoc::line(),
1380 )
1381 .nest(2)
1382 .group(),
1383 )
1384 .append(RcDoc::text(")"))
1385 .append(RcDoc::line())
1386 .append(func.body.to_doc())
1387 .append(RcDoc::text(")"))
1388 .nest(2)
1389 } else {
1390 let args = if let Some((car, cdr)) = self.split_improper() {
1391 let iter = car
1392 .iter()
1393 .map(ToDoc::to_doc)
1394 .chain(core::iter::once(RcDoc::text(".")))
1395 .chain(core::iter::once(cdr.to_doc()));
1396
1397 RcDoc::intersperse(iter, RcDoc::line())
1398 } else {
1399 RcDoc::intersperse(self.args.iter().map(ToDoc::to_doc), RcDoc::line())
1400 };
1401
1402 RcDoc::text("(")
1403 .append(args.nest(1).group())
1404 .append(RcDoc::text(")"))
1405 .nest(2)
1406 .group()
1407 }
1408 }
1409}
1410
1411impl fmt::Display for List {
1412 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1413 let Some((car, cdr)) = self.split_improper() else {
1414 return write!(f, "({})", self.args.iter().join(" "));
1415 };
1416
1417 write!(f, "(")?;
1418
1419 for arg in car {
1420 write!(f, "{} ", arg)?;
1421 }
1422
1423 write!(f, ". {})", cdr)
1424 }
1425}
1426
1427impl From<List> for ExprKind {
1428 fn from(val: List) -> Self {
1429 ExprKind::List(val)
1430 }
1431}
1432
1433impl Deref for List {
1434 type Target = [ExprKind];
1435
1436 fn deref(&self) -> &[ExprKind] {
1437 &self.args
1438 }
1439}
1440
1441impl IntoIterator for List {
1443 type Item = ExprKind;
1444 type IntoIter = thin_vec::IntoIter<Self::Item>;
1446
1447 fn into_iter(self) -> Self::IntoIter {
1448 self.args.into_iter()
1449 }
1450}
1451
1452#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1453pub struct Quote {
1454 pub expr: ExprKind,
1455 pub location: SyntaxObject,
1456}
1457
1458impl Quote {
1459 pub fn new(expr: ExprKind, location: SyntaxObject) -> Self {
1460 Quote { expr, location }
1461 }
1462}
1463
1464impl ToDoc for Quote {
1465 fn to_doc(&self) -> RcDoc<'_, ()> {
1466 RcDoc::text("(quote")
1467 .append(RcDoc::line())
1468 .append(self.expr.to_doc())
1469 .append(RcDoc::text(")"))
1470 .nest(2)
1471 }
1472}
1473
1474impl fmt::Display for Quote {
1475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1476 write!(f, "(quote {})", self.expr)
1477 }
1478}
1479
1480impl From<Quote> for ExprKind {
1481 fn from(val: Quote) -> Self {
1482 ExprKind::Quote(Box::new(val))
1483 }
1484}
1485
1486#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1489pub struct Macro {
1490 pub name: Box<ExprKind>,
1491 pub syntax_rules: Box<SyntaxRules>,
1492 pub location: SyntaxObject,
1493}
1494
1495impl fmt::Display for Macro {
1496 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1497 write!(f, "(define-syntax {} {})", self.name, self.syntax_rules)
1498 }
1499}
1500
1501impl ToDoc for Macro {
1502 fn to_doc(&self) -> RcDoc<'_, ()> {
1503 RcDoc::text("(define-syntax")
1504 .append(RcDoc::line())
1505 .append(self.name.to_doc())
1506 .append(RcDoc::line())
1507 .append(self.syntax_rules.to_doc())
1508 .append(RcDoc::text(")"))
1509 .nest(1)
1510 .group()
1511 }
1512}
1513
1514impl Macro {
1515 pub fn new(name: ExprKind, syntax_rules: Box<SyntaxRules>, location: SyntaxObject) -> Self {
1516 Macro {
1517 name: Box::new(name),
1518 syntax_rules,
1519 location,
1520 }
1521 }
1522}
1523
1524impl From<Macro> for ExprKind {
1525 fn from(val: Macro) -> Self {
1526 ExprKind::Macro(Box::new(val))
1527 }
1528}
1529
1530#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1533pub struct SyntaxRules {
1534 pub syntax: ThinVec<ExprKind>,
1535 pub patterns: ThinVec<PatternPair>,
1536 pub location: SyntaxObject,
1537}
1538
1539impl SyntaxRules {
1540 pub fn new(
1541 syntax: ThinVec<ExprKind>,
1542 patterns: ThinVec<PatternPair>,
1543 location: SyntaxObject,
1544 ) -> Self {
1545 SyntaxRules {
1546 syntax,
1547 patterns,
1548 location,
1549 }
1550 }
1551}
1552
1553impl fmt::Display for SyntaxRules {
1554 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1555 write!(
1556 f,
1557 "(syntax-rules ({}) {})",
1558 self.syntax.iter().map(|x| x.to_string()).join(" "),
1559 self.patterns.iter().map(|x| x.to_string()).join("\n")
1560 )
1561 }
1562}
1563
1564impl ToDoc for SyntaxRules {
1565 fn to_doc(&self) -> RcDoc<'_, ()> {
1566 RcDoc::text("(syntax-rules")
1567 .append(RcDoc::line())
1568 .append(RcDoc::text("("))
1569 .append(
1570 RcDoc::intersperse(self.syntax.iter().map(|x| x.to_doc()), RcDoc::line())
1571 .nest(1)
1572 .group(),
1573 )
1574 .append(RcDoc::text(")"))
1575 .append(RcDoc::line())
1576 .append(
1577 RcDoc::intersperse(self.patterns.iter().map(|x| x.to_doc()), RcDoc::line())
1578 .nest(2)
1579 .group(),
1580 )
1581 .append(RcDoc::text(")"))
1582 .nest(2)
1583 }
1584}
1585
1586impl From<SyntaxRules> for ExprKind {
1587 fn from(val: SyntaxRules) -> Self {
1588 ExprKind::SyntaxRules(Box::new(val))
1589 }
1590}
1591
1592#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
1593pub struct PatternPair {
1594 pub pattern: ExprKind,
1595 pub body: ExprKind,
1596}
1597
1598impl PatternPair {
1599 pub fn new(pattern: ExprKind, body: ExprKind) -> Result<Self, ParseError> {
1600 if let Some(list) = pattern.list() {
1601 if list.is_empty() {
1602 return Err(ParseError::SyntaxError(
1603 "syntax-rules expects a non empty list for the pattern".to_string(),
1604 list.location,
1605 None,
1606 ));
1607 }
1608 } else {
1609 return Err(ParseError::SyntaxError(
1610 "syntax-rules expects a list for the pattern".to_string(),
1611 pattern.span(),
1612 None,
1613 ));
1614 }
1615
1616 Ok(PatternPair { pattern, body })
1617 }
1618}
1619
1620impl ToDoc for PatternPair {
1621 fn to_doc(&self) -> RcDoc<'_, ()> {
1622 RcDoc::text("[")
1623 .append(self.pattern.to_doc())
1624 .append(RcDoc::line())
1625 .append(self.body.to_doc())
1626 .append(RcDoc::text("]"))
1627 .nest(1)
1628 .group()
1629 }
1630}
1631
1632impl fmt::Display for PatternPair {
1633 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1634 write!(f, "[{}\n{}]", self.pattern, self.body)
1635 }
1636}
1637
1638#[inline]
1639pub(crate) fn parse_if<I>(
1640 mut value_iter: I,
1641 syn: SyntaxObject,
1642) -> core::result::Result<ExprKind, ParseError>
1643where
1644 I: Iterator<Item = ExprKind>,
1645{
1646 value_iter.next();
1648
1649 let ret_value = If::new(
1650 value_iter.next().ok_or_else(|| {
1651 ParseError::SyntaxError(
1652 "if expects a test condition, found none".to_string(),
1653 syn.span,
1654 None,
1655 )
1656 })?,
1657 value_iter.next().ok_or_else(|| {
1658 ParseError::SyntaxError(
1659 "if expects a then condition, found none".to_string(),
1660 syn.span,
1661 None,
1662 )
1663 })?,
1664 value_iter
1666 .next()
1667 .unwrap_or_else(|| ExprKind::ident("#%prim.void")),
1668 syn.clone(),
1676 )
1677 .into();
1678
1679 if value_iter.next().is_some() {
1680 Err(ParseError::SyntaxError(
1681 "if takes only 3 expressions".to_string(),
1682 syn.span,
1683 None,
1684 ))
1685 } else {
1686 Ok(ret_value)
1687 }
1688}
1689
1690#[inline]
1691pub(crate) fn parse_define<I>(
1692 mut value_iter: I,
1693 syn: SyntaxObject,
1694) -> core::result::Result<ExprKind, ParseError>
1695where
1696 I: Iterator<Item = ExprKind>,
1697{
1698 value_iter.next();
1699
1700 match value_iter.next().ok_or_else(|| {
1701 ParseError::SyntaxError(
1702 "define expects an identifier, found none".to_string(),
1703 syn.span,
1704 None,
1705 )
1706 })? {
1707 ExprKind::List(l) => {
1710 let mut name_ref = l.args.first().ok_or_else(|| {
1711 ParseError::SyntaxError(
1712 "define expected a function name, found none".to_string(),
1713 syn.span,
1714 None,
1715 )
1716 })?;
1717
1718 if let ExprKind::Atom(Atom {
1719 syn:
1720 SyntaxObject {
1721 ty: TokenType::Identifier(datum_syntax),
1722 ..
1723 },
1724 }) = name_ref
1725 {
1726 if *datum_syntax == *DATUM_SYNTAX {
1727 return Ok(ExprKind::Define(Box::new(Define::new(
1728 ExprKind::List(List::new(l.args)),
1729 {
1730 let v = value_iter.next().ok_or_else(|| {
1731 ParseError::SyntaxError(
1732 "define statement expected a body, found none".to_string(),
1733 syn.span,
1734 None,
1735 )
1736 })?;
1737 if value_iter.next().is_some() {
1738 return Err(ParseError::SyntaxError(
1739 "Define expected only one expression after the identifier"
1740 .to_string(),
1741 syn.span,
1742 None,
1743 ));
1744 }
1745 v
1746 },
1747 syn,
1748 ))));
1749 }
1750 }
1751
1752 let mut args_stack = Vec::new();
1753
1754 while let ExprKind::List(l) = name_ref {
1755 if l.first_ident() == Some(&DATUM_SYNTAX) {
1756 break;
1757 }
1758
1759 if let Some(name) = l.args.first() {
1760 name_ref = name;
1761 }
1762
1763 if let Some(rest) = l.args.get(1..) {
1764 let mut lst = List::new_maybe_improper(rest.into(), l.improper);
1765 lst.location = l.location;
1766 args_stack.push(lst);
1767 } else {
1768 let mut lst = List::new_maybe_improper(ThinVec::new(), l.improper);
1769 lst.location = l.location;
1770 args_stack.push(lst);
1771 }
1772 }
1773
1774 let found_inner_name = Some(name_ref.clone());
1775
1776 let mut args = l.args.into_iter();
1777
1778 let name = args.next().ok_or_else(|| {
1779 ParseError::SyntaxError(
1780 "define expected a function name, found none".to_string(),
1781 syn.span,
1782 None,
1783 )
1784 })?;
1785
1786 let args: ThinVec<_> = args.collect();
1787
1788 let body_exprs: Vec<_> = value_iter.collect();
1789
1790 if body_exprs.is_empty() {
1791 return Err(ParseError::SyntaxError(
1792 "Function body cannot be empty".to_string(),
1793 syn.span,
1794 None,
1795 ));
1796 }
1797
1798 let body = if body_exprs.len() == 1 {
1799 body_exprs[0].clone()
1800 } else {
1801 ExprKind::Begin(Box::new(Begin::new(
1802 body_exprs,
1803 SyntaxObject::default(TokenType::Begin),
1804 )))
1805 };
1806
1807 if args_stack.is_empty() {
1808 let rest = l.improper;
1809 let lambda = ExprKind::LambdaFunction(Box::new(LambdaFunction::new_maybe_rest(
1810 args,
1811 body,
1812 SyntaxObject::new(TokenType::Lambda, syn.span),
1813 rest,
1814 )));
1815
1816 Ok(ExprKind::Define(Box::new(Define::new(name, lambda, syn))))
1817 } else {
1818 args_stack.insert(0, List::new_maybe_improper(args, l.improper));
1819
1820 let first = args_stack.pop().unwrap();
1821 let mut lambda =
1822 ExprKind::LambdaFunction(Box::new(LambdaFunction::new_maybe_rest(
1823 first.args,
1824 body,
1825 SyntaxObject::new(TokenType::Lambda, syn.span),
1826 first.improper,
1827 )));
1828
1829 while let Some(next) = args_stack.pop() {
1830 lambda = ExprKind::LambdaFunction(Box::new(LambdaFunction::new_maybe_rest(
1831 next.args,
1832 lambda,
1833 SyntaxObject::new(TokenType::Lambda, next.location),
1834 next.improper,
1835 )));
1836 }
1837
1838 let res = ExprKind::Define(Box::new(Define::new(
1839 found_inner_name.unwrap().clone(),
1840 lambda,
1841 syn,
1842 )));
1843
1844 Ok(res)
1845 }
1846 }
1847 ExprKind::Atom(a) => Ok(ExprKind::Define(Box::new(Define::new(
1848 ExprKind::Atom(a),
1849 {
1850 let v = value_iter.next().ok_or_else(|| {
1851 ParseError::SyntaxError(
1852 "define statement expected a body, found none".to_string(),
1853 syn.span,
1854 None,
1855 )
1856 })?;
1857 if value_iter.next().is_some() {
1858 return Err(ParseError::SyntaxError(
1859 "Define expected only one expression after the identifier".to_string(),
1860 syn.span,
1861 None,
1862 ));
1863 }
1864 v
1865 },
1866 syn,
1867 )))),
1868
1869 _ => Err(ParseError::SyntaxError(
1870 "Define expects either an identifier or a list with the function name and arguments"
1871 .to_string(),
1872 syn.span,
1873 None,
1874 )),
1875 }
1876}
1877
1878#[inline]
1879pub(crate) fn parse_new_let<I>(
1880 mut value_iter: I,
1881 syn: SyntaxObject,
1882) -> core::result::Result<ExprKind, ParseError>
1883where
1884 I: Iterator<Item = ExprKind>,
1885{
1886 value_iter.next();
1887
1888 let let_pairs = if let ExprKind::List(l) = value_iter.next().ok_or_else(|| {
1889 ParseError::SyntaxError(
1890 "let expected a list of variable bindings pairs in the second position, found none"
1891 .to_string(),
1892 syn.span,
1893 None,
1894 )
1895 })? {
1896 l.args
1897 } else {
1898 return Err(ParseError::SyntaxError(
1899 "let expects a list of variable bindings pairs in the second position".to_string(),
1900 syn.span,
1901 None,
1902 ));
1903 };
1904
1905 let body_exprs: Vec<_> = value_iter.collect();
1906
1907 if body_exprs.is_empty() {
1908 return Err(ParseError::SyntaxError(
1909 "let expects an expression, found none".to_string(),
1910 syn.span,
1911 None,
1912 ));
1913 }
1914
1915 let body = if body_exprs.len() == 1 {
1916 body_exprs[0].clone()
1917 } else {
1918 ExprKind::Begin(Box::new(Begin::new(
1919 body_exprs,
1920 SyntaxObject::default(TokenType::Begin),
1921 )))
1922 };
1923
1924 let mut pairs = Vec::with_capacity(let_pairs.len());
1925
1926 for pair in let_pairs {
1927 if let ExprKind::List(l) = pair {
1928 let pair = l.args;
1929
1930 if pair.len() != 2 {
1931 return Err(ParseError::SyntaxError(
1932 format!("let expected a list of variable binding pairs, found a pair with length {}",
1933 pair.len()),
1934 syn.span, None
1935 ));
1936 }
1937
1938 let mut iter = pair.into_iter();
1939
1940 let identifier = iter.next().unwrap();
1941 let application_arg = iter.next().unwrap();
1942 pairs.push((identifier, application_arg))
1943 } else {
1944 return Err(ParseError::SyntaxError(
1945 "let expected a list of variable binding pairs".to_string(),
1946 syn.span,
1947 None,
1948 ));
1949 }
1950 }
1951
1952 Ok(ExprKind::Let(Let::new(pairs, body, syn).into()))
1953}
1954
1955#[inline]
1956fn parse_named_let<I>(
1957 mut value_iter: I,
1958 syn: SyntaxObject,
1959 name: ExprKind,
1960) -> core::result::Result<ExprKind, ParseError>
1961where
1962 I: Iterator<Item = ExprKind>,
1963{
1964 let pairs = if let ExprKind::List(l) = value_iter.next().ok_or_else(|| {
1965 ParseError::SyntaxError(
1966 "named let expects a list of argument id and init expr pairs, found none".to_string(),
1967 syn.span,
1968 None,
1969 )
1970 })? {
1971 l.args
1972 } else {
1973 return Err(ParseError::SyntaxError(
1974 "named let expects a list of variable bindings pairs in the second position"
1975 .to_string(),
1976 syn.span,
1977 None,
1978 ));
1979 };
1980
1981 let body_exprs: Vec<_> = value_iter.collect();
1982
1983 if body_exprs.is_empty() {
1984 return Err(ParseError::SyntaxError(
1985 "let expects an expression, found none".to_string(),
1986 syn.span,
1987 None,
1988 ));
1989 }
1990
1991 let body = if body_exprs.len() == 1 {
1992 body_exprs[0].clone()
1993 } else {
1994 ExprKind::Begin(Box::new(Begin::new(
1995 body_exprs,
1996 SyntaxObject::default(TokenType::Begin),
1997 )))
1998 };
1999
2000 let mut arguments = ThinVec::with_capacity(pairs.len());
2001
2002 let mut application_args = Vec::with_capacity(pairs.len());
2005
2006 for pair in pairs {
2007 if let ExprKind::List(l) = pair {
2008 let pair = l.args;
2009
2010 if pair.len() != 2 {
2011 return Err(ParseError::SyntaxError(
2012 format!("let expected a list of variable binding pairs, found a pair with length {}",
2013 pair.len()),
2014 syn.span, None
2015 ));
2016 }
2017
2018 let identifier = pair[0].clone();
2019 let application_arg = pair[1].clone();
2020
2021 arguments.push(identifier);
2022 application_args.push(application_arg);
2023 } else {
2024 return Err(ParseError::SyntaxError(
2025 "let expected a list of variable binding pairs".to_string(),
2026 syn.span,
2027 None,
2028 ));
2029 }
2030 }
2031
2032 let function: ExprKind = LambdaFunction::new(arguments, body, syn.clone()).into();
2034
2035 let define: ExprKind = Define::new(name.clone(), function, syn.clone()).into();
2036
2037 let mut fake_application_args = application_args
2040 .iter()
2041 .enumerate()
2042 .map(|(x, _)| ExprKind::ident(&format!("###{}", x)))
2043 .collect();
2044
2045 let application: ExprKind = {
2046 let mut application = thin_vec![name];
2047 application.append(&mut fake_application_args);
2048 List::new(application).into()
2049 };
2050
2051 let begin = ExprKind::Begin(Box::new(Begin::new(vec![define, application], syn.clone())));
2052
2053 let eval_application_args = ExprKind::Let(Box::new(Let::new(
2054 application_args
2055 .into_iter()
2056 .enumerate()
2057 .map(|x| (ExprKind::ident(&format!("###{}", x.0)), x.1))
2058 .collect(),
2059 begin,
2060 syn.clone(),
2061 )));
2062
2063 Ok(List::new(thin_vec![LambdaFunction::new(
2066 thin_vec![],
2067 eval_application_args,
2068 syn,
2069 )
2070 .into()])
2071 .into())
2072}
2073
2074#[inline]
2075pub(crate) fn parse_let<I>(
2076 mut value_iter: I,
2077 mut syn: SyntaxObject,
2078) -> core::result::Result<ExprKind, ParseError>
2079where
2080 I: Iterator<Item = ExprKind>,
2081{
2082 value_iter.next();
2083
2084 let let_pairs = match value_iter.next().ok_or_else(|| {
2085 ParseError::SyntaxError(
2086 "let expected a list of variable bindings pairs in the second position, found none"
2087 .to_string(),
2088 syn.span,
2089 None,
2090 )
2091 })? {
2092 ExprKind::List(l) => l.args,
2094 name @ ExprKind::Atom(_) => return parse_named_let(value_iter, syn, name),
2096 _ => {
2097 return Err(ParseError::SyntaxError(
2098 "let expects a list of variable bindings pairs in the second position".to_string(),
2099 syn.span,
2100 None,
2101 ));
2102 }
2103 };
2104
2105 let body_exprs: Vec<_> = value_iter.collect();
2106
2107 if body_exprs.is_empty() {
2108 return Err(ParseError::SyntaxError(
2109 "let expects an expression, found none".to_string(),
2110 syn.span,
2111 None,
2112 ));
2113 }
2114
2115 let body = if body_exprs.len() == 1 {
2116 body_exprs[0].clone()
2117 } else {
2118 ExprKind::Begin(Box::new(Begin::new(
2119 body_exprs,
2120 SyntaxObject::default(TokenType::Begin),
2121 )))
2122 };
2123
2124 let mut arguments = ThinVec::with_capacity(let_pairs.len());
2125
2126 let mut application_args = ThinVec::with_capacity(let_pairs.len());
2129
2130 for pair in let_pairs {
2131 if let ExprKind::List(l) = pair {
2132 let pair = l.args;
2133
2134 if pair.len() != 2 {
2135 return Err(ParseError::SyntaxError(
2136 format!("let expected a list of variable binding pairs, found a pair with length {}",
2137 pair.len()),
2138 syn.span, None
2139 ));
2140 }
2141
2142 let identifier = pair[0].clone();
2143 let application_arg = pair[1].clone();
2144
2145 arguments.push(identifier);
2146 application_args.push(application_arg);
2147 } else {
2148 return Err(ParseError::SyntaxError(
2149 "let expected a list of variable binding pairs".to_string(),
2150 syn.span,
2151 None,
2152 ));
2153 }
2154 }
2155
2156 syn.ty = TokenType::Lambda;
2158
2159 let mut function: ThinVec<ExprKind> =
2160 thin_vec![LambdaFunction::new(arguments, body, syn).into()];
2161
2162 function.append(&mut application_args);
2163
2164 Ok(ExprKind::List(List::new(function)))
2165}
2166
2167#[inline]
2168pub(crate) fn parse_single_argument<I>(
2169 mut value_iter: I,
2170 syn: SyntaxObject,
2171 name: &'static str,
2172 constructor: fn(ExprKind, SyntaxObject) -> ExprKind,
2173) -> Result<ExprKind, ParseError>
2174where
2175 I: Iterator<Item = ExprKind>,
2176{
2177 value_iter.next();
2178
2179 let func = value_iter.next().ok_or_else(|| {
2180 ParseError::ArityMismatch(
2181 format!("{name} expected one argument, found none"),
2182 syn.span,
2183 None,
2184 )
2185 })?;
2186
2187 if value_iter.next().is_some() {
2188 Err(ParseError::SyntaxError(
2189 format!("{name} expects only one argument"),
2190 syn.span,
2191 None,
2192 ))
2193 } else {
2194 Ok(constructor(func, syn))
2195 }
2196}
2197
2198impl TryFrom<ThinVec<ExprKind>> for ExprKind {
2199 type Error = ParseError;
2200 fn try_from(value: ThinVec<ExprKind>) -> core::result::Result<Self, Self::Error> {
2201 if let Some(f) = value.first().cloned() {
2205 match f {
2206 ExprKind::Atom(a) => {
2207 match &a.syn.ty {
2210 TokenType::If => parse_if(value.into_iter(), a.syn.clone()),
2213 TokenType::Identifier(expr) if *expr == *IF => {
2214 parse_if(value.into_iter(), a.syn.clone())
2215 }
2216
2217 TokenType::Define => parse_define(value.into_iter(), a.syn.clone()),
2218 TokenType::Identifier(expr) if *expr == *DEFINE => {
2219 parse_define(value.into_iter(), a.syn.clone())
2220 }
2221
2222 TokenType::Let => parse_let(value.into_iter(), a.syn.clone()),
2223 TokenType::Identifier(expr) if *expr == *LET => {
2224 parse_let(value.into_iter(), a.syn.clone())
2225 }
2226
2227 TokenType::TestLet => parse_new_let(value.into_iter(), a.syn.clone()),
2229 TokenType::Identifier(expr) if *expr == *PLAIN_LET => {
2230 parse_new_let(value.into_iter(), a.syn.clone())
2231 }
2232
2233 TokenType::Quote => parse_single_argument(
2234 value.into_iter(),
2235 a.syn.clone(),
2236 "quote",
2237 |expr, syn| Quote::new(expr, syn).into(),
2238 ),
2239 TokenType::Identifier(expr) if *expr == *QUOTE => parse_single_argument(
2240 value.into_iter(),
2241 a.syn.clone(),
2242 "quote",
2243 |expr, syn| Quote::new(expr, syn).into(),
2244 ),
2245
2246 TokenType::Return => parse_single_argument(
2247 value.into_iter(),
2248 a.syn.clone(),
2249 "return!",
2250 |expr, syn| Return::new(expr, syn).into(),
2251 ),
2252 TokenType::Identifier(expr) if *expr == *RETURN => parse_single_argument(
2253 value.into_iter(),
2254 a.syn.clone(),
2255 "return!",
2256 |expr, syn| Return::new(expr, syn).into(),
2257 ),
2258
2259 TokenType::Require => parse_require(&a, value),
2260 TokenType::Identifier(expr) if *expr == *REQUIRE => {
2261 parse_require(&a, value)
2262 }
2263
2264 TokenType::Set => parse_set(&a, value),
2265 TokenType::Identifier(expr) if *expr == *SET => parse_set(&a, value),
2266
2267 TokenType::Begin => parse_begin(a, value),
2268 TokenType::Identifier(expr) if *expr == *BEGIN => parse_begin(a, value),
2269
2270 TokenType::Lambda => parse_lambda(a, value),
2271 TokenType::Identifier(expr)
2272 if *expr == *LAMBDA
2273 || *expr == *LAMBDA_FN
2274 || *expr == *LAMBDA_SYMBOL =>
2275 {
2276 parse_lambda(a, value)
2277 }
2278
2279 TokenType::Identifier(expr) if *expr == *DEFINE_SYNTAX => {
2280 let syn = a.syn.clone();
2281
2282 if value.len() < 3 {
2283 return Err(ParseError::SyntaxError(
2284 format!("define-syntax expects 2 arguments - the name of the macro and the syntax-rules, found {}", value.len()), syn.span, None
2285 ));
2286 }
2287
2288 let mut value_iter = value.into_iter();
2291 value_iter.next();
2292
2293 let name = value_iter.next().unwrap();
2294
2295 let syntax = value_iter.next();
2296
2297 let syntax_rules = if let Some(ExprKind::SyntaxRules(s)) = syntax {
2300 s
2301 } else {
2302 return Err(ParseError::SyntaxError(
2303 "define-syntax expected a syntax-rules object".to_string(),
2304 syn.span,
2305 None,
2306 ));
2307 };
2308
2309 Ok(ExprKind::Macro(Box::new(Macro::new(
2310 name,
2311 syntax_rules,
2312 syn,
2313 ))))
2314 }
2315
2316 TokenType::DefineSyntax => {
2317 let syn = a.syn.clone();
2318
2319 if value.len() < 3 {
2320 return Err(ParseError::SyntaxError(
2321 format!("define-syntax expects 2 arguments - the name of the macro and the syntax-rules, found {}", value.len()), syn.span, None
2322 ));
2323 }
2324
2325 let mut value_iter = value.into_iter();
2328 value_iter.next();
2329
2330 let name = value_iter.next().unwrap();
2331
2332 let syntax = value_iter.next();
2333
2334 let syntax_rules = if let Some(ExprKind::SyntaxRules(s)) = syntax {
2337 s
2338 } else {
2339 return Err(ParseError::SyntaxError(
2340 "define-syntax expected a syntax-rules object".to_string(),
2341 syn.span,
2342 None,
2343 ));
2344 };
2345
2346 Ok(ExprKind::Macro(Box::new(Macro::new(
2347 name,
2348 syntax_rules,
2349 syn,
2350 ))))
2351 }
2352 TokenType::SyntaxRules => {
2353 let syn = a.syn.clone();
2354
2355 if value.len() < 3 {
2356 return Err(ParseError::SyntaxError(
2357 format!("syntax-rules expects a list of introduced syntax, and at least one pattern-body pair, found {} arguments", value.len()), syn.span, None
2358 ));
2359 }
2360
2361 let mut value_iter = value.into_iter();
2362 value_iter.next();
2363
2364 let syntax_vec = if let Some(ExprKind::List(l)) = value_iter.next() {
2365 l.args
2366 } else {
2367 return Err(ParseError::SyntaxError(
2368 "syntax-rules expects a list of new syntax forms used in the macro".to_string(), syn.span, None));
2369 };
2370
2371 let mut pairs = ThinVec::new();
2372 let rest: Vec<_> = value_iter.collect();
2373
2374 for pair in rest {
2375 if let ExprKind::List(l) = pair {
2376 if l.args.len() != 2 {
2377 return Err(ParseError::SyntaxError(
2378 "syntax-rules requires only one pattern to one body"
2379 .to_string(),
2380 syn.span,
2381 None,
2382 ));
2383 }
2384
2385 let mut pair_iter = l.args.into_iter();
2386 let pair_object = PatternPair::new(
2387 pair_iter.next().unwrap(),
2388 pair_iter.next().unwrap(),
2389 )?;
2390 pairs.push(pair_object);
2391 } else {
2392 return Err(ParseError::SyntaxError(
2393 "syntax-rules requires pattern to expressions to be in a list".to_string(), syn.span, None
2394 ));
2395 }
2396 }
2397
2398 Ok(ExprKind::SyntaxRules(Box::new(SyntaxRules::new(
2399 syntax_vec, pairs, syn,
2400 ))))
2401 }
2402
2403 TokenType::Identifier(expr) if *expr == *SYNTAX_RULES => {
2404 let syn = a.syn.clone();
2405
2406 if value.len() < 3 {
2407 return Err(ParseError::SyntaxError(
2408 format!("syntax-rules expects a list of introduced syntax, and at least one pattern-body pair, found {} arguments", value.len()), syn.span, None
2409 ));
2410 }
2411
2412 let mut value_iter = value.into_iter();
2413 value_iter.next();
2414
2415 let syntax_vec = if let Some(ExprKind::List(l)) = value_iter.next() {
2416 l.args
2417 } else {
2418 return Err(ParseError::SyntaxError(
2419 "syntax-rules expects a list of new syntax forms used in the macro".to_string(), syn.span, None));
2420 };
2421
2422 let mut pairs = ThinVec::new();
2423 let rest: Vec<_> = value_iter.collect();
2424
2425 for pair in rest {
2426 if let ExprKind::List(l) = pair {
2427 if l.args.len() != 2 {
2428 return Err(ParseError::SyntaxError(
2429 "syntax-rules requires only one pattern to one body"
2430 .to_string(),
2431 syn.span,
2432 None,
2433 ));
2434 }
2435
2436 let mut pair_iter = l.args.into_iter();
2437 let pair_object = PatternPair::new(
2438 pair_iter.next().unwrap(),
2439 pair_iter.next().unwrap(),
2440 )?;
2441 pairs.push(pair_object);
2442 } else {
2443 return Err(ParseError::SyntaxError(
2444 "syntax-rules requires pattern to expressions to be in a list".to_string(), syn.span, None
2445 ));
2446 }
2447 }
2448
2449 Ok(ExprKind::SyntaxRules(Box::new(SyntaxRules::new(
2450 syntax_vec, pairs, syn,
2451 ))))
2452 }
2453 _ => Ok(ExprKind::List(List::new(value))),
2454 }
2455 }
2456 _ => Ok(ExprKind::List(List::new(value))),
2457 }
2458 } else {
2459 Ok(ExprKind::List(List::new(thin_vec![])))
2460 }
2461 }
2462}
2463
2464pub fn parse_lambda(a: Atom, value: ThinVec<ExprKind>) -> Result<ExprKind, ParseError> {
2465 let syn = a.syn;
2466 if value.len() < 3 {
2467 return Err(ParseError::SyntaxError(
2468 format!(
2469 "lambda expected at least 2 arguments - the bindings list and one or more expressions, found {} instead",
2470 value.len()
2471 ),
2472 syn.span, None
2473 ));
2474 }
2475 let mut value_iter = value.into_iter();
2476 value_iter.next();
2477 let arguments = value_iter.next();
2478 match arguments {
2479 Some(ExprKind::List(l)) => {
2480 let args = l.args;
2481
2482 let body_exprs: Vec<_> = value_iter.collect();
2498
2499 let body = if body_exprs.len() == 1 {
2500 body_exprs.into_iter().next().unwrap()
2501 } else {
2502 ExprKind::Begin(Box::new(Begin::new(
2503 body_exprs,
2504 SyntaxObject::default(TokenType::Begin),
2505 )))
2506 };
2507
2508 let rest = l.improper;
2509
2510 Ok(ExprKind::LambdaFunction(Box::new(
2511 LambdaFunction::new_maybe_rest(args, body, syn, rest),
2512 )))
2513 }
2514 Some(ExprKind::Atom(a)) => {
2515 let body_exprs: Vec<_> = value_iter.collect();
2516
2517 let body = if body_exprs.len() == 1 {
2518 body_exprs.into_iter().next().unwrap()
2519 } else {
2520 ExprKind::Begin(Box::new(Begin::new(
2521 body_exprs,
2522 SyntaxObject::default(TokenType::Begin),
2523 )))
2524 };
2525
2526 Ok(ExprKind::LambdaFunction(Box::new(
2528 LambdaFunction::new_with_rest_arg(thin_vec![ExprKind::Atom(a)], body, syn),
2529 )))
2530 }
2531 _ => {
2532 Err(ParseError::SyntaxError(
2537 format!("lambda function expected a list of identifiers, found: {arguments:?}"),
2538 syn.span,
2539 None,
2540 ))
2541 }
2542 }
2543}
2544
2545pub(crate) fn parse_set(a: &Atom, value: ThinVec<ExprKind>) -> Result<ExprKind, ParseError> {
2546 let syn = a.syn.clone();
2547 if value.len() != 3 {
2548 return Err(ParseError::ArityMismatch(
2549 "set! expects an identifier and an expression".to_string(),
2550 syn.span,
2551 None,
2552 ));
2553 }
2554 let mut value_iter = value.into_iter();
2555 value_iter.next();
2556 let identifier = value_iter.next().unwrap();
2557 let expression = value_iter.next().unwrap();
2558 Ok(ExprKind::Set(Box::new(Set::new(
2559 identifier, expression, syn,
2560 ))))
2561}
2562
2563pub(crate) fn parse_require(a: &Atom, value: ThinVec<ExprKind>) -> Result<ExprKind, ParseError> {
2564 let syn = a.syn.clone();
2565 if value.len() < 2 {
2566 return Err(ParseError::ArityMismatch(
2567 "require expects at least one identifier or string".to_string(),
2568 syn.span,
2569 None,
2570 ));
2571 }
2572 let mut value_iter = value.into_iter();
2573 value_iter.next();
2574 let expressions = value_iter
2575 .map(|x| {
2576 match &x {
2577 ExprKind::Atom(_) | ExprKind::List(_) => Ok(x),
2578 _ => Err(ParseError::SyntaxError(
2579 "require expects atoms".to_string(),
2580 syn.span,
2581 None,
2582 )),
2583 }
2584
2585 })
2591 .collect::<Result<Vec<_>, ParseError>>()?;
2592 Ok(ExprKind::Require(Box::new(Require::new(expressions, syn))))
2593}
2594
2595pub(crate) fn parse_begin(a: Atom, value: ThinVec<ExprKind>) -> Result<ExprKind, ParseError> {
2596 let syn = a.syn;
2597 let mut value_iter = value.into_iter();
2598 value_iter.next();
2599 Ok(ExprKind::Begin(Box::new(Begin::new(
2600 value_iter.collect(),
2601 syn,
2602 ))))
2603}
2604
2605#[cfg(test)]
2606mod display_tests {
2607
2608 use super::*;
2609 use crate::parser::{Parser, Result, SourceId};
2610
2611 fn parse(expr: &str) -> ExprKind {
2612 let a: Result<Vec<ExprKind>> = Parser::new(expr, SourceId::none()).collect();
2613
2614 a.unwrap()[0].clone()
2615 }
2616
2617 #[test]
2618 fn display_lambda_quote() {
2619 let expression = "(lambda (x) (quote x))";
2620 let parsed_expr = parse(expression);
2621 let expected = "(lambda (x) (quote x))";
2622 assert_eq!(parsed_expr.to_string(), expected);
2623 }
2624
2625 #[test]
2626 fn display_list() {
2627 let expression = "(list 1 2 3 4)";
2628 let parsed_expr = parse(expression);
2629 let expected = "(list 1 2 3 4)";
2630 assert_eq!(parsed_expr.to_string(), expected);
2631 }
2632
2633 #[test]
2634 fn display_lambda() {
2635 let expression = "(lambda (x) (+ x 10))";
2636 let parsed_expr = parse(expression);
2637 let expected = "(lambda (x) (+ x 10))";
2638 assert_eq!(parsed_expr.to_string(), expected);
2639 }
2640
2641 #[test]
2642 fn display_set() {
2643 let expression = "(set! x 10)";
2644 let parsed_expr = parse(expression);
2645 let expected = "(set! x 10)";
2646 assert_eq!(parsed_expr.to_string(), expected);
2647 }
2648
2649 #[test]
2650 fn display_panic() {
2651 let expression = "(panic! 12345)";
2652 let parsed_expr = parse(expression);
2653 let expected = "(panic! 12345)";
2654 assert_eq!(parsed_expr.to_string(), expected);
2655 }
2656
2657 #[test]
2658 fn display_begin() {
2659 let expression = "(begin 1 2 3 4 5)";
2660 let parsed_expr = parse(expression);
2661 let expected = "(begin 1 2 3 4 5)";
2662 assert_eq!(parsed_expr.to_string(), expected);
2663 }
2664
2665 #[test]
2666 fn display_define_normal() {
2667 let expression = "(define a 10)";
2668 let parsed_expr = parse(expression);
2669 let expected = "(define a 10)";
2670 assert_eq!(parsed_expr.to_string(), expected);
2671 }
2672
2673 #[test]
2674 fn display_define_function() {
2675 let expression = "(define (applesauce x y z) (+ x y z))";
2676 let parsed_expr = parse(expression);
2677 let expected = "(define applesauce (lambda (x y z) (+ x y z)))";
2678 assert_eq!(parsed_expr.to_string(), expected);
2679 }
2680
2681 #[test]
2682 fn display_let() {
2683 let expression = "(let ((x 10)) (+ x 10))";
2684 let parsed_expr = parse(expression);
2685 let expected = "((lambda (x) (+ x 10)) 10)";
2686 assert_eq!(parsed_expr.to_string(), expected);
2687 }
2688
2689 #[test]
2690 fn display_apply() {
2691 let expression = "(apply + (list 1 2 3 4))";
2692 let parsed_expr = parse(expression);
2693 let expected = "(apply + (list 1 2 3 4))";
2694 assert_eq!(parsed_expr.to_string(), expected);
2695 }
2696
2697 #[test]
2698 fn display_transduce() {
2699 let expression = "(transduce 1 2 3 4)";
2700 let parsed_expr = parse(expression);
2701 let expected = "(transduce 1 2 3 4)";
2702 assert_eq!(parsed_expr.to_string(), expected);
2703 }
2704
2705 #[test]
2706 fn display_execute_two_args() {
2707 let expression = "(execute 1 2)";
2708 let parsed_expr = parse(expression);
2709 let expected = "(execute 1 2)";
2710 assert_eq!(parsed_expr.to_string(), expected);
2711 }
2712
2713 #[test]
2714 fn display_execute_three_args() {
2715 let expression = "(execute 1 2 3)";
2716 let parsed_expr = parse(expression);
2717 let expected = "(execute 1 2 3)";
2718 assert_eq!(parsed_expr.to_string(), expected);
2719 }
2720
2721 #[test]
2722 fn display_if() {
2723 let expression = "(if 1 2 3)";
2724 let parsed_expr = parse(expression);
2725 let expected = "(if 1 2 3)";
2726 assert_eq!(parsed_expr.to_string(), expected);
2727 }
2728
2729 #[test]
2730 fn display_quote() {
2731 let expression = "'(1 2 3 4)";
2732 let parsed_expr = parse(expression);
2733 let expected = "(quote (1 2 3 4))";
2734 assert_eq!(parsed_expr.to_string(), expected);
2735 }
2736
2737 #[test]
2738 fn display_read() {
2739 let expression = "(read '(1 2 3 4))";
2740 let parsed_expr = parse(expression);
2741 let expected = "(read (quote (1 2 3 4)))";
2742 assert_eq!(parsed_expr.to_string(), expected);
2743 }
2744
2745 #[test]
2746 fn display_return() {
2747 let expression = "(return! 10)";
2748 let parsed_expr = parse(expression);
2749 let expected = "(return! 10)";
2750 assert_eq!(parsed_expr.to_string(), expected);
2751 }
2752
2753 #[test]
2754 fn display_struct() {
2755 let expression = "(struct Apple (a b c))";
2756 let parsed_expr = parse(expression);
2757 let expected = "(struct Apple (a b c))";
2758 assert_eq!(parsed_expr.to_string(), expected);
2759 }
2760
2761 #[test]
2762 fn display_eval() {
2763 let expression = "(eval 'a)";
2764 let parsed_expr = parse(expression);
2765 let expected = "(eval (quote a))";
2766 assert_eq!(parsed_expr.to_string(), expected);
2767 }
2768}
2769
2770#[cfg(test)]
2771mod pretty_print_tests {
2772 use super::*;
2773 use crate::parser::{Parser, Result, SourceId};
2774
2775 fn parse(expr: &str) -> ExprKind {
2776 let a: Result<Vec<ExprKind>> = Parser::new(expr, SourceId::none()).collect();
2777
2778 a.unwrap()[0].clone()
2779 }
2780
2781 #[test]
2782 fn pretty_set() {
2783 let expression = r#"
2784 (define test-function
2785 (lambda (a b c)
2786 (begin
2787 (set! bananas 10)
2788 (if applesauce 100 #f)
2789 (if applesauce 100 (if applesauce 100 #f)))))"#;
2790 let parsed_expr = parse(expression);
2791 let _output = parsed_expr.to_pretty(45);
2792
2793 assert!(true)
2794 }
2795}