conjure_cp_essence_parser/parser/
parse_literal.rs

1use crate::errors::{ConjureParseError, EssenceParseError};
2use crate::parse_expr;
3use conjure_cp_core::ast::{Atom, Expression, Literal, SymbolTable};
4#[allow(unused)]
5use uniplate::Uniplate;
6
7pub fn parse_literal(src: &str) -> Result<Literal, EssenceParseError> {
8    // HACK: Create a dummy symbol table - don't need it for parsing literals
9    let symbol_table = SymbolTable::new();
10    let expr = parse_expr(src, &symbol_table)?;
11    match expr {
12        Expression::Atomic(_metadata, atom) => match atom {
13            Atom::Literal(lit) => Ok(lit),
14            _ => {
15                Err(ConjureParseError::Parse(format!("Expected a literal, got '{atom:?}'")).into())
16            }
17        },
18        _ => Err(ConjureParseError::Parse(format!("Expected a literal, got '{expr:?}'")).into()),
19    }
20}
21
22mod test {
23    #[allow(unused)]
24    use super::parse_literal;
25    #[allow(unused)]
26    use conjure_cp_core::ast::Metadata;
27    #[allow(unused)]
28    use conjure_cp_core::ast::{
29        Atom, DeclarationPtr, Domain, Expression, Literal, Moo, Name, SymbolTable,
30    };
31    #[allow(unused)]
32    use std::collections::HashMap;
33    #[allow(unused)]
34    use std::sync::Arc;
35    #[allow(unused)]
36    use std::{cell::RefCell, rc::Rc};
37    #[allow(unused)]
38    use tree_sitter::Range;
39
40    #[test]
41    pub fn test_parse_bool() {
42        let src_true = "true";
43        let src_false = "false";
44        let literal_true = parse_literal(src_true).unwrap();
45        let literal_false = parse_literal(src_false).unwrap();
46        assert_eq!(literal_true, Literal::Bool(true));
47        assert_eq!(literal_false, Literal::Bool(false));
48    }
49
50    #[test]
51    pub fn test_parse_int() {
52        let src_int = "42";
53        let literal_int = parse_literal(src_int).unwrap();
54        assert_eq!(literal_int, Literal::Int(42));
55    }
56
57    #[test]
58    pub fn test_parse_neg_int() {
59        let src_int = "-42";
60        let literal_int = parse_literal(src_int).unwrap();
61        assert_eq!(literal_int, Literal::Int(-42));
62    }
63
64    #[test]
65    pub fn test_bad() {
66        let src_bad = "bad";
67        let src_expr = "2 + 2";
68        let literal_bad = parse_literal(src_bad);
69        let literal_expr = parse_literal(src_expr);
70        assert!(literal_bad.is_err());
71        assert!(literal_expr.is_err());
72    }
73}