Skip to main content

steel_parser/
ast.rs

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
19// TODO: Have this macro share the implementation crate wide
20macro_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                // estimate lower bound of capacity needed
110                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        // TODO: accept more literals e.g. `3+0i`, `3/3`, etc.
528        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// Define normal
736#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
737pub struct Define {
738    // This could either be name + args
739    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    // Helpful for the optimizer and the LSP
800    // to resolve keyword args ahead of time.
801    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    // TODO: Attach the span from the parser - just the offset
1115    // of the open and close parens
1116    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
1441// and we'll implement IntoIterator
1442impl IntoIterator for List {
1443    type Item = ExprKind;
1444    // type IntoIter = alloc::vec::IntoIter<Self::Item>;
1445    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// TODO figure out how many fields a macro has
1487// put it into here nicely
1488#[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// TODO figure out a good mapping immediately to a macro that can be interpreted
1531// by the expander
1532#[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    // let mut value_iter = value.into_iter();
1647    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        // Replace else condition with just a void if its not found!
1665        value_iter
1666            .next()
1667            .unwrap_or_else(|| ExprKind::ident("#%prim.void")),
1668        //     ok_or_else(|| {
1669        //     ParseError::SyntaxError(
1670        //         "if expects an else condition, found none".to_string(),
1671        //         syn.span,
1672        //         None,
1673        //     )
1674        // })?,
1675        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        // TODO maybe add implicit begin here
1708        // maybe do it later, not sure
1709        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    // insert args at the end
2003    // put the function in the inside
2004    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    // This is the body of the define
2033    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    // Evaluate the application args first:
2038
2039    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    // Wrap the whole thing inside of an empty function application, to create a new scope
2064
2065    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        // Standard let
2093        ExprKind::List(l) => l.args,
2094        // Named let
2095        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    // insert args at the end
2127    // put the function in the inside
2128    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    // Since we've converted it, we should turn it into a lambda
2157    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        // let mut value = value.into_iter().peekable();
2202
2203        // TODO -> get rid of this clone on the first value
2204        if let Some(f) = value.first().cloned() {
2205            match f {
2206                ExprKind::Atom(a) => {
2207                    // let value = value.into_iter();
2208
2209                    match &a.syn.ty {
2210                        // Have this also match on the first argument being a TokenType::Identifier("if")
2211                        // Do the same for the rest of the arguments
2212                        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                        // TODO: Deprecate
2228                        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                            // println!("{}", value.iter().map(|x| x.to_pretty(60)).join("\n\n"));
2289
2290                            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                            // println!("{:?}", syntax);
2298
2299                            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                            // println!("{}", value.iter().map(|x| x.to_pretty(60)).join("\n\n"));
2326
2327                            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                            // println!("{:?}", syntax);
2335
2336                            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            // for arg in &args {
2483            //     if let ExprKind::Atom(_) = arg {
2484            //         continue;
2485            //     } else {
2486            //         return Err(ParseError::SyntaxError(
2487            //             format!(
2488            //                 "lambda function expects a list of identifiers, found: {}",
2489            //                 List::new(args)
2490            //             ),
2491            //             syn.span,
2492            //             None,
2493            //         ));
2494            //     }
2495            // }
2496
2497            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            // (lambda x ...) => x is a rest arg, becomes a list at run time
2527            Ok(ExprKind::LambdaFunction(Box::new(
2528                LambdaFunction::new_with_rest_arg(thin_vec![ExprKind::Atom(a)], body, syn),
2529            )))
2530        }
2531        _ => {
2532            // TODO -> handle case like
2533            // (lambda x 10) <- where x is immediately bound to be a rest arg
2534            // This should be fairly trivial in this case since we can just put the
2535            // first thing into a vec for the lambda node
2536            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            // if let ExprKind::Atom(a) = x {
2586            //     Ok(a)
2587            // } else {
2588
2589            // }
2590        })
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}