crisp_runtime/
lib.rs

1pub mod parsing;
2use num_iter::{range, range_step};
3use parsing::*;
4use pest::iterators::{Pair, Pairs};
5use proc_macro2::TokenStream;
6use quote::quote;
7use std::{
8    fmt::Debug,
9    ops::{Add, Div, Mul, Sub},
10    sync::Arc,
11};
12
13#[derive(Clone)]
14pub struct FnPtr(pub Arc<dyn Fn(&[Value]) -> Value>);
15impl PartialEq for FnPtr {
16    fn eq(&self, other: &Self) -> bool {
17        self == other
18    }
19    fn ne(&self, other: &Self) -> bool {
20        self != other
21    }
22}
23impl PartialOrd for FnPtr {
24    fn ge(&self, other: &Self) -> bool {
25        true
26    }
27    fn gt(&self, other: &Self) -> bool {
28        true
29    }
30    fn le(&self, other: &Self) -> bool {
31        true
32    }
33    fn lt(&self, other: &Self) -> bool {
34        true
35    }
36    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
37        None
38    }
39}
40impl Debug for FnPtr {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42        return Ok(());
43    }
44}
45
46#[derive(Debug, Clone, PartialEq, PartialOrd)]
47pub enum Value {
48    STR(String),
49    F32(f32),
50    F64(f64),
51    I32(i32),
52    I64(i64),
53    BYTE(u8),
54    BOOL(bool),
55    LIST(Vec<Value>),
56    FN(FnPtr),
57}
58impl Value {
59    pub fn call(&self, args: &[Value]) -> Value {
60        match self {
61            Value::FN(f) => (f.0)(args),
62            _ => panic!("Cannot call a non-function."),
63        }
64    }
65    fn as_string(&self) -> Result<String, String> {
66        if let Value::STR(s) = self {
67            Ok(s.clone())
68        } else {
69            Err("Not a string".to_string())
70        }
71    }
72    fn as_f32(&self) -> Result<f32, String> {
73        if let Value::F32(f) = self {
74            Ok(*f)
75        } else {
76            Err("Not an f32".to_string())
77        }
78    }
79    fn as_f64(&self) -> Result<f64, String> {
80        if let Value::F64(f) = self {
81            Ok(*f)
82        } else {
83            Err("Not an f64".to_string())
84        }
85    }
86    fn as_i32(&self) -> Result<i32, String> {
87        if let Value::I32(f) = self {
88            Ok(*f)
89        } else {
90            Err("Not an i32".to_string())
91        }
92    }
93    fn as_i64(&self) -> Result<i64, String> {
94        if let Value::I64(f) = self {
95            Ok(*f)
96        } else {
97            Err("Not an i64".to_string())
98        }
99    }
100    fn as_bool(&self) -> Result<bool, String> {
101        if let Value::BOOL(b) = self {
102            Ok(*b)
103        } else {
104            Err("Not a bool".to_string())
105        }
106    }
107    fn as_list(&self) -> Result<Vec<Value>, String> {
108        if let Value::LIST(f) = self {
109            Ok(f.clone())
110        } else {
111            Err("Not a list".to_string())
112        }
113    }
114    fn as_function(&self) -> Result<FnPtr, String> {
115        if let Value::FN(f) = self {
116            Ok(f.clone())
117        } else {
118            Err("Not a function".to_string())
119        }
120    }
121}
122impl Add for Value {
123    type Output = Value;
124    fn add(self, rhs: Self) -> Self::Output {
125        match (self, rhs) {
126            (Value::F32(x), Value::F32(y)) => Value::F32(x + y),
127            (Value::F32(x), Value::F64(y)) => Value::F64(x as f64 + y),
128            (Value::F32(x), Value::I32(y)) => Value::F32(x + y as f32),
129            (Value::F32(x), Value::I64(y)) => Value::F64(x as f64 + y as f64),
130
131            (Value::F64(x), Value::F64(y)) => Value::F64(x + y),
132            (Value::F64(x), Value::F32(y)) => Value::F64(x + y as f64),
133            (Value::F64(x), Value::I32(y)) => Value::F64(x + y as f64),
134            (Value::F64(x), Value::I64(y)) => Value::F64(x + y as f64),
135
136            (Value::I32(x), Value::I32(y)) => Value::I32(x + y),
137            (Value::I32(x), Value::I64(y)) => Value::I64(x as i64 + y),
138            (Value::I32(x), Value::F32(y)) => Value::F32(x as f32 + y),
139            (Value::I32(x), Value::F64(y)) => Value::F64(x as f64 + y),
140
141            (Value::I64(x), Value::I64(y)) => Value::I64(x + y),
142            (Value::I64(x), Value::I32(y)) => Value::I64(x + y as i64),
143            (Value::I64(x), Value::F32(y)) => Value::F64(x as f64 + y as f64),
144            (Value::I64(x), Value::F64(y)) => Value::F64(x as f64 + y),
145
146            (Value::STR(x), Value::STR(y)) => Value::STR(x + &y),
147            (Value::BYTE(x), Value::BYTE(y)) => Value::BYTE(x + y),
148            _ => {
149                panic!("Incompatible types for adding.")
150            }
151        }
152    }
153}
154impl Sub for Value {
155    type Output = Value;
156    fn sub(self, rhs: Self) -> Self::Output {
157        match (self, rhs) {
158            (Value::F32(x), Value::F32(y)) => Value::F32(x - y),
159            (Value::F32(x), Value::F64(y)) => Value::F64(x as f64 - y),
160            (Value::F32(x), Value::I32(y)) => Value::F32(x - y as f32),
161            (Value::F32(x), Value::I64(y)) => Value::F64(x as f64 - y as f64),
162
163            (Value::F64(x), Value::F64(y)) => Value::F64(x - y),
164            (Value::F64(x), Value::F32(y)) => Value::F64(x - y as f64),
165            (Value::F64(x), Value::I32(y)) => Value::F64(x - y as f64),
166            (Value::F64(x), Value::I64(y)) => Value::F64(x - y as f64),
167
168            (Value::I32(x), Value::I32(y)) => Value::I32(x - y),
169            (Value::I32(x), Value::I64(y)) => Value::I64(x as i64 - y),
170            (Value::I32(x), Value::F32(y)) => Value::F32(x as f32 - y),
171            (Value::I32(x), Value::F64(y)) => Value::F64(x as f64 - y),
172
173            (Value::I64(x), Value::I64(y)) => Value::I64(x - y),
174            (Value::I64(x), Value::I32(y)) => Value::I64(x - y as i64),
175            (Value::I64(x), Value::F32(y)) => Value::F64(x as f64 - y as f64),
176            (Value::I64(x), Value::F64(y)) => Value::F64(x as f64 - y),
177
178            (Value::BYTE(x), Value::BYTE(y)) => Value::BYTE(x - y),
179            _ => {
180                panic!("Incompatible types for adding.")
181            }
182        }
183    }
184}
185impl Mul for Value {
186    type Output = Value;
187    fn mul(self, rhs: Self) -> Self::Output {
188        match (self, rhs) {
189            (Value::F32(x), Value::F32(y)) => Value::F32(x * y),
190            (Value::F32(x), Value::F64(y)) => Value::F64(x as f64 * y),
191            (Value::F32(x), Value::I32(y)) => Value::F32(x * y as f32),
192            (Value::F32(x), Value::I64(y)) => Value::F64(x as f64 * y as f64),
193
194            (Value::F64(x), Value::F64(y)) => Value::F64(x * y),
195            (Value::F64(x), Value::F32(y)) => Value::F64(x * y as f64),
196            (Value::F64(x), Value::I32(y)) => Value::F64(x * y as f64),
197            (Value::F64(x), Value::I64(y)) => Value::F64(x * y as f64),
198
199            (Value::I32(x), Value::I32(y)) => Value::I32(x * y),
200            (Value::I32(x), Value::I64(y)) => Value::I64(x as i64 * y),
201            (Value::I32(x), Value::F32(y)) => Value::F32(x as f32 * y),
202            (Value::I32(x), Value::F64(y)) => Value::F64(x as f64 * y),
203
204            (Value::I64(x), Value::I64(y)) => Value::I64(x * y),
205            (Value::I64(x), Value::I32(y)) => Value::I64(x * y as i64),
206            (Value::I64(x), Value::F32(y)) => Value::F64(x as f64 * y as f64),
207            (Value::I64(x), Value::F64(y)) => Value::F64(x as f64 * y),
208
209            (Value::BYTE(x), Value::BYTE(y)) => Value::BYTE(x * y),
210            _ => {
211                panic!("Incompatible types for adding.")
212            }
213        }
214    }
215}
216impl Div for Value {
217    type Output = Value;
218    fn div(self, rhs: Self) -> Self::Output {
219        match (self, rhs) {
220            (Value::F32(x), Value::F32(y)) => Value::F32(x / y),
221            (Value::F32(x), Value::F64(y)) => Value::F64(x as f64 / y),
222            (Value::F32(x), Value::I32(y)) => Value::F32(x / y as f32),
223            (Value::F32(x), Value::I64(y)) => Value::F64(x as f64 / y as f64),
224
225            (Value::F64(x), Value::F64(y)) => Value::F64(x / y),
226            (Value::F64(x), Value::F32(y)) => Value::F64(x / y as f64),
227            (Value::F64(x), Value::I32(y)) => Value::F64(x / y as f64),
228            (Value::F64(x), Value::I64(y)) => Value::F64(x / y as f64),
229
230            (Value::I32(x), Value::I32(y)) => Value::I32(x / y),
231            (Value::I32(x), Value::I64(y)) => Value::I64(x as i64 / y),
232            (Value::I32(x), Value::F32(y)) => Value::F32(x as f32 / y),
233            (Value::I32(x), Value::F64(y)) => Value::F64(x as f64 / y),
234
235            (Value::I64(x), Value::I64(y)) => Value::I64(x / y),
236            (Value::I64(x), Value::I32(y)) => Value::I64(x / y as i64),
237            (Value::I64(x), Value::F32(y)) => Value::F64(x as f64 / y as f64),
238            (Value::I64(x), Value::F64(y)) => Value::F64(x as f64 / y),
239
240            (Value::BYTE(x), Value::BYTE(y)) => Value::BYTE(x / y),
241            _ => {
242                panic!("Incompatible types for adding.")
243            }
244        }
245    }
246}
247impl From<isize> for Value {
248    fn from(value: isize) -> Self {
249        Value::I32(value as i32)
250    }
251}
252impl From<i64> for Value {
253    fn from(value: i64) -> Self {
254        Value::I64(value)
255    }
256}
257impl From<i32> for Value {
258    fn from(value: i32) -> Self {
259        Value::I32(value)
260    }
261}
262impl From<Value> for i32 {
263    fn from(value: Value) -> Self {
264        match value {
265            Value::I32(x) => x,
266            Value::I64(x) => x as i32,
267            _ => panic!("Must be an integer type!"),
268        }
269    }
270}
271impl Add<Value> for i64 {
272    type Output = i64;
273    fn add(self, rhs: Value) -> Self::Output {
274        match rhs {
275            Value::I32(x) => self + x as i64,
276            Value::I64(x) => self + x,
277            _ => panic!("Must be an integer type!"),
278        }
279    }
280}
281impl From<Value> for i64 {
282    fn from(value: Value) -> Self {
283        match value {
284            Value::I64(x) => x,
285            Value::I32(x) => x as i64,
286            _ => panic!("Must be an integer type!"),
287        }
288    }
289}
290impl From<bool> for Value {
291    fn from(value: bool) -> Self {
292        Value::BOOL(value)
293    }
294}
295
296pub fn transpile_to_rust(pairs: Pairs<'_, Rule>) -> TokenStream {
297    let mut result = TokenStream::new();
298    for pair in pairs {
299        match pair.as_rule() {
300            Rule::forloop => {
301                let mut inner = pair.into_inner();
302                let dummy = syn::parse_str::<syn::Ident>(inner.next().unwrap().as_str()).unwrap();
303                let iterator = transpile_to_rust(inner.next().unwrap().into_inner());
304                let expression = transpile_to_rust(inner.next().unwrap().into_inner());
305                result.extend(quote! {for #dummy in #iterator {#expression}});
306            }
307            Rule::range => {
308                let mut inner = pair.into_inner();
309                let min = syn::parse_str::<syn::Lit>(inner.next().unwrap().as_str()).unwrap();
310                let max = syn::parse_str::<syn::Lit>(inner.next().unwrap().as_str()).unwrap();
311                let step = inner.next();
312                if let Some(s) = step {
313                    let s_trans = transpile_to_rust(s.into_inner());
314                    result.extend(quote! {range_step(#min, #max, #s_trans)})
315                } else {
316                    result.extend(quote! {range(#min, #max)})
317                }
318            }
319            Rule::set => {
320                let mut inner = pair.into_inner();
321                let var = syn::parse_str::<syn::Ident>(inner.next().unwrap().as_str()).unwrap();
322                let val = transpile_to_rust(inner.next().unwrap().into_inner());
323                result.extend(quote! {#var = #val;});
324            }
325            Rule::fun => {
326                result.extend(parse_function(pair));
327            }
328            Rule::def => {
329                let mut inner = pair.into_inner();
330                let var_name =
331                    syn::parse_str::<syn::Ident>(inner.next().unwrap().as_str()).unwrap();
332                let var_def = transpile_to_rust(inner.next().unwrap().into_inner());
333                result.extend(quote! {let #var_name: Value = #var_def.into();});
334            }
335            Rule::defn => {
336                let mut inner = pair.into_inner();
337                let var_name =
338                    syn::parse_str::<syn::Ident>(inner.next().unwrap().as_str()).unwrap();
339                let mut params = Vec::new();
340                while inner.len() > 1 {
341                    let param = inner.next().unwrap();
342                    params.push(match param.as_rule() {
343                        Rule::symbol_type => parse_typed_identifier(param),
344                        Rule::symbol => {
345                            let symbol = syn::parse_str::<syn::Ident>(param.as_str())
346                                .expect("Invalid symbol");
347                            quote! {#symbol: Value}
348                        }
349                        _ => {
350                            panic!("Invalid function parameter")
351                        }
352                    });
353                }
354                let body = transpile_to_rust(inner.next().unwrap().into_inner());
355                let indices = 0..params.len();
356                result.extend(
357                    quote! {let #var_name = Value::FN(FnPtr(Arc::new(|args: &[Value]| {
358                         #(let #params = args[#indices].clone().into();)*
359                         (#body).into()
360                    })));},
361                );
362            }
363            Rule::tfun => {
364                let mut inner = pair.into_inner();
365                let mut params = Vec::new();
366                while inner.len() > 1 {
367                    let param = inner.next().unwrap();
368                    params.push(syn::parse_str::<syn::Ident>(param.as_str()).unwrap());
369                }
370                let body = transpile_to_rust(inner.next().unwrap().into_inner());
371                let indices = 0..params.len();
372                result.extend(quote! {Value::FN(FnPtr(Arc::new(|args: &[Value]| {
373                     #(let #params = args[#indices].clone().into();)*
374                     #body
375                })));});
376            }
377            Rule::tdef => {
378                let mut inner = pair.into_inner();
379                let var_name = syn::parse_str::<syn::Ident>(inner.next().unwrap().as_str())
380                    .expect("Invalid typed variable name");
381                let var_def = transpile_to_rust(inner.next().unwrap().into_inner());
382                result.extend(quote! {let #var_name = #var_def;});
383            }
384            Rule::tdefn => {
385                let mut inner = pair.into_inner();
386                let var_name = syn::parse_str::<syn::Ident>(
387                    inner.next().expect("Expected typed function name").as_str(),
388                )
389                .expect("Invalid typed function name");
390                let mut params = Vec::new();
391                while inner.len() > 1 {
392                    let param = inner.next().expect("Expected typed function parameter");
393                    params.push(parse_typed_identifier(param.clone()));
394                }
395                let body =
396                    transpile_to_rust(inner.next().expect("Error parsing body").into_inner());
397                let indices = 0..params.len();
398                result.extend(
399                    quote! {let #var_name = Value::FN(FnPtr(Arc::new(Box::new(|args: &[Value]| {
400                         #(let #params = args[#indices].clone().into();)*
401                         (#body).into()
402                    }))));},
403                );
404            }
405            Rule::ifb => {
406                let mut inner = pair.into_inner();
407                let cond = transpile_to_rust(inner.next().unwrap().into_inner());
408                let if_true = transpile_to_rust(inner.next().unwrap().into_inner());
409                let if_false = transpile_to_rust(inner.next().unwrap().into_inner());
410                result.extend(quote! {if #cond {#if_true} else {#if_false}});
411            }
412            Rule::opvar => {
413                let mut inner = pair.into_inner();
414                let operator = transpile_to_rust(inner.next().unwrap().into_inner());
415                let mut operands = Vec::new();
416                for pair in inner {
417                    operands.push(transpile_to_rust(pair.into_inner()));
418                }
419                let first_operand = operands.first().unwrap();
420                result.extend(quote! {#first_operand});
421                for op in operands.iter().skip(1) {
422                    result.extend(quote! {#operator #op});
423                }
424            }
425            Rule::fnvar => {
426                let mut inner = pair.into_inner();
427                let fn_sym =
428                    syn::parse_str::<syn::Ident>(inner.next().unwrap().as_span().as_str()).unwrap();
429                let mut args = Vec::new();
430                for pair in inner {
431                    args.push(transpile_to_rust(pair.into_inner()))
432                }
433                result.extend(quote! {#fn_sym.call(&[#(#args.into()),*])});
434            }
435            Rule::list => {
436                let inner = pair.into_inner();
437                let transpiled = transpile_to_rust(inner);
438                result.extend(quote! {{#transpiled}});
439            }
440            Rule::symbol => {
441                println!("{}", pair.as_str());
442                let inner = syn::parse_str::<syn::Ident>(pair.as_str()).expect("Invalid symbol");
443                result.extend(quote! {#inner});
444            }
445            Rule::add => {
446                result.extend(quote! {+});
447            }
448            Rule::sub => {
449                result.extend(quote! {-});
450            }
451            Rule::mul => {
452                result.extend(quote! {*});
453            }
454            Rule::div => {
455                result.extend(quote! {/});
456            }
457            Rule::less => {
458                result.extend(quote! {<});
459            }
460            Rule::more => {
461                result.extend(quote! {>});
462            }
463            Rule::equal => {
464                result.extend(quote! {==});
465            }
466            Rule::number => {
467                let inner = syn::parse_str::<syn::Lit>(pair.as_str()).unwrap();
468                result.extend(quote! {Value::from(#inner)});
469            }
470            Rule::boolean => {
471                let inner = syn::parse_str::<syn::LitBool>(pair.as_str()).unwrap();
472                result.extend(quote! {Value::from(#inner)});
473            }
474            Rule::EOI => return result,
475            _ => {
476                let inner = pair.into_inner();
477                result.extend(transpile_to_rust(inner));
478            }
479        }
480    }
481    result
482}
483
484fn parse_function(pair: Pair<'_, Rule>) -> TokenStream {
485    let mut inner = pair.into_inner();
486    let mut params = Vec::new();
487    while inner.len() > 1 {
488        let param = inner.next().unwrap();
489        params.push(match param.as_rule() {
490            Rule::symbol_type => parse_typed_identifier(param),
491            Rule::symbol => {
492                let symbol = syn::parse_str::<syn::Ident>(param.as_str()).expect("Invalid symbol");
493                quote! {#symbol: Value}
494            }
495            _ => {
496                panic!("Invalid function parameter")
497            }
498        });
499    }
500    let body = transpile_to_rust(inner.next().unwrap().into_inner());
501    let indices = 0..params.len();
502    quote! {Value::FN(FnPtr(Arc::new(|args: &[Value]| {
503        #(let #params = args[#indices].clone().into();)*
504        #body
505    })));}
506}
507
508fn parse_typed_identifier(ident: Pair<'_, Rule>) -> TokenStream {
509    let mut inner = ident.into_inner();
510    let symbol =
511        syn::parse_str::<syn::Ident>(inner.next().expect("Expected typed symbol").as_str())
512            .expect("Could not parse typed symbol");
513    let t = inner.next().expect("Expected type").as_str();
514    let t_token = match t {
515        "STR" => {
516            quote! {String}
517        }
518        "F32" => {
519            quote! {f32}
520        }
521        "F64" => {
522            quote! {f64}
523        }
524        "I32" => {
525            quote! {i32}
526        }
527        "I64" => {
528            quote! {i64}
529        }
530        "BOOL" => {
531            quote! {bool}
532        }
533        "LIST" => {
534            quote! {Vec<Value>}
535        }
536        "FN" => {
537            quote! {Box<dyn Fn(&[Value]) -> Value>}
538        }
539        _ => quote! { #t },
540    };
541    quote! {#symbol: #t_token}
542}