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#[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 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 SyntaxObject(s) => self.visit_syntax_object(s),
96 Custom(_) => {
97 stop!(Generic => "Can't convert from Custom Type to expression!")
100 }
101 ListV(l) => {
102 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 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 self.quoted = false;
131
132 return return_value;
133 } _ => {}
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 }
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
187impl 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 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}