1
use crate::errors::FatalParseError;
2
use crate::expression::parse_expression;
3
use crate::field;
4
use crate::parser::ParseContext;
5
use crate::parser::domain::parse_domain;
6
use crate::util::{TypecheckingContext, named_children};
7
use conjure_cp_core::ast::{AbstractLiteral, DomainPtr, Expression};
8
use conjure_cp_core::{domain_int, range};
9
use tree_sitter::Node;
10

            
11
2596
pub fn parse_abstract(
12
2596
    ctx: &mut ParseContext,
13
2596
    node: &Node,
14
2596
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
15
2596
    match node.kind() {
16
2596
        "record" => parse_record(ctx, node),
17
2596
        "tuple" => parse_tuple(ctx, node),
18
2596
        "matrix" => parse_matrix(ctx, node),
19
1836
        "set_literal" => parse_set_literal(ctx, node),
20
        _ => Err(FatalParseError::internal_error(
21
            format!("Expected abstract literal, got: {}", node.kind()),
22
            Some(node.range()),
23
        )),
24
    }
25
2596
}
26

            
27
fn parse_record(
28
    ctx: &mut ParseContext,
29
    node: &Node,
30
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
31
    let mut values = Vec::new();
32
    for child in node.children_by_field_name("name_value_pair", &mut node.walk()) {
33
        let name_node = field!(child, "name");
34
        let name_str = &ctx.source_code[name_node.start_byte()..name_node.end_byte()];
35
        let name = conjure_cp_core::ast::Name::user(name_str);
36

            
37
        let Some(value) = parse_expression(ctx, field!(child, "value"))? else {
38
            return Ok(None);
39
        };
40
        values.push(conjure_cp_core::ast::records::RecordValue { name, value });
41
    }
42
    Ok(Some(AbstractLiteral::Record(values)))
43
}
44

            
45
fn parse_tuple(
46
    ctx: &mut ParseContext,
47
    node: &Node,
48
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
49
    let mut elements = Vec::new();
50
    for child in named_children(node) {
51
        let Some(expr) = parse_expression(ctx, child)? else {
52
            return Ok(None);
53
        };
54
        elements.push(expr);
55
    }
56
    Ok(Some(AbstractLiteral::Tuple(elements)))
57
}
58

            
59
760
fn parse_matrix(
60
760
    ctx: &mut ParseContext,
61
760
    node: &Node,
62
760
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
63
760
    let mut elements = vec![];
64
760
    let mut domain: Option<DomainPtr> = None;
65
1884
    for child in named_children(node) {
66
1884
        if child.kind() == "arithmetic_expr"
67
1884
            || child.kind() == "bool_expr"
68
1884
            || child.kind() == "comparison_expr"
69
1884
            || child.kind() == "atom"
70
        {
71
1838
            let Some(expr) = parse_expression(ctx, child)? else {
72
68
                return Ok(None);
73
            };
74
1770
            elements.push(expr);
75
        } else {
76
46
            let Some(parsed_domain) = parse_domain(ctx, child)? else {
77
                return Ok(None);
78
            };
79
46
            domain = Some(parsed_domain);
80
        }
81
    }
82
692
    if domain.is_none() {
83
646
        let count = elements.len() as i32;
84
646
        domain = Some(domain_int!(1..count));
85
658
    }
86

            
87
692
    Ok(Some(AbstractLiteral::Matrix(elements, domain.unwrap())))
88
760
}
89

            
90
1836
fn parse_set_literal(
91
1836
    ctx: &mut ParseContext,
92
1836
    node: &Node,
93
1836
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
94
1836
    let mut elements = Vec::new();
95
4760
    for child in named_children(node) {
96
4760
        ctx.typechecking_context = TypecheckingContext::Unknown;
97
4760
        let Some(expr) = parse_expression(ctx, child)? else {
98
            return Ok(None);
99
        };
100
4760
        elements.push(expr);
101
    }
102
1836
    Ok(Some(AbstractLiteral::Set(elements)))
103
1836
}