steel_parser/
ast.rs

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