1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use crate::err::{SJFLError, Span};
use crate::value::{List, InternedString, Table, Variable, Value};
use super::{match_exact, Parse, Session};
use hmath::Ratio;

impl Parse for Value {

    // if the first character is ` `, it dies!
    fn parse(s: &[u8], ind: usize, session: &mut Session) -> Result<(Self, usize), SJFLError> {

        match s[ind] {
            b'"' | b'\'' => {
                let (s, ind) = InternedString::parse(s, ind, session)?;

                Ok((Value::String(s), ind))
            }
            b'-' | b'0'..=b'9' => {  // - | 0-9
                let (n, ind) = Ratio::parse(s, ind, session)?;

                Ok((Value::Number(n), ind))
            }
            b'A'..=b'Z' | b'_' => {  // A-Z | _

                if let Ok(n) = match_exact(s, ind, b"True") {
                    Ok((Value::Boolean(true), n))
                }

                else if let Ok(n) = match_exact(s, ind, b"False") {
                    Ok((Value::Boolean(false), n))
                }

                else if let Ok(n) = match_exact(s, ind, b"None") {
                    Ok((Value::None, n))
                }

                else {
                    let (var, ind) = Variable::parse(s, ind, session)?;

                    Ok((Value::Variable(var), ind))
                }

            }
            b'[' => {  // [
                let (l, ind) = List::parse(s, ind, session)?;

                Ok((Value::List(l), ind))
            }
            b'a'..=b'z' => {  // a-z

                if let Ok(n) = match_exact(s, ind, b"true") {
                    Ok((Value::Boolean(true), n))
                }

                else if let Ok(n) = match_exact(s, ind, b"false") {
                    Ok((Value::Boolean(false), n))
                }

                else if let Ok(n) = match_exact(s, ind, b"null") {
                    Ok((Value::None, n))
                }

                else {
                    let (var, ind) = Variable::parse(s, ind, session)?;

                    Ok((Value::Variable(var), ind))
                }

            }
            b'{' => {  // {
                let (t, ind) = Table::parse(s, ind, session)?;

                Ok((Value::Table(t), ind))
            }
            _ => Err(SJFLError::UnexpectedChar(s[ind], Span::from_index(ind)))
        }

    }

}