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

            
9
598
pub fn parse_abstract(
10
598
    node: &Node,
11
598
    source_code: &str,
12
598
    symbols_ptr: Option<SymbolTablePtr>,
13
598
) -> Result<AbstractLiteral<Expression>, EssenceParseError> {
14
598
    match node.kind() {
15
598
        "record" => parse_record(node, source_code, symbols_ptr),
16
598
        "tuple" => parse_tuple(node, source_code, symbols_ptr),
17
598
        "matrix" => parse_matrix(node, source_code, symbols_ptr),
18
594
        "set_literal" => parse_set_literal(node, source_code, symbols_ptr),
19
        _ => Err(EssenceParseError::syntax_error(
20
            format!("Expected abstract literal, got: '{}'", node.kind()),
21
            Some(node.range()),
22
        )),
23
    }
24
598
}
25

            
26
fn parse_record(
27
    node: &Node,
28
    source_code: &str,
29
    symbols_ptr: Option<SymbolTablePtr>,
30
) -> Result<AbstractLiteral<Expression>, EssenceParseError> {
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 = &source_code[name_node.start_byte()..name_node.end_byte()];
35
        let name = conjure_cp_core::ast::Name::user(name_str);
36

            
37
        let value: Expression = parse_expression(
38
            field!(child, "value"),
39
            source_code,
40
            node,
41
            symbols_ptr.clone(),
42
        )?;
43
        values.push(conjure_cp_core::ast::records::RecordValue { name, value });
44
    }
45
    Ok(AbstractLiteral::Record(values))
46
}
47

            
48
fn parse_tuple(
49
    node: &Node,
50
    source_code: &str,
51
    symbols_ptr: Option<SymbolTablePtr>,
52
) -> Result<AbstractLiteral<Expression>, EssenceParseError> {
53
    let mut elements = Vec::new();
54
    for child in named_children(node) {
55
        elements.push(parse_expression(
56
            child,
57
            source_code,
58
            node,
59
            symbols_ptr.clone(),
60
        )?);
61
    }
62
    Ok(AbstractLiteral::Tuple(elements))
63
}
64

            
65
4
fn parse_matrix(
66
4
    node: &Node,
67
4
    source_code: &str,
68
4
    symbols_ptr: Option<SymbolTablePtr>,
69
4
) -> Result<AbstractLiteral<Expression>, EssenceParseError> {
70
4
    let mut elements = vec![];
71
4
    let mut domain: Option<DomainPtr> = None;
72
16
    for child in named_children(node) {
73
16
        if child.kind() == "arithmetic_expr"
74
16
            || child.kind() == "bool_expr"
75
16
            || child.kind() == "comparison_expr"
76
16
            || child.kind() == "atom"
77
        {
78
12
            elements.push(parse_expression(
79
12
                child,
80
12
                source_code,
81
12
                node,
82
12
                symbols_ptr.clone(),
83
            )?);
84
        } else {
85
4
            domain = Some(parse_domain(child, source_code, symbols_ptr.clone())?);
86
        }
87
    }
88
4
    if domain.is_none() {
89
        let count = elements.len() as i32;
90
        domain = Some(domain_int!(1..count));
91
4
    }
92

            
93
4
    Ok(AbstractLiteral::Matrix(elements, domain.unwrap()))
94
4
}
95

            
96
594
fn parse_set_literal(
97
594
    node: &Node,
98
594
    source_code: &str,
99
594
    symbols_ptr: Option<SymbolTablePtr>,
100
594
) -> Result<AbstractLiteral<Expression>, EssenceParseError> {
101
594
    let mut elements = Vec::new();
102
1540
    for child in named_children(node) {
103
1540
        elements.push(parse_expression(
104
1540
            child,
105
1540
            source_code,
106
1540
            node,
107
1540
            symbols_ptr.clone(),
108
        )?);
109
    }
110
594
    Ok(AbstractLiteral::Set(elements))
111
594
}