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
1871
pub fn parse_abstract(
12
1871
    ctx: &mut ParseContext,
13
1871
    node: &Node,
14
1871
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
15
1871
    match node.kind() {
16
1871
        "record" => parse_record(ctx, node),
17
1871
        "tuple" => parse_tuple(ctx, node),
18
1871
        "matrix" => parse_matrix(ctx, node),
19
1782
        "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
1871
}
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
89
fn parse_matrix(
60
89
    ctx: &mut ParseContext,
61
89
    node: &Node,
62
89
) -> Result<Option<AbstractLiteral<Expression>>, FatalParseError> {
63
89
    let mut elements = vec![];
64
89
    let mut domain: Option<DomainPtr> = None;
65
158
    for child in named_children(node) {
66
158
        if child.kind() == "arithmetic_expr"
67
158
            || child.kind() == "bool_expr"
68
158
            || child.kind() == "comparison_expr"
69
158
            || child.kind() == "atom"
70
        {
71
146
            let Some(expr) = parse_expression(ctx, child)? else {
72
66
                return Ok(None);
73
            };
74
80
            elements.push(expr);
75
        } else {
76
12
            let Some(parsed_domain) = parse_domain(ctx, child)? else {
77
                return Ok(None);
78
            };
79
12
            domain = Some(parsed_domain);
80
        }
81
    }
82
23
    if domain.is_none() {
83
11
        let count = elements.len() as i32;
84
11
        domain = Some(domain_int!(1..count));
85
23
    }
86

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

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