1
use crate::errors::{ConjureParseError, FatalParseError};
2
use crate::parse_expr;
3
use conjure_cp_core::ast::{Atom, Expression, Literal, SymbolTablePtr};
4
#[allow(unused)]
5
use uniplate::Uniplate;
6

            
7
6
pub fn parse_literal(src: &str) -> Result<Literal, FatalParseError> {
8
    // HACK: Create a dummy symbol table - don't need it for parsing literals
9
6
    let symbol_table = SymbolTablePtr::new();
10
6
    let expr = parse_expr(src, symbol_table)?;
11
6
    let Some(expr) = expr else {
12
1
        return Err(
13
1
            ConjureParseError::Parse("Expected a literal, got no expression".to_string()).into(),
14
1
        );
15
    };
16
5
    match expr {
17
4
        Expression::Atomic(_metadata, atom) => match atom {
18
4
            Atom::Literal(lit) => Ok(lit),
19
            _ => {
20
                Err(ConjureParseError::Parse(format!("Expected a literal, got '{atom:?}'")).into())
21
            }
22
        },
23
1
        _ => Err(ConjureParseError::Parse(format!("Expected a literal, got '{expr:?}'")).into()),
24
    }
25
6
}
26

            
27
mod test {
28
    #[allow(unused)]
29
    use super::parse_literal;
30
    #[allow(unused)]
31
    use conjure_cp_core::ast::Metadata;
32
    #[allow(unused)]
33
    use conjure_cp_core::ast::{
34
        Atom, DeclarationPtr, Domain, Expression, Literal, Moo, Name, SymbolTable,
35
    };
36
    #[allow(unused)]
37
    use std::collections::HashMap;
38
    #[allow(unused)]
39
    use std::sync::Arc;
40
    #[allow(unused)]
41
    use std::{cell::RefCell, rc::Rc};
42
    #[allow(unused)]
43
    use tree_sitter::Range;
44

            
45
    #[test]
46
1
    pub fn test_parse_bool() {
47
1
        let src_true = "true";
48
1
        let src_false = "false";
49
1
        let literal_true = parse_literal(src_true).unwrap();
50
1
        let literal_false = parse_literal(src_false).unwrap();
51
1
        assert_eq!(literal_true, Literal::Bool(true));
52
1
        assert_eq!(literal_false, Literal::Bool(false));
53
1
    }
54

            
55
    #[test]
56
1
    pub fn test_parse_int() {
57
1
        let src_int = "42";
58
1
        let literal_int = parse_literal(src_int).unwrap();
59
1
        assert_eq!(literal_int, Literal::Int(42));
60
1
    }
61

            
62
    #[test]
63
1
    pub fn test_parse_neg_int() {
64
1
        let src_int = "-42";
65
1
        let literal_int = parse_literal(src_int).unwrap();
66
1
        assert_eq!(literal_int, Literal::Int(-42));
67
1
    }
68

            
69
    #[test]
70
1
    pub fn test_bad() {
71
1
        let src_bad = "bad";
72
1
        let src_expr = "2 + 2";
73
1
        let literal_bad = parse_literal(src_bad);
74
1
        let literal_expr = parse_literal(src_expr);
75
1
        assert!(literal_bad.is_err());
76
1
        assert!(literal_expr.is_err());
77
1
    }
78
}