garnish_lang_simple_data/
lib.rs

1use std::collections::hash_map::DefaultHasher;
2use std::fmt::{Debug, Display, Formatter};
3use std::hash::Hash;
4use std::{collections::HashMap, hash::Hasher};
5
6pub use error::DataError;
7use garnish_lang_traits::helpers::iterate_concatenation_mut;
8use garnish_lang_traits::{GarnishData, GarnishDataType, Instruction};
9
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12
13mod clone;
14mod data;
15mod error;
16mod instruction;
17mod runtime;
18
19pub use data::*;
20pub use instruction::SimpleInstruction;
21
22/// Utility to convert strings to [`u64`], the Symbol type for [`SimpleGarnishData`].
23pub fn symbol_value(value: &str) -> u64 {
24    let mut h = DefaultHasher::new();
25    value.hash(&mut h);
26    let hv = h.finish();
27
28    hv
29}
30
31/// Default custom type for [`SimpleGarnishData`] when no custom types are needed.
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Debug, Hash)]
34pub struct NoCustom {}
35
36impl Display for NoCustom {
37    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
38        f.write_str("NoCustom")
39    }
40}
41
42impl DisplayForCustomItem for NoCustom {
43    fn display_with_list(&self, _list: &SimpleDataList, _level: usize) -> String {
44        format!("{}", self)
45    }
46}
47
48/// Implementation of [`GarnishData`]. Uses standard Rust collections for storing data.
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50#[derive(Debug, Clone)]
51pub struct SimpleGarnishData<T = NoCustom>
52where
53    T: Clone + PartialEq + Eq + PartialOrd + Debug + Hash,
54{
55    register: Vec<usize>,
56    data: SimpleDataList<T>,
57    end_of_constant_data: usize,
58    values: Vec<usize>,
59    instructions: Vec<SimpleInstruction>,
60    instruction_cursor: usize,
61    expression_table: Vec<usize>,
62    current_list: Option<(Vec<usize>, Vec<usize>)>,
63    current_char_list: Option<String>,
64    current_byte_list: Option<Vec<u8>>,
65    cache: HashMap<u64, usize>,
66    max_char_list_depth: usize,
67}
68
69/// Alias for [`SimpleGarnishData`] with [`NoCustom`] type parameter.
70pub type SimpleDataRuntimeNC = SimpleGarnishData<NoCustom>;
71
72impl SimpleGarnishData<NoCustom> {
73    pub fn new() -> Self {
74        SimpleGarnishData {
75            register: vec![],
76            data: SimpleDataList::default(),
77            end_of_constant_data: 0,
78            values: vec![],
79            instruction_cursor: 0,
80            instructions: vec![],
81            expression_table: vec![],
82            current_list: None,
83            current_char_list: None,
84            current_byte_list: None,
85            cache: HashMap::new(),
86            max_char_list_depth: 1000,
87        }
88    }
89}
90
91impl<T> SimpleGarnishData<T>
92where
93    T: Clone + PartialEq + Eq + PartialOrd + Debug + Hash,
94{
95    pub fn new_custom() -> Self {
96        SimpleGarnishData {
97            register: vec![],
98            data: SimpleDataList::<T>::default(),
99            end_of_constant_data: 0,
100            values: vec![],
101            instruction_cursor: 0,
102            instructions: vec![],
103            expression_table: vec![],
104            current_list: None,
105            current_char_list: None,
106            current_byte_list: None,
107            cache: HashMap::new(),
108            max_char_list_depth: 1000,
109        }
110    }
111
112    pub(crate) fn get(&self, index: usize) -> Result<&SimpleData<T>, DataError> {
113        match self.data.get(index) {
114            None => Err(format!("No data at addr {:?}", index))?,
115            Some(d) => Ok(d),
116        }
117    }
118
119    pub fn add_custom(&mut self, data: T) -> Result<usize, DataError> {
120        self.data.push(SimpleData::Custom(data));
121        Ok(self.data.len() - 1)
122    }
123
124    pub fn add_stack_frame(&mut self, frame: SimpleStackFrame) -> Result<usize, DataError> {
125        self.data.push(SimpleData::StackFrame(frame));
126        Ok(self.data.len() - 1)
127    }
128
129    pub fn get_custom(&self, addr: usize) -> Result<T, DataError> {
130        self.get(addr)?.as_custom()
131    }
132
133    pub fn get_symbols(&self) -> &HashMap<u64, String> {
134        self.data.symbol_to_name()
135    }
136
137    pub fn get_registers(&self) -> &Vec<usize> {
138        &self.register
139    }
140
141    pub fn get_jump_points(&self) -> &Vec<usize> {
142        &self.expression_table
143    }
144
145    pub fn get_instructions(&self) -> &Vec<SimpleInstruction> {
146        &self.instructions
147    }
148
149    pub fn get_data(&self) -> &SimpleDataList<T> {
150        &self.data
151    }
152
153    pub fn get_data_mut(&mut self) -> &mut SimpleDataList<T> {
154        &mut self.data
155    }
156
157    pub fn get_raw_data(&self, index: usize) -> Option<SimpleData<T>> {
158        self.data.get(index).cloned()
159    }
160
161    pub fn set_end_of_constant(&mut self, addr: usize) -> Result<(), DataError> {
162        if addr >= self.data.len() {
163            Err(DataError::from("Cannot set end of constant data to be over current data amount".to_string()))
164        } else {
165            self.end_of_constant_data = addr;
166            Ok(())
167        }
168    }
169
170    pub fn get_end_of_constant_data(&self) -> usize {
171        self.end_of_constant_data
172    }
173
174    pub fn get_current_instruction(&self) -> Option<(Instruction, Option<usize>)> {
175        self.get_instruction(self.get_instruction_cursor())
176    }
177
178    pub fn advance_instruction_cursor(&mut self) -> Result<(), String> {
179        self.instruction_cursor += 1;
180        Ok(())
181    }
182
183    pub fn display_current_value(&self) -> String
184    where
185        T: Display + DisplayForCustomItem,
186    {
187        self.values.last().and_then(|l| Some(self.data.display_for_item(*l))).unwrap_or("<NoData>".to_string())
188    }
189
190    pub fn collect_concatenation_indices(&self, left: usize, right: usize) -> Vec<usize> {
191        let mut items = vec![];
192        let mut con_stack = vec![right, left];
193
194        while let Some(item) = con_stack.pop() {
195            match self.get_data().get(item) {
196                None => items.push(UNIT_INDEX),
197                Some(SimpleData::Concatenation(left, right)) => {
198                    con_stack.push(right.clone());
199                    con_stack.push(left.clone());
200                }
201                Some(SimpleData::List(list_items, _)) => {
202                    for item in list_items {
203                        items.push(item.clone());
204                    }
205                }
206                Some(SimpleData::Slice(list, range)) => match (self.get_data().get(*list), self.get_data().get(*range)) {
207                    (Some(SimpleData::List(_, _)), Some(SimpleData::Range(_, _))) => {
208                        let iter = self.get_list_slice_item_iter(item);
209
210                        for item in iter {
211                            items.push(item.clone());
212                        }
213                    }
214                    (Some(SimpleData::Concatenation(left, right)), Some(SimpleData::Range(start, end))) => match (self.get_data().get(*start), self.get_data().get(*end)) {
215                        (Some(SimpleData::Number(SimpleNumber::Integer(start))), Some(SimpleData::Number(SimpleNumber::Integer(end)))) => {
216                            let mut nested_con_stack = vec![*right, *left];
217                            let mut top_level_con_items = vec![];
218
219                            while let Some(item) = nested_con_stack.pop() {
220                                match self.get_data().get(item) {
221                                    None => items.push(UNIT_INDEX),
222                                    Some(SimpleData::Concatenation(left, right)) => {
223                                        nested_con_stack.push(right.clone());
224                                        nested_con_stack.push(left.clone());
225                                    }
226                                    _ => top_level_con_items.push(item.clone()),
227                                }
228                            }
229
230                            top_level_con_items
231                                .iter()
232                                .skip(*start as usize)
233                                .take((end - start) as usize + 1)
234                                .map(usize::clone)
235                                .for_each(|i| items.push(i));
236                        }
237                        _ => items.push(UNIT_INDEX),
238                    },
239                    _ => items.push(UNIT_INDEX),
240                },
241                Some(_) => items.push(item),
242            }
243        }
244
245        items
246    }
247
248    fn cache_add(&mut self, value: SimpleData<T>) -> Result<usize, DataError> {
249        let mut h = DefaultHasher::new();
250        value.hash(&mut h);
251        value.get_data_type().hash(&mut h);
252        let hv = h.finish();
253
254        match self.cache.get(&hv) {
255            Some(addr) => Ok(*addr),
256            None => {
257                let addr = self.data.len();
258                self.data.push(value);
259                self.cache.insert(hv, addr);
260                Ok(addr)
261            }
262        }
263    }
264
265    fn add_to_current_char_list(&mut self, from: usize, depth: usize) -> Result<(), DataError> {
266        if depth >= self.max_char_list_depth {
267            return Ok(());
268        }
269
270        match self.get_data_type(from)? {
271            GarnishDataType::Invalid => todo!(),
272            GarnishDataType::Custom => todo!(),
273            GarnishDataType::Unit => {
274                self.add_to_char_list('(')?;
275                self.add_to_char_list(')')?;
276            }
277            GarnishDataType::True => {
278                self.add_to_char_list('$')?;
279                self.add_to_char_list('?')?;
280            }
281            GarnishDataType::False => {
282                self.add_to_char_list('$')?;
283                self.add_to_char_list('!')?;
284            }
285            GarnishDataType::Type => {
286                let s = format!("{:?}", self.get_type(from)?);
287                for c in s.chars() {
288                    self.add_to_char_list(c)?;
289                }
290            }
291            GarnishDataType::Number => {
292                let x = self.get_number(from)?;
293                let s = x.to_string();
294                for c in s.chars() {
295                    self.add_to_char_list(c)?;
296                }
297            }
298            GarnishDataType::Char => {
299                let c = self.get_char(from)?;
300                self.add_to_char_list(c)?;
301            }
302            GarnishDataType::CharList => {
303                let len = self.get_char_list_len(from)?;
304                for i in 0..len {
305                    let c = self.get_char_list_item(from, i.into())?;
306                    self.add_to_char_list(c)?;
307                }
308            }
309            GarnishDataType::Byte => {
310                let b = self.get_byte(from)?;
311                let s = b.to_string();
312                self.start_char_list()?;
313                for c in s.chars() {
314                    self.add_to_char_list(c)?;
315                }
316            }
317            GarnishDataType::ByteList => {
318                let len = self.get_byte_list_len(from)?;
319                let mut strs = vec![];
320                for i in 0..len {
321                    let b = self.get_byte_list_item(from, i.into())?;
322                    strs.push(format!("'{}'", b));
323                }
324                let s = strs.join(" ");
325                self.start_char_list()?;
326                for c in s.chars() {
327                    self.add_to_char_list(c)?;
328                }
329            }
330            GarnishDataType::Symbol => {
331                let sym = self.get_symbol(from)?;
332                let s = match self.data.get_symbol(sym) {
333                    None => sym.to_string(),
334                    Some(s) => s.clone(),
335                };
336
337                for c in s.chars() {
338                    self.add_to_char_list(c)?;
339                }
340            }
341            GarnishDataType::SymbolList => {
342                let len = self.get_symbol_list_len(from)?;
343                let mut strs = vec![];
344                for i in 0..len {
345                    let sym = self.get_symbol_list_item(from, i.into())?;
346                    let s = match self.data.get_symbol(sym) {
347                        None => sym.to_string(),
348                        Some(s) => s.clone(),
349                    };
350                    strs.push(format!("{}", s));
351                }
352                let s = strs.join(", ");
353                self.start_char_list()?;
354                for c in s.chars() {
355                    self.add_to_char_list(c)?;
356                }
357            }
358            GarnishDataType::Expression => {
359                let e = self.get_expression(from)?;
360                let s = format!("Expression({})", e);
361
362                for c in s.chars() {
363                    self.add_to_char_list(c)?;
364                }
365            }
366            GarnishDataType::External => {
367                let e = self.get_external(from)?;
368                let s = format!("External({})", e);
369
370                for c in s.chars() {
371                    self.add_to_char_list(c)?;
372                }
373            }
374            GarnishDataType::Range => {
375                let (start, end) = self.get_range(from).and_then(|(start, end)| Ok((self.get_number(start)?, self.get_number(end)?)))?;
376
377                let s = format!("{}..{}", start, end);
378
379                for c in s.chars() {
380                    self.add_to_char_list(c)?;
381                }
382            }
383            GarnishDataType::Pair => {
384                let (left, right) = self.get_pair(from)?;
385                if depth > 0 {
386                    self.add_to_char_list('(')?;
387                }
388                self.add_to_current_char_list(left, depth + 1)?;
389                self.add_to_char_list(' ')?;
390                self.add_to_char_list('=')?;
391                self.add_to_char_list(' ')?;
392                self.add_to_current_char_list(right, depth + 1)?;
393                if depth > 0 {
394                    self.add_to_char_list(')')?;
395                }
396            }
397            GarnishDataType::Partial => {
398                let (left, right) = self.get_pair(from)?;
399                if depth > 0 {
400                    self.add_to_char_list('(')?;
401                }
402                self.add_to_current_char_list(left, depth + 1)?;
403                self.add_to_char_list(' ')?;
404                self.add_to_char_list('~')?;
405                self.add_to_char_list(' ')?;
406                self.add_to_current_char_list(right, depth + 1)?;
407                if depth > 0 {
408                    self.add_to_char_list(')')?;
409                }
410            }
411            GarnishDataType::Concatenation => {
412                let (left, right) = self.get_concatenation(from)?;
413                self.add_to_current_char_list(left, depth + 1)?;
414                self.add_to_current_char_list(right, depth + 1)?;
415            }
416            GarnishDataType::List => {
417                let len = self.get_list_len(from)?;
418
419                if depth > 0 {
420                    self.add_to_char_list('(')?;
421                }
422
423                for i in 0..len {
424                    let item = self.get_list_item(from, i.into())?;
425                    self.add_to_current_char_list(item, depth + 1)?;
426
427                    if i < len - 1 {
428                        self.add_to_char_list(',')?;
429                        self.add_to_char_list(' ')?;
430                    }
431                }
432
433                if depth > 0 {
434                    self.add_to_char_list(')')?;
435                }
436            }
437            GarnishDataType::Slice => {
438                let (value, range) = self.get_slice(from)?;
439                let (start, end) = self.get_range(range)?;
440                let (start, end) = (self.get_number(start)?.to_integer().as_integer()?, self.get_number(end)?.to_integer().as_integer()?);
441
442                match self.get_data_type(value)? {
443                    GarnishDataType::CharList => {
444                        for i in start..=end {
445                            let c = self.get_char_list_item(value, i.into())?;
446                            self.add_to_char_list(c)?;
447                        }
448                    }
449                    GarnishDataType::List => {
450                        if depth > 0 {
451                            self.add_to_char_list('(')?;
452                        }
453
454                        for i in start..=end {
455                            let item = self.get_list_item(value, i.into())?;
456                            self.add_to_current_char_list(item, depth + 1)?;
457
458                            if i != end {
459                                self.add_to_char_list(',')?;
460                                self.add_to_char_list(' ')?;
461                            }
462                        }
463
464                        if depth > 0 {
465                            self.add_to_char_list(')')?;
466                        }
467                    }
468                    GarnishDataType::Concatenation => {
469                        iterate_concatenation_mut(self, value, |this, index, addr| {
470                            let i = index.to_integer().as_integer()?;
471                            if i >= start && i <= end {
472                                this.add_to_current_char_list(addr, depth + 1)?;
473                            }
474
475                            Ok(None)
476                        })
477                        .or_else(|err| Err(DataError::from(format!("{:?}", err))))?;
478                    }
479                    _ => {
480                        self.add_to_current_char_list(value, depth + 1)?;
481                        self.add_to_char_list(' ')?;
482                        self.add_to_char_list('~')?;
483                        self.add_to_char_list(' ')?;
484                        self.add_to_current_char_list(range, depth + 1)?;
485                    }
486                }
487            }
488        }
489
490        Ok(())
491    }
492}
493
494#[cfg(test)]
495mod utilities {
496    use crate::SimpleGarnishData;
497
498    #[test]
499    fn set_end_of_constant_data_error_over_max_data() {
500        let mut data = SimpleGarnishData::new();
501        let result = data.set_end_of_constant(10);
502
503        assert!(result.is_err());
504    }
505
506    #[test]
507    fn set_end_of_constant_data_is_inclusive() {
508        let mut data = SimpleGarnishData::new();
509        data.set_end_of_constant(2).unwrap();
510
511        assert_eq!(data.end_of_constant_data, 2);
512    }
513}
514
515#[cfg(test)]
516mod data_storage {
517    use crate::{GarnishData, SimpleGarnishData};
518
519    #[test]
520    fn unit() {
521        let mut runtime = SimpleGarnishData::new();
522
523        assert_eq!(runtime.add_unit().unwrap(), 0);
524        assert_eq!(runtime.add_unit().unwrap(), 0);
525        assert_eq!(runtime.add_unit().unwrap(), 0);
526
527        assert_eq!(runtime.get_data_len(), 3);
528        assert!(runtime.data.get(0).unwrap().is_unit());
529    }
530
531    #[test]
532    fn false_data() {
533        let mut runtime = SimpleGarnishData::new();
534
535        assert_eq!(runtime.add_false().unwrap(), 1);
536        assert_eq!(runtime.add_false().unwrap(), 1);
537        assert_eq!(runtime.add_false().unwrap(), 1);
538
539        assert_eq!(runtime.get_data_len(), 3);
540        assert!(runtime.data.get(1).unwrap().is_false());
541    }
542
543    #[test]
544    fn true_data() {
545        let mut runtime = SimpleGarnishData::new();
546
547        assert_eq!(runtime.add_true().unwrap(), 2);
548        assert_eq!(runtime.add_true().unwrap(), 2);
549        assert_eq!(runtime.add_true().unwrap(), 2);
550
551        assert_eq!(runtime.get_data_len(), 3);
552        assert!(runtime.data.get(2).unwrap().is_true());
553    }
554
555    #[test]
556    fn integers() {
557        let mut runtime = SimpleGarnishData::new();
558
559        let start = runtime.get_data_len();
560        let i1 = runtime.add_number(10.into()).unwrap();
561        let i2 = runtime.add_number(20.into()).unwrap();
562        let i3 = runtime.add_number(10.into()).unwrap();
563
564        assert_eq!(i1, start);
565        assert_eq!(i2, start + 1);
566        assert_eq!(i3, i1);
567
568        assert_eq!(runtime.get_data_len(), 5);
569        assert_eq!(runtime.data.get(3).unwrap().as_number().unwrap(), 10.into());
570        assert_eq!(runtime.data.get(4).unwrap().as_number().unwrap(), 20.into());
571    }
572
573    #[test]
574    fn symbols() {
575        let mut runtime = SimpleGarnishData::new();
576
577        let start = runtime.get_data_len();
578        let i1 = runtime.add_symbol(1).unwrap();
579        let i2 = runtime.add_symbol(2).unwrap();
580        let i3 = runtime.add_symbol(1).unwrap();
581
582        assert_eq!(i1, start);
583        assert_eq!(i2, start + 1);
584        assert_eq!(i3, i1);
585
586        assert_eq!(runtime.get_data_len(), 5);
587        assert_eq!(runtime.data.get(3).unwrap().as_symbol().unwrap(), 1);
588        assert_eq!(runtime.data.get(4).unwrap().as_symbol().unwrap(), 2);
589    }
590
591    #[test]
592    fn expression() {
593        let mut runtime = SimpleGarnishData::new();
594
595        let start = runtime.get_data_len();
596        let i1 = runtime.add_expression(10).unwrap();
597        let i2 = runtime.add_expression(20).unwrap();
598        let i3 = runtime.add_expression(10).unwrap();
599
600        assert_eq!(i1, start);
601        assert_eq!(i2, start + 1);
602        assert_eq!(i3, i1);
603
604        assert_eq!(runtime.get_data_len(), 5);
605        assert_eq!(runtime.data.get(3).unwrap().as_expression().unwrap(), 10);
606        assert_eq!(runtime.data.get(4).unwrap().as_expression().unwrap(), 20);
607    }
608
609    #[test]
610    fn external() {
611        let mut runtime = SimpleGarnishData::new();
612
613        let start = runtime.get_data_len();
614        let i1 = runtime.add_external(10).unwrap();
615        let i2 = runtime.add_external(20).unwrap();
616        let i3 = runtime.add_external(10).unwrap();
617
618        assert_eq!(i1, start);
619        assert_eq!(i2, start + 1);
620        assert_eq!(i3, i1);
621
622        assert_eq!(runtime.get_data_len(), 5);
623        assert_eq!(runtime.data.get(3).unwrap().as_external().unwrap(), 10);
624        assert_eq!(runtime.data.get(4).unwrap().as_external().unwrap(), 20);
625    }
626
627    #[test]
628    fn similar_values_cache_differently() {
629        let mut runtime = SimpleGarnishData::new();
630
631        let start = runtime.get_data_len();
632        let i1 = runtime.add_external(10).unwrap();
633        let i2 = runtime.add_expression(10).unwrap();
634
635        assert_eq!(i1, start);
636        assert_eq!(i2, start + 1);
637        assert_ne!(i1, i2);
638
639        assert_eq!(runtime.get_data_len(), 5);
640        assert_eq!(runtime.data.get(3).unwrap().as_external().unwrap(), 10);
641        assert_eq!(runtime.data.get(4).unwrap().as_expression().unwrap(), 10);
642    }
643}
644
645#[cfg(test)]
646mod to_symbol {
647    use crate::{GarnishData, SimpleGarnishData, symbol_value};
648
649    #[test]
650    fn unit() {
651        let mut runtime = SimpleGarnishData::new();
652
653        let d1 = runtime.add_unit().unwrap();
654        let addr = runtime.add_symbol_from(d1).unwrap();
655
656        let val = symbol_value("()");
657        assert_eq!(runtime.get_symbol(addr).unwrap(), val);
658    }
659}
660
661#[cfg(test)]
662mod to_byte_list {
663    use crate::{GarnishData, SimpleGarnishData};
664
665    #[test]
666    fn unit() {
667        let mut runtime = SimpleGarnishData::new();
668
669        let d1 = runtime.add_unit().unwrap();
670        let addr = runtime.add_byte_list_from(d1).unwrap();
671        let len = runtime.get_byte_list_len(addr).unwrap();
672
673        assert_eq!(len, 0);
674    }
675}
676
677#[cfg(test)]
678mod to_char_list {
679    use crate::{GarnishData, GarnishDataType, NoCustom, SimpleGarnishData};
680
681    fn assert_to_char_list<Func>(expected: &str, setup: Func)
682    where
683        Func: FnOnce(&mut SimpleGarnishData) -> usize,
684    {
685        let mut runtime = SimpleGarnishData::new();
686
687        let d1 = setup(&mut runtime);
688
689        let addr = runtime.add_char_list_from(d1).unwrap();
690        let len = runtime.get_char_list_len(addr).unwrap();
691
692        let mut chars = String::new();
693
694        for i in 0..len {
695            let c = runtime.get_char_list_item(addr, i.into()).unwrap();
696            chars.push(c);
697        }
698
699        assert_eq!(chars, expected, "{:?} != {:?}", chars, expected);
700    }
701
702    #[test]
703    fn unit() {
704        assert_to_char_list("()", |runtime| runtime.add_unit().unwrap())
705    }
706
707    #[test]
708    fn true_boolean() {
709        assert_to_char_list("$?", |runtime| runtime.add_true().unwrap())
710    }
711
712    #[test]
713    fn false_boolean() {
714        assert_to_char_list("$!", |runtime| runtime.add_false().unwrap())
715    }
716
717    #[test]
718    fn integer() {
719        assert_to_char_list("10", |runtime| runtime.add_number(10.into()).unwrap())
720    }
721
722    #[test]
723    fn char() {
724        assert_to_char_list("c", |runtime| runtime.add_char('c').unwrap())
725    }
726
727    #[test]
728    fn type_data() {
729        assert_to_char_list("Unit", |runtime| runtime.add_type(GarnishDataType::Unit).unwrap())
730    }
731
732    #[test]
733    fn char_list() {
734        assert_to_char_list("characters", |runtime| {
735            runtime.start_char_list().unwrap();
736            runtime.add_to_char_list('c').unwrap();
737            runtime.add_to_char_list('h').unwrap();
738            runtime.add_to_char_list('a').unwrap();
739            runtime.add_to_char_list('r').unwrap();
740            runtime.add_to_char_list('a').unwrap();
741            runtime.add_to_char_list('c').unwrap();
742            runtime.add_to_char_list('t').unwrap();
743            runtime.add_to_char_list('e').unwrap();
744            runtime.add_to_char_list('r').unwrap();
745            runtime.add_to_char_list('s').unwrap();
746            runtime.end_char_list().unwrap()
747        })
748    }
749
750    #[test]
751    fn byte() {
752        assert_to_char_list("100", |runtime| runtime.add_byte(100).unwrap())
753    }
754
755    #[test]
756    fn byte_list() {
757        assert_to_char_list("'10' '20' '30'", |runtime| {
758            runtime.start_byte_list().unwrap();
759            runtime.add_to_byte_list(10).unwrap();
760            runtime.add_to_byte_list(20).unwrap();
761            runtime.add_to_byte_list(30).unwrap();
762            runtime.end_byte_list().unwrap()
763        })
764    }
765
766    #[test]
767    fn symbol() {
768        let s = SimpleGarnishData::<NoCustom>::parse_symbol("my_symbol").unwrap().to_string();
769        assert_to_char_list(s.as_str(), |runtime| runtime.add_symbol(SimpleGarnishData::<NoCustom>::parse_symbol("my_symbol").unwrap()).unwrap())
770    }
771
772    #[test]
773    fn symbol_list() {
774        assert_to_char_list("symbol_one, symbol_two", |runtime| {
775            let sym1 = runtime.parse_add_symbol("symbol_one").unwrap();
776            let sym2 = runtime.parse_add_symbol("symbol_two").unwrap();
777            runtime.merge_to_symbol_list(sym1, sym2).unwrap()
778        })
779    }
780
781    #[test]
782    fn expression() {
783        assert_to_char_list("Expression(10)", |runtime| runtime.add_expression(10).unwrap())
784    }
785
786    #[test]
787    fn external() {
788        assert_to_char_list("External(10)", |runtime| runtime.add_external(10).unwrap())
789    }
790
791    #[test]
792    fn range() {
793        assert_to_char_list("5..10", |runtime| {
794            let d1 = runtime.add_number(5.into()).unwrap();
795            let d2 = runtime.add_number(10.into()).unwrap();
796            runtime.add_range(d1, d2).unwrap()
797        })
798    }
799
800    #[test]
801    fn pair() {
802        assert_to_char_list("10 = 10", |runtime| {
803            let d1 = runtime.add_number(10.into()).unwrap();
804            let d2 = runtime.add_number(10.into()).unwrap();
805            runtime.add_pair((d1, d2)).unwrap()
806        })
807    }
808
809    #[test]
810    fn pair_nested() {
811        assert_to_char_list("10 = (20 = 30)", |runtime| {
812            let d1 = runtime.add_number(10.into()).unwrap();
813            let d2 = runtime.add_number(20.into()).unwrap();
814            let d3 = runtime.add_number(30.into()).unwrap();
815            let d4 = runtime.add_pair((d2, d3)).unwrap();
816            runtime.add_pair((d1, d4)).unwrap()
817        })
818    }
819
820    #[test]
821    fn pair_nested_two() {
822        assert_to_char_list("10 = (20 = (30 = 40))", |runtime| {
823            let d1 = runtime.add_number(10.into()).unwrap();
824            let d2 = runtime.add_number(20.into()).unwrap();
825            let d3 = runtime.add_number(30.into()).unwrap();
826            let d4 = runtime.add_number(40.into()).unwrap();
827            let d5 = runtime.add_pair((d3, d4)).unwrap();
828            let d6 = runtime.add_pair((d2, d5)).unwrap();
829            runtime.add_pair((d1, d6)).unwrap()
830        })
831    }
832
833    #[test]
834    fn list() {
835        assert_to_char_list("10, 20, 30", |runtime| {
836            let d1 = runtime.add_number(10.into()).unwrap();
837            let d2 = runtime.add_number(20.into()).unwrap();
838            let d3 = runtime.add_number(30.into()).unwrap();
839            runtime.start_list(3).unwrap();
840            runtime.add_to_list(d1, false).unwrap();
841            runtime.add_to_list(d2, false).unwrap();
842            runtime.add_to_list(d3, false).unwrap();
843            runtime.end_list().unwrap()
844        })
845    }
846
847    #[test]
848    fn list_nested() {
849        assert_to_char_list("10, (20, 30), 40", |runtime| {
850            let d1 = runtime.add_number(10.into()).unwrap();
851            let d2 = runtime.add_number(20.into()).unwrap();
852            let d3 = runtime.add_number(30.into()).unwrap();
853            let d4 = runtime.add_number(40.into()).unwrap();
854
855            runtime.start_list(2).unwrap();
856            runtime.add_to_list(d2, false).unwrap();
857            runtime.add_to_list(d3, false).unwrap();
858            let list = runtime.end_list().unwrap();
859
860            runtime.start_list(3).unwrap();
861            runtime.add_to_list(d1, false).unwrap();
862            runtime.add_to_list(list, false).unwrap();
863            runtime.add_to_list(d4, false).unwrap();
864            runtime.end_list().unwrap()
865        })
866    }
867
868    #[test]
869    fn slice_of_char_list() {
870        assert_to_char_list("cde", |runtime| {
871            let s = runtime.parse_add_char_list("abcdef").unwrap();
872
873            let start = runtime.add_number(2.into()).unwrap();
874            let end = runtime.add_number(4.into()).unwrap();
875            let range = runtime.add_range(start, end).unwrap();
876
877            runtime.add_slice(s, range).unwrap()
878        })
879    }
880
881    #[test]
882    fn slice_of_concatenation() {
883        assert_to_char_list("304050", |runtime| {
884            let d1 = runtime.add_number(10.into()).unwrap();
885            let d2 = runtime.add_number(20.into()).unwrap();
886            let d3 = runtime.add_number(30.into()).unwrap();
887            let d4 = runtime.add_number(40.into()).unwrap();
888            let d5 = runtime.add_number(50.into()).unwrap();
889            let d6 = runtime.add_number(60.into()).unwrap();
890
891            let cat1 = runtime.add_concatenation(d1, d2).unwrap();
892            let cat2 = runtime.add_concatenation(cat1, d3).unwrap();
893            let cat3 = runtime.add_concatenation(cat2, d4).unwrap();
894            let cat4 = runtime.add_concatenation(cat3, d5).unwrap();
895            let cat5 = runtime.add_concatenation(cat4, d6).unwrap();
896
897            let start = runtime.add_number(2.into()).unwrap();
898            let end = runtime.add_number(4.into()).unwrap();
899            let range = runtime.add_range(start, end).unwrap();
900
901            runtime.add_slice(cat5, range).unwrap()
902        })
903    }
904
905    #[test]
906    fn slice_of_list() {
907        assert_to_char_list("30, 40, 50", |runtime| {
908            let d1 = runtime.add_number(10.into()).unwrap();
909            let d2 = runtime.add_number(20.into()).unwrap();
910            let d3 = runtime.add_number(30.into()).unwrap();
911            let d4 = runtime.add_number(40.into()).unwrap();
912            let d5 = runtime.add_number(50.into()).unwrap();
913            let d6 = runtime.add_number(60.into()).unwrap();
914
915            runtime.start_list(3).unwrap();
916            runtime.add_to_list(d1, false).unwrap();
917            runtime.add_to_list(d2, false).unwrap();
918            runtime.add_to_list(d3, false).unwrap();
919            runtime.add_to_list(d4, false).unwrap();
920            runtime.add_to_list(d5, false).unwrap();
921            runtime.add_to_list(d6, false).unwrap();
922            let list = runtime.end_list().unwrap();
923
924            let start = runtime.add_number(2.into()).unwrap();
925            let end = runtime.add_number(4.into()).unwrap();
926            let range = runtime.add_range(start, end).unwrap();
927
928            runtime.add_slice(list, range).unwrap()
929        })
930    }
931
932    #[test]
933    fn concatenation() {
934        assert_to_char_list("Hello World!", |runtime| {
935            let d1 = runtime.parse_add_char_list("Hello ").unwrap();
936            let d2 = runtime.parse_add_char_list("World!").unwrap();
937            runtime.add_concatenation(d1, d2).unwrap()
938        })
939    }
940}