Skip to main content

conjure_cp_essence_parser/parser/
parse_literal.rs

1use crate::errors::{ConjureParseError, FatalParseError};
2use crate::parse_expr;
3use conjure_cp_core::ast::{Atom, Expression, Literal, SymbolTablePtr};
4#[allow(unused)]
5use uniplate::Uniplate;
6
7pub fn parse_literal(src: &str) -> Result<Literal, FatalParseError> {
8    // HACK: Create a dummy symbol table - don't need it for parsing literals
9    let symbol_table = SymbolTablePtr::new();
10    let expr = parse_expr(src, symbol_table)?;
11    let Some(expr) = expr else {
12        return Err(
13            ConjureParseError::Parse("Expected a literal, got no expression".to_string()).into(),
14        );
15    };
16    match expr {
17        Expression::Atomic(_metadata, atom) => match atom {
18            Atom::Literal(lit) => Ok(lit),
19            _ => {
20                Err(ConjureParseError::Parse(format!("Expected a literal, got '{atom:?}'")).into())
21            }
22        },
23        _ => Err(ConjureParseError::Parse(format!("Expected a literal, got '{expr:?}'")).into()),
24    }
25}
26
27mod 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    pub fn test_parse_bool() {
47        let src_true = "true";
48        let src_false = "false";
49        let literal_true = parse_literal(src_true).unwrap();
50        let literal_false = parse_literal(src_false).unwrap();
51        assert_eq!(literal_true, Literal::Bool(true));
52        assert_eq!(literal_false, Literal::Bool(false));
53    }
54
55    #[test]
56    pub fn test_parse_int() {
57        let src_int = "42";
58        let literal_int = parse_literal(src_int).unwrap();
59        assert_eq!(literal_int, Literal::Int(42));
60    }
61
62    #[test]
63    pub fn test_parse_neg_int() {
64        let src_int = "-42";
65        let literal_int = parse_literal(src_int).unwrap();
66        assert_eq!(literal_int, Literal::Int(-42));
67    }
68
69    #[test]
70    pub fn test_bad() {
71        let src_bad = "bad";
72        let src_expr = "2 + 2";
73        let literal_bad = parse_literal(src_bad);
74        let literal_expr = parse_literal(src_expr);
75        assert!(literal_bad.is_err());
76        assert!(literal_expr.is_err());
77    }
78}