c_a_l/
x.rs

1use crate::{btoi, drop, drop_end, macros::*, p::Node, take, take_end};
2use colored::Colorize;
3use rand::Rng;
4use std::{ascii, borrow::Cow, cmp, fs, iter::zip};
5
6/*
7 * various err type macros
8 */
9
10macro_rules! err_nyi {
11    ($($t:tt)*) => {{
12        err_fmt!("{}\n{}", "'nyi".purple(), format!($($t)*))
13    }};
14}
15
16macro_rules! err_domain {
17    ($($t:tt)*) => {{
18        err_fmt!("{}\n{}", "'domain".yellow(), format!($($t)*))
19    }};
20}
21
22macro_rules! err_io {
23    ($($t:tt)*) => {{
24        err_fmt!("{}\n{}", "'io".green(), format!($($t)*))
25    }};
26}
27
28/** the result of an eval() function */
29type EvalResult<'a, T> = Result<(T, Cow<'a, State>), String>;
30type OkNode<'a> = EvalResult<'a, Node>;
31
32#[derive(Debug, Clone)]
33pub struct State {
34    vars: Vec<(Node, Node)>,
35}
36
37impl State {
38    pub fn new() -> Self {
39        Self { vars: Vec::new() }
40    }
41
42    pub fn with(x: Vec<(Node, Node)>) -> Self {
43        Self { vars: x }
44    }
45
46    pub fn with_var<'a>(&self, x: Cow<'static, str>, y: Node) -> Cow<'a, Self> {
47        let mut v = self.vars.clone();
48        v.push((Node::X(x), y));
49
50        Cow::Owned(State::with(v))
51    }
52
53    pub fn with_vars<'a>(
54        &self,
55        x: Vec<(Cow<'static, str>, Node)>,
56    ) -> Cow<'a, Self> {
57        let mut v = self.vars.clone();
58
59        for (x, y) in x.into_iter() {
60            v.push((Node::X(x), y));
61        }
62
63        Cow::Owned(State::with(v))
64    }
65
66    pub fn with_verb<'a>(&self, x: Node, y: Node) -> Cow<'a, Self> {
67        let mut v = self.vars.clone();
68        v.push((x, y));
69
70        Cow::Owned(State::with(v))
71    }
72
73    pub fn get_bind(&self, x: &Node) -> Option<Node> {
74        for (k, v) in self.vars.iter().rev() {
75            if x == k {
76                return Some(v.clone());
77            }
78        }
79
80        None
81    }
82
83    pub fn with_bind<'a>(&self, x: Node, y: Node) -> Cow<'a, Self> {
84        let mut v = self.vars.clone();
85        v.push((x, y));
86
87        Cow::Owned(State::with(v))
88    }
89
90    pub fn has_fn(&self, f: &str) -> bool {
91        for (x, _) in self.vars.iter() {
92            if x == &(Node::M {
93                verb: f.to_string().into(),
94                rhs: None,
95            }) {
96                return true;
97            }
98        }
99        false
100    }
101
102    pub fn get_fn<T>(&self, f: T) -> Option<Node>
103    where
104        String: From<T>,
105    {
106        let f = &String::from(f);
107        for (k, v) in self.vars.iter().rev() {
108            if &(Node::M {
109                verb: f.to_string().into(),
110                rhs: None,
111            }) == k
112            {
113                return Some(v.clone());
114            }
115        }
116        None
117    }
118}
119
120macro_rules! mk_ok {
121    ($a:ident, $x:ty, $n:path) => {
122        fn $a<'a>(x: $x, s: Cow<'a, State>) -> OkNode<'a> {
123            Ok(($n(x), s))
124        }
125    };
126}
127
128mk_ok!(ok_i, i64, Node::I);
129mk_ok!(ok_f, f64, Node::F);
130mk_ok!(ok_c, char, Node::C);
131mk_ok!(ok_a, Vec<Node>, Node::A);
132mk_ok!(ok_s, Box<Node>, Node::S);
133
134fn is_homogenous(x: &[Node]) -> bool {
135    if x.len() > 0 {
136        let t = node_type(&x[0]);
137        x.iter().all(|x| t == node_type(&x))
138    } else {
139        false
140    }
141}
142
143fn node_type(x: &Node) -> String {
144    match x {
145        Node::I(_) => "i".to_string(),
146        Node::F(_) => "f".to_string(),
147        Node::C(_) => "c".to_string(),
148        Node::A(x) => {
149            if is_homogenous(&x) {
150                node_type(&x[0]).to_uppercase()
151            } else {
152                "A".to_string()
153            }
154        }
155        Node::S(_) => "s".to_string(),
156        Node::O(_) => "o".to_string(),
157        Node::P(_) => "p".to_string(),
158        Node::T(_) => "t".to_string(),
159        Node::X(_) => "x".to_string(),
160        Node::D { .. } => "d".to_string(),
161        Node::M { .. } => "m".to_string(),
162    }
163}
164
165pub fn eval_each<'a>(
166    x: &[Node],
167    s: Cow<'a, State>,
168) -> EvalResult<'a, Vec<Node>> {
169    let mut r = Vec::new();
170    let mut s = s;
171
172    for i in x.iter() {
173        let (c, _s) = eval(i, s)?;
174        s = _s;
175        r.push(c);
176    }
177
178    Ok((r, s))
179}
180
181#[allow(unreachable_patterns)]
182pub fn eval<'a>(x: &Node, s: Cow<'a, State>) -> EvalResult<'a, Node> {
183    match x {
184        x @ (Node::I(_)
185        | Node::F(_)
186        | Node::C(_)
187        | Node::O(_)
188        | Node::T(_)
189        | Node::S(_)
190        | Node::D {
191            verb: _,
192            lhs: _,
193            rhs: None,
194        }
195        | Node::M { verb: _, rhs: None }) => Ok((x.clone(), s)),
196
197        Node::A(x) => {
198            let mut v = Vec::new();
199            let mut _s = s.clone();
200            #[allow(unused_assignments)]
201            let mut p = Node::empty();
202
203            for i in x.iter() {
204                (p, _s) = eval(i, _s)?;
205                v.push(p);
206            }
207
208            ok_a(v, s)
209        }
210
211        /* get a var */
212        x @ Node::X(xs) => match s.get_bind(&x) {
213            Some(v) => Ok((v, s)),
214            None => err_fmt!("'value\n {xs} is not defined"),
215        },
216
217        /* progn */
218        Node::P(x) => Ok((
219            {
220                let (x, _) = eval_each(x, s.clone())?;
221                match x.into_iter().last() {
222                    Some(x) => x,
223                    None => Node::empty(),
224                }
225            },
226            s,
227        )),
228
229        Node::M {
230            verb: v,
231            rhs: Some(x),
232        } => {
233            let (x, s) = eval(&*x, s)?;
234            match (&**v, x) {
235                /* iota */
236                ("!", Node::I(x)) => ok_a(
237                    (/* either 0->x or x->0 */if x > 0 { 0..x } else { x..0 })
238                        .map(|x| Node::I(x))
239                        .collect(),
240                    s,
241                ),
242                /* negate */
243                ("-", Node::I(x)) => ok_i(-x, s),
244                ("-", Node::F(x)) => ok_f(-x, s),
245                /* floor */
246                ("_", Node::I(x)) => ok_i(x, s),
247                ("_", Node::F(x)) => ok_i(x.floor() as i64, s),
248                /* enlist */
249                (",", x) => ok_a(vec![x], s),
250                /* fmt */
251                ("$", x) => Ok((Node::from_str(format!("{x}")), s)),
252                /* head */
253                ("*", Node::A(x)) => match x.into_iter().nth(0) {
254                    Some(x) => Ok((x, s)),
255                    None => ok_a(Vec::new(), s),
256                },
257                ("*", x) => Ok((x, s)),
258                /* tail */
259                ("%", Node::A(x)) => ok_a(drop(x, 1), s),
260                ("%", x) => Ok((x, s)),
261                /* len */
262                ("#", Node::A(x)) => ok_i(x.len() as i64, s),
263                ("#", _) => ok_i(1, s),
264                /* reverse */
265                ("|", Node::A(x)) => ok_a(x.into_iter().rev().collect(), s),
266                /* not */
267                ("~", Node::I(0)) => ok_i(1, s),
268                ("~", Node::I(1)) => ok_i(0, s),
269                ("~", Node::I(x)) => {
270                    err_nyi!(
271                        "not must be applied to 1 or 0\n -> {}",
272                        format!("~{x}").blue()
273                    )
274                }
275                /* type */
276                ("@", x) => ok_s(Box::new(Node::X(node_type(&x).into())), s),
277                /* println */
278                ("<<", x @ Node::A(_)) if x.is_str() => {
279                    println!("{}", x.un_str());
280                    Ok((Node::empty(), s))
281                }
282                ("<", x @ Node::A(_)) if x.is_str() => {
283                    puts!("{}", x.un_str());
284                    Ok((Node::empty(), s))
285                }
286                /* eprintln */
287                ("<<!", x @ Node::A(_)) if x.is_str() => {
288                    eprintln!("{}", x.un_str());
289                    Ok((Node::empty(), s))
290                }
291                ("<!", x @ Node::A(_)) if x.is_str() => {
292                    eputs!("{}", x.un_str());
293                    Ok((Node::empty(), s))
294                }
295                /* read file */
296                (">>", x @ Node::A(_)) if x.is_str() => {
297                    let f = x.un_str();
298                    match fs::read_to_string(f) {
299                        Ok(x) => Ok((Node::from_str(x), s)),
300                        Err(e) => err_io!("failed to read file to string: {e}"),
301                    }
302                }
303                /* user defined monads */
304                (v, x) if s.has_fn(v) => {
305                    let f = s
306                        .get_fn(v)
307                        .expect("unreachable: state has fn but can't get_fn()");
308                    eval(&Node::dyad(".", f, x), s)
309                }
310                (v, x) => {
311                    let t = node_type(&x);
312                    err_fmt!(
313                        "'nyi\nmonadic {v}{t} is not yet implemented\n -> {}",
314                        format!("{v}{x}").blue()
315                    )
316                }
317            }
318        }
319
320        Node::D {
321            verb: v,
322            lhs: x,
323            rhs: Some(y),
324        } => {
325            /* gets needs to be evaluated separately so the lhs isn't eval'd */
326            match &**v {
327                ":" => {
328                    let (y, s) = eval(&*y, s)?;
329                    return match (*x.clone(), y) {
330                        (Node::X(x), y) => Ok((y.clone(), (*s).with_var(x, y))),
331                        (x @ Node::M { verb: _, rhs: None }, y) => {
332                            Ok((y.clone(), (*s).with_verb(x, y)))
333                        }
334                        (x, y) => err_nyi!(
335                            "{x} gets {y} is not yet implemented\n -> {}",
336                            format!("{x}:{y}").blue()
337                        ),
338                    };
339                }
340                "::" => {
341                    let (y, s) = eval(&*y, s)?;
342                    return match (*x.clone(), y) {
343                        (Node::A(x), y) if x[0].is_x() && x[1].is_i() => {
344                            let i = x[1].un_i();
345                            let b = &x[0];
346                            let a = s.get_bind(b);
347
348                            match a {
349                                Some(Node::A(mut v)) => {
350                                    v[i as usize] = y;
351                                    let s = (*s).with_bind(
352                                        b.clone(),
353                                        Node::A(v.clone()),
354                                    );
355                                    ok_a(v, s)
356                                }
357                                Some(a) => err_nyi!(
358                                    "can only mend arrays, not {a}\n -> {}",
359                                    format!("{}::{y}", Node::A(x)).blue()
360                                ),
361                                None => err_nyi!("bind {} not found", x[0]),
362                            }
363                        }
364                        (x, y) => err_nyi!(
365                            "{x} mend {y} is not yet implemented\n -> {}",
366                            format!("{x}::{y}").blue()
367                        ),
368                    };
369                }
370                _ => {}
371            };
372
373            let (y, s) = eval(&*y, s)?;
374            let (x, s) = eval(&*x, s)?;
375            match (&**v, x, y) {
376                /* math */
377                ("+", Node::I(x), Node::I(y)) => ok_i(x + y, s),
378                ("-", Node::I(x), Node::I(y)) => ok_i(x - y, s),
379                ("*", Node::I(x), Node::I(y)) => ok_i(x * y, s),
380                ("%", Node::I(x), Node::I(y)) => ok_f(x as f64 / y as f64, s),
381                ("<", Node::I(x), Node::I(y)) => ok_i(btoi(x < y), s),
382                (">", Node::I(x), Node::I(y)) => ok_i(btoi(x > y), s),
383                ("&", Node::I(x), Node::I(y)) => ok_i(cmp::min(x, y), s),
384                ("|", Node::I(x), Node::I(y)) => ok_i(cmp::max(x, y), s),
385                ("^", Node::I(x), Node::I(y)) => {
386                    ok_f((x as f64).powf(y as f64), s)
387                }
388                ("!", Node::I(x), Node::I(y)) => ok_i(y % x, s),
389                /* some verbs are atomic */
390                (
391                    v @ ("+" | "-" | "*" | "%" | "<" | ">" | "&" | "|" | "^"
392                    | "!"),
393                    x,
394                    Node::A(y),
395                ) => {
396                    let mut r = Vec::new();
397                    let mut s = s;
398                    for i in y.into_iter() {
399                        let (c, _s) = eval(&Node::dyad(v, x.clone(), i), s)?;
400                        s = _s;
401                        r.push(c);
402                    }
403                    ok_a(r, s)
404                }
405                /* match */
406                ("~", x, y) => ok_i(btoi(x == y), s),
407                /* random */
408                ("?", Node::I(x), Node::I(y)) => {
409                    ok_i(rand::thread_rng().gen_range(x..y + 1), s)
410                }
411                ("$", Node::S(x), y) => match (*x, y) {
412                    (Node::X(x), Node::I(y)) if &*x == "c" => {
413                        match ascii::Char::from_u8(y as u8) {
414                            Some(c) => ok_c(c.into(), s),
415                            None => err_fmt!("cannot cast {y} to char"),
416                        }
417                    }
418                    (x, y) => err_fmt!("cannot cast {y} to `{x}"),
419                },
420                /* join */
421                (",", Node::A(mut x), Node::A(mut y)) => ok_a(
422                    {
423                        x.append(&mut y);
424                        x.clone()
425                    },
426                    s,
427                ),
428                (",", Node::A(mut x), y) => ok_a(
429                    {
430                        x.push(y);
431                        x.clone()
432                    },
433                    s,
434                ),
435                (",", x, Node::A(mut y)) => ok_a(
436                    {
437                        y.insert(0, x);
438                        y.clone()
439                    },
440                    s,
441                ),
442                (",", x, y) => ok_a(vec![x, y], s),
443                /* join strings */
444                ("/", x @ Node::A(_), Node::A(y))
445                    if (x.is_str() || x.is_c())
446                        && y.iter().all(|x| x.is_str()) =>
447                {
448                    let i = x.un_str();
449                    Ok((
450                        Node::from_str(
451                            y.into_iter()
452                                .map(|x| x.un_str())
453                                .collect::<Vec<_>>()
454                                .join(&i),
455                        ),
456                        s,
457                    ))
458                }
459                /* cols */
460                ("|||", Node::I(x), Node::A(mut y)) => {
461                    let mut r = Vec::new();
462                    loop {
463                        if y.len() > x as usize {
464                            let h = take(&mut y, x);
465                            r.push(Node::A(h));
466                        } else {
467                            r.push(Node::A(y));
468                            break;
469                        }
470                    }
471                    ok_a(r, s)
472                }
473                /* find */
474                ("?", x, Node::A(y)) => ok_i(
475                    match y.into_iter().position(|i| x == i) {
476                        Some(x) => x as i64,
477                        None => -1,
478                    },
479                    s,
480                ),
481                /* take */
482                ("#", Node::I(n), Node::A(mut v)) => ok_a(take(&mut v, n), s),
483                ("#", Node::A(mut v), Node::I(n)) => {
484                    ok_a(take_end(&mut v, n), s)
485                }
486                /* drop */
487                ("_", Node::I(n), Node::A(v)) => ok_a(drop(v, n), s),
488                ("_", Node::A(mut v), Node::I(n)) => {
489                    ok_a(drop_end(&mut v, n), s)
490                }
491                ("_", Node::M { verb: x, rhs: None }, Node::A(y)) => ok_a(
492                    {
493                        let mut v = Vec::new();
494                        for i in y.into_iter() {
495                            if let (Node::I(1), _) =
496                                eval(&Node::monad(&*x, i.clone()), s.clone())?
497                            {
498                                v.push(i);
499                            }
500                        }
501                        v
502                    },
503                    s,
504                ),
505                /* each */
506                /* TODO: eval_each but don't save state */
507                ("'", x, Node::A(y)) => {
508                    let (e, _) = eval_each(
509                        &y.into_iter()
510                            .map(|i| match node_type(&i).as_str() {
511                                t if t.chars().all(|x| x.is_ascii_uppercase()) => {
512                                    Node::dyad(".", x.clone(), Node::monad(",", i))
513                                }
514                                _ => Node::dyad(".", x.clone(), i),
515                            })
516                            .collect::<Vec<_>>(),
517                        s.clone(),
518                    )?;
519                    ok_a(e, s)
520                }
521                /* apply n */
522                (".", ref wx @ Node::A(ref x), wy @ Node::I(y)) => {
523                    match x.iter().nth(y as usize) {
524                        Some(x) => Ok((x.clone(), s)),
525                        None => {
526                            err_domain!(" -> {}", format!("{wx} . {wy}").blue())
527                        }
528                    }
529                }
530                (".", Node::A(x), Node::A(y)) if y.iter().all(|x| x.is_i()) => {
531                    let mut v = Vec::new();
532                    for i in y.into_iter() {
533                        v.push(x[i.un_i() as usize].clone());
534                    }
535                    ok_a(v, s)
536                }
537                (".", Node::M { verb: v, rhs: None }, Node::A(y)) => {
538                    if y.len() == 2 {
539                        eval(&Node::dyad(&*v, y[0].clone(), y[1].clone()), s)
540                    } else {
541                        err_nyi!(" -> {v}{}", Node::A(y))
542                    }
543                }
544                (".", Node::M { verb: v, rhs: None }, y) => {
545                    eval(&Node::monad(&*v, y), s)
546                }
547                (
548                    ".",
549                    Node::D {
550                        verb: v,
551                        lhs,
552                        rhs: None,
553                    },
554                    y,
555                ) => eval(&Node::dyad(&*v, *lhs, y), s),
556                (".", Node::O(x), Node::A(y)) => {
557                    let mut v: Vec<_> = ["x", "y", "z"]
558                        .into_iter()
559                        .map(|x| Cow::from(x))
560                        .collect();
561                    let v = take(&mut v, y.len() as i64);
562                    let (e, _) = eval_each(
563                        &x,
564                        s.with_vars(zip(v, y).collect::<Vec<_>>()),
565                    )?;
566                    match e.into_iter().last() {
567                        Some(x) => Ok((x, s)),
568                        None => Ok((Node::empty(), s)),
569                    }
570                }
571                (".", Node::O(x), y) => {
572                    eval(&Node::dyad(".", Node::O(x), Node::A(vec![y])), s)
573                }
574                /* user defined dyads */
575                (v, x, y) if s.has_fn(v) => {
576                    let f = s.get_fn(v).expect(
577                        "unreachable: state has fn but not found by get_fn()",
578                    );
579                    eval(&Node::dyad(".", f, Node::A(vec![x, y])), s)
580                }
581                (v, x, y) => {
582                    let xt = node_type(&x);
583                    let yt = node_type(&y);
584                    err_nyi!(
585                        "dyadic {xt}{v}{yt} is not yet implemented\n -> {}",
586                        format!("{x}{v}{y}").blue()
587                    )
588                }
589            }
590        }
591
592        _ => err_nyi!(" -> {x}"),
593    }
594}
595
596#[cfg(test)]
597mod tests {
598    use crate::{
599        p::{parse, Node},
600        x::{eval, eval_each, State},
601    };
602    use std::borrow::Cow;
603
604    fn exec(x: &Node) -> Result<Node, String> {
605        let (r, _) = eval(x, Cow::Owned(State::new()))?;
606        Ok(r)
607    }
608
609    #[test]
610    fn eval_one() {
611        assert_eq!(exec(&Node::I(1)).unwrap(), Node::I(1));
612    }
613
614    #[test]
615    fn monads() {
616        for (x, y) in [
617            (
618                "!4",
619                Node::A([0, 1, 2, 3].iter().map(|x| Node::I(*x)).collect()),
620            ),
621            ("-1", Node::I(-1)),
622            (
623                "! -4",
624                Node::A([4, 3, 2, 1].iter().map(|x| Node::I(-*x)).collect()),
625            ),
626            ("_1", Node::I(1)),
627            ("_1.0", Node::I(1)),
628            ("* !10", Node::I(0)),
629            ("# !10", Node::I(10)),
630            (
631                "| !3",
632                Node::A([2, 1, 0].iter().map(|x| Node::I(*x)).collect()),
633            ),
634            ("~1", Node::I(0)),
635            ("~0", Node::I(1)),
636            (",1", Node::A(vec![Node::I(1)])),
637            (
638                "% !3",
639                Node::A([1, 2].iter().map(|x| Node::I(*x)).collect()),
640            ),
641        ]
642        .into_iter()
643        {
644            assert_eq!(exec(&parse(x).unwrap()[0].clone()).unwrap(), y);
645        }
646    }
647
648    #[test]
649    fn dyads() {
650        let abc = Node::A("abc".chars().map(|x| Node::C(x)).collect());
651
652        for (x, y) in [
653            ("1+1", Node::I(2)),
654            (
655                "1+ !3",
656                Node::A([1, 2, 3].iter().map(|x| Node::I(*x)).collect()),
657            ),
658            (
659                "2% 1+ !2",
660                Node::A([2, 1].iter().map(|x| Node::F(*x as f64)).collect()),
661            ),
662            ("1-1", Node::I(0)),
663            ("4*3", Node::I(12)),
664            ("10%2", Node::F(5.0)),
665            (r#""ab","c""#, abc.clone()),
666            (r#""a","bc""#, abc.clone()),
667            (r#""a","b","c""#, abc.clone()),
668            ("1|0&1", Node::I(1)),
669            ("5<1>2", Node::I(0)),
670            (
671                "3||| !9",
672                Node::A(
673                    [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
674                        .iter()
675                        .map(|x| {
676                            Node::A(x.iter().map(|x| Node::I(*x)).collect())
677                        })
678                        .collect(),
679                ),
680            ),
681            ("(!10) . 2", Node::I(2)),
682            ("(+) . (1;2)", Node::I(3)),
683            (
684                "(~)_(1;0;1;0;1;0)",
685                Node::A([0, 0, 0].iter().map(|x| Node::I(*x)).collect()),
686            ),
687            ("{x+1} . ,1", Node::I(2)),
688            ("{x+y}.(1;2)", Node::I(3)),
689            (
690                "{x+1}' !3",
691                Node::A([1, 2, 3].iter().map(|x| Node::I(*x)).collect()),
692            ),
693            ("{x+y+z}.1+ !4", Node::I(6)),
694            ("{a:x;a+1}. ,1", Node::I(2)),
695            (
696                "(1+)'(1;2)",
697                Node::A([2, 3].iter().map(|x| Node::I(*x)).collect()),
698            ),
699            (
700                "{1+ !x}' 1+ !3",
701                Node::A(
702                    [0, 1, 2]
703                        .iter()
704                        .map(|x| {
705                            Node::A((0..1+*x).map(|x| Node::I(1 + x)).collect())
706                        })
707                        .collect(),
708                ),
709            ),
710            (
711                "{$x}'\"abc\"",
712                Node::A(
713                    "abc"
714                        .chars()
715                        .map(|x| Node::from_str(format!("\"{x}\"")))
716                        .collect(),
717                ),
718            ),
719            (
720                r#"{$x}'("abc";"def")"#,
721                Node::A(
722                    ["abc", "def"]
723                        .iter()
724                        .map(|x| Node::from_str(format!("\"{x}\"")))
725                        .collect(),
726                ),
727            ),
728            ("a+a:1", Node::I(2)),
729            (
730                r#""abcdefghijklmnopqrstuvwxyz"[0;2;4;6]"#,
731                Node::A("aceg".chars().map(|x| Node::C(x)).collect()),
732            ),
733        ]
734        .into_iter()
735        {
736            assert_eq!(
737                exec(&parse(x).unwrap().last().unwrap().clone()).unwrap(),
738                y
739            );
740        }
741    }
742
743    /* wow */
744    #[test]
745    fn state() {
746        assert_eq!(
747            {
748                let (x, s) = eval_each(
749                    &parse("a:1;a+1").unwrap(),
750                    Cow::Owned(State::new()),
751                )
752                .unwrap();
753                assert_eq!(
754                    s.vars,
755                    vec![(Node::X(Cow::Borrowed("a")), Node::I(1))]
756                );
757                x
758            },
759            vec![Node::I(1), Node::I(2)]
760        );
761    }
762
763    #[test]
764    fn progn() {
765        for (x, y) in
766            [("[1;2;3]", Node::I(3)), ("[a:1;a+1]", Node::I(2))].into_iter()
767        {
768            assert_eq!(
769                eval_each(&parse(x).unwrap(), Cow::Owned(State::new()))
770                    .unwrap()
771                    .0
772                    .into_iter()
773                    .last()
774                    .unwrap(),
775                y
776            );
777        }
778    }
779
780    #[test]
781    fn def_verb() {
782        for (x, y) in [
783            ("(++):{x+y};1++1", Node::I(2)),
784            ("(++):(-);++1", Node::I(-1)),
785            (
786                "(!):{-x};!3",
787                Node::A([0, 1, 2].iter().map(|x| Node::I(*x)).collect()),
788            ),
789        ]
790        .into_iter()
791        {
792            assert_eq!(
793                eval_each(&parse(x).unwrap(), Cow::Owned(State::new()))
794                    .unwrap()
795                    .0
796                    .into_iter()
797                    .last()
798                    .unwrap(),
799                y
800            );
801        }
802    }
803}