steel/parser/
ast.rs

1use crate::{
2    parser::{
3        parser::SyntaxObject, tokens::TokenType::*, tryfrom_visitor::TryFromExprKindForSteelVal,
4    },
5    rvals::SteelComplex,
6};
7
8use steel_parser::tokens::{IntLiteral, NumberLiteral, RealLiteral};
9
10use crate::{
11    rerrs::SteelErr,
12    rvals::SteelVal::{self, *},
13};
14
15pub use steel_parser::ast::{
16    AstTools, Atom, Begin, Define, ExprKind, If, IteratorExtensions, LambdaFunction, Let, List,
17    Macro, PatternPair, Quote, Require, Return, Set, SyntaxRules, Vector, STANDARD_MODULE_GET,
18    UNREADABLE_MODULE_GET,
19};
20
21impl TryFrom<ExprKind> for SteelVal {
22    type Error = SteelErr;
23
24    fn try_from(e: ExprKind) -> std::result::Result<Self, Self::Error> {
25        TryFromExprKindForSteelVal::try_from_expr_kind(e)
26    }
27}
28
29/// Convert this ExprKind into a typed version of the AST
30/// TODO: Matt -> actually do a full visitor on the AST
31// pub(crate) fn from_list_repr_to_ast(expr: ExprKind) -> Result<ExprKind, ParseError> {
32//     if let ExprKind::List(l) = expr {
33//         ExprKind::try_from(
34//             l.args
35//                 .into_iter()
36//                 .map(from_list_repr_to_ast)
37//                 .collect::<Result<Vec<_>, ParseError>>()?,
38//         )
39//     } else {
40//         Ok(expr)
41//     }
42// }
43
44#[derive(Debug)]
45pub(crate) struct TryFromSteelValVisitorForExprKind {
46    pub(crate) qq_depth: usize,
47    pub(crate) quoted: bool,
48}
49
50impl TryFromSteelValVisitorForExprKind {
51    pub fn root(value: &SteelVal) -> std::result::Result<ExprKind, SteelErr> {
52        Self {
53            qq_depth: 0,
54            quoted: false,
55        }
56        .visit(value)
57    }
58
59    // type Error = &'static str;
60    pub fn visit(&mut self, value: &SteelVal) -> std::result::Result<ExprKind, SteelErr> {
61        match value {
62            BoolV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
63                BooleanLiteral(*x),
64            )))),
65            NumV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
66                RealLiteral::Float(*x).into(),
67            )))),
68            IntV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
69                RealLiteral::Int(IntLiteral::Small(*x)).into(),
70            )))),
71
72            BigNum(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
73                RealLiteral::Int(IntLiteral::Big(Box::new(x.unwrap()))).into(),
74            )))),
75            VectorV(lst) => {
76                let items: std::result::Result<Vec<ExprKind>, _> =
77                    lst.iter().map(|x| self.visit(x)).collect();
78                Ok(ExprKind::List(List::new(items?)))
79            }
80            Void => stop!(Generic => "Can't convert from Void to expression!"),
81            StringV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
82                StringLiteral(x.to_arc_string()),
83            )))),
84            FuncV(_) => stop!(Generic => "Can't convert from Function to expression!"),
85
86            SymbolV(x) if x.starts_with("#:") => Ok(ExprKind::Atom(Atom::new(
87                SyntaxObject::default(Keyword(x.as_str().into())),
88            ))),
89
90            SymbolV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
91                Identifier(x.as_str().into()),
92            )))),
93
94            // TODO: Change the implementation here to respect quotes correctly
95            SyntaxObject(s) => self.visit_syntax_object(s),
96            Custom(_) => {
97                // TODO: if the returned object is a custom type, check
98                // to see if its a Syntax struct to replace the span with
99                stop!(Generic => "Can't convert from Custom Type to expression!")
100            }
101            ListV(l) => {
102                // Rooted - things operate as normal
103                if self.qq_depth == 0 {
104                    let maybe_special_form = l.first().and_then(|x| {
105                        x.as_symbol()
106                            .or_else(|| x.as_syntax_object().and_then(|x| x.syntax.as_symbol()))
107                    });
108
109                    // dbg!(&maybe_special_form);
110
111                    match maybe_special_form {
112                        Some(x) if x.as_str() == "quote" => {
113                            if self.quoted {
114                                let items: std::result::Result<Vec<ExprKind>, _> =
115                                    l.iter().map(|x| self.visit(x)).collect();
116
117                                return Ok(ExprKind::List(List::new(items?)));
118                            }
119
120                            self.quoted = true;
121
122                            let return_value = Ok(l
123                                .into_iter()
124                                .map(|x| self.visit(x))
125                                .collect::<std::result::Result<Vec<_>, _>>()?
126                                .try_into()?);
127
128                            // dbg!(&return_value);
129
130                            self.quoted = false;
131
132                            return return_value;
133                        } // "quasiquote" => {
134                        //     self.qq_depth += 1;
135                        // }
136
137                        // Empty list, just return as a quoted list
138                        // None => {
139                        // return Ok(ExprKind::empty());
140                        // }
141                        _ => {}
142                    }
143                }
144
145                Ok(l.into_iter()
146                    .map(|x| self.visit(x))
147                    .collect::<std::result::Result<Vec<_>, _>>()?
148                    .try_into()?)
149
150                // If we're not quoted, we need to just return this pushed down to an ast
151                // let items: std::result::Result<Vec<ExprKind>, &'static str> =
152                // l.iter().map(|x| self.visit(x)).collect();
153
154                // Ok(ExprKind::List(List::new(items?)))
155            }
156            CharV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
157                CharacterLiteral(*x),
158            )))),
159            unknown => {
160                stop!(Generic => "Unable to convert from value to expression: {:?}", unknown)
161            }
162        }
163    }
164}
165
166#[cold]
167fn complex_to_literal(v: &SteelComplex) -> Result<NumberLiteral, &'static str> {
168    let val_to_real = |real_val: &SteelVal| -> Result<RealLiteral, &'static str> {
169        let l = match real_val {
170            NumV(n) => (*n).into(),
171            IntV(n) => (*n).into(),
172            Rational(n) => (*n).into(),
173            BigNum(n) => IntLiteral::Big(Box::new(n.as_ref().clone())).into(),
174            BigRational(n) => RealLiteral::Rational(
175                IntLiteral::Big(Box::new(n.numer().clone())),
176                IntLiteral::Big(Box::new(n.denom().clone())),
177            ),
178            _ => return Err("SteelVal not a valid real number"),
179        };
180        Ok(l)
181    };
182    let re = val_to_real(&v.re)?;
183    let im = val_to_real(&v.im)?;
184    Ok(NumberLiteral::Complex(re, im))
185}
186
187/// Sometimes you want to execute a list
188/// as if it was an expression
189impl TryFrom<&SteelVal> for ExprKind {
190    type Error = &'static str;
191    fn try_from(r: &SteelVal) -> std::result::Result<Self, Self::Error> {
192        fn inner_try_from(
193            r: &SteelVal,
194            depth: usize,
195        ) -> std::result::Result<ExprKind, &'static str> {
196            if depth > 64 {
197                return Err("Unable to convert steel val to exprkind - depth was too large!");
198            }
199
200            match r {
201                BoolV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
202                    BooleanLiteral(*x),
203                )))),
204                NumV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
205                    RealLiteral::Float(*x).into(),
206                )))),
207                IntV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
208                    RealLiteral::Int(IntLiteral::Small(*x)).into(),
209                )))),
210                Rational(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
211                    RealLiteral::Rational(
212                        IntLiteral::Small(*x.numer() as isize),
213                        IntLiteral::Small(*x.denom() as isize),
214                    )
215                    .into(),
216                )))),
217                BigRational(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
218                    RealLiteral::Rational(
219                        IntLiteral::Big(Box::new(x.numer().clone())),
220                        IntLiteral::Big(Box::new(x.denom().clone())),
221                    )
222                    .into(),
223                )))),
224                BigNum(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
225                    RealLiteral::Int(IntLiteral::Big(Box::new(x.unwrap()))).into(),
226                )))),
227                Complex(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
228                    complex_to_literal(x)?.into(),
229                )))
230                .into()),
231                VectorV(lst) => {
232                    let items: std::result::Result<Vec<ExprKind>, &'static str> =
233                        lst.iter().map(|x| inner_try_from(x, depth + 1)).collect();
234                    Ok(ExprKind::List(List::new(items?)))
235                }
236                Void => Err("Can't convert from Void to expression!"),
237                StringV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
238                    StringLiteral(x.to_arc_string()),
239                )))),
240                FuncV(_) => Err("Can't convert from Function to expression!"),
241                SymbolV(x) if x.starts_with("#:") => Ok(ExprKind::Atom(Atom::new(
242                    SyntaxObject::default(Keyword(x.as_str().into())),
243                ))),
244                SymbolV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
245                    Identifier(x.as_str().into()),
246                )))),
247                SyntaxObject(s) => s
248                    .to_exprkind()
249                    .map_err(|_| "Unable to convert syntax object back to exprkind"),
250                Custom(_) => {
251                    // TODO: if the returned object is a custom type, check
252                    // to see if its a Syntax struct to replace the span with
253                    Err("Can't convert from Custom Type to expression!")
254                }
255                ListV(l) => {
256                    let items: std::result::Result<Vec<ExprKind>, &'static str> =
257                        l.iter().map(|x| inner_try_from(x, depth + 1)).collect();
258
259                    Ok(ExprKind::List(List::new(items?)))
260                }
261                CharV(x) => Ok(ExprKind::Atom(Atom::new(SyntaxObject::default(
262                    CharacterLiteral(*x),
263                )))),
264
265                Pair(_) => Err("Can't convert from pair to expression!"),
266
267                PortV(_) => Err("Can't convert from port to expression!"),
268                Closure(_) => Err("Can't convert from bytecode closure to expression"),
269                HashMapV(_) => Err("Can't convert from hashmap to expression!"),
270                HashSetV(_) => Err("Can't convert from hashset to expression!"),
271                IterV(_) => Err("Can't convert from iterator to expression!"),
272                FutureFunc(_) => Err("Can't convert from future function to expression!"),
273                FutureV(_) => Err("Can't convert future to expression!"),
274                StreamV(_) => Err("Can't convert from stream to expression!"),
275                BoxedFunction(_) => Err("Can't convert from boxed function to expression!"),
276                ContinuationFunction(_) => Err("Can't convert from continuation to expression!"),
277                MutFunc(_) => Err("Can't convert from function to expression!"),
278                BuiltIn(_) => Err("Can't convert from function to expression!"),
279                ReducerV(_) => Err("Can't convert from reducer to expression!"),
280                MutableVector(_) => Err("Can't convert from vector to expression!"),
281                CustomStruct(_) => Err("Can't convert from struct to expression!"),
282                BoxedIterator(_) => Err("Can't convert from boxed iterator to expression!"),
283                Boxed(_) => Err("Can't convert from boxed steel val to expression!"),
284                Reference(_) => Err("Can't convert from opaque reference type to expression!"),
285                HeapAllocated(_) => Err("Can't convert from heap allocated value to expression!"),
286                ByteVector(_) => Err("Can't convert from bytevector to expression!"),
287            }
288        }
289
290        inner_try_from(r, 0)
291    }
292}