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}