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

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

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

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

            
52
fn parse_tuple(
53
    node: &Node,
54
    source_code: &str,
55
    symbols_ptr: Option<SymbolTablePtr>,
56
    errors: &mut Vec<RecoverableParseError>,
57
) -> Result<AbstractLiteral<Expression>, FatalParseError> {
58
    let mut elements = Vec::new();
59
4
    for child in named_children(node) {
60
4
        elements.push(parse_expression(
61
4
            child,
62
4
            source_code,
63
4
            node,
64
4
            symbols_ptr.clone(),
65
16
            errors,
66
16
        )?);
67
16
    }
68
16
    Ok(AbstractLiteral::Tuple(elements))
69
16
}
70

            
71
16
fn parse_matrix(
72
4
    node: &Node,
73
4
    source_code: &str,
74
16
    symbols_ptr: Option<SymbolTablePtr>,
75
4
    errors: &mut Vec<RecoverableParseError>,
76
8
) -> Result<AbstractLiteral<Expression>, FatalParseError> {
77
4
    let mut elements = vec![];
78
4
    let mut domain: Option<DomainPtr> = None;
79
20
    for child in named_children(node) {
80
16
        if child.kind() == "arithmetic_expr"
81
16
            || child.kind() == "bool_expr"
82
20
            || child.kind() == "comparison_expr"
83
16
            || child.kind() == "atom"
84
        {
85
16
            elements.push(parse_expression(
86
12
                child,
87
16
                source_code,
88
16
                node,
89
12
                symbols_ptr.clone(),
90
606
                errors,
91
594
            )?);
92
594
        } else {
93
598
            domain = Some(parse_domain(
94
598
                child,
95
1544
                source_code,
96
1544
                symbols_ptr.clone(),
97
4
                errors,
98
            )?);
99
1540
        }
100
    }
101
598
    if domain.is_none() {
102
594
        let count = elements.len() as i32;
103
        domain = Some(domain_int!(1..count));
104
4
    }
105

            
106
4
    Ok(AbstractLiteral::Matrix(elements, domain.unwrap()))
107
4
}
108

            
109
594
fn parse_set_literal(
110
594
    node: &Node,
111
594
    source_code: &str,
112
594
    symbols_ptr: Option<SymbolTablePtr>,
113
594
    errors: &mut Vec<RecoverableParseError>,
114
594
) -> Result<AbstractLiteral<Expression>, FatalParseError> {
115
594
    let mut elements = Vec::new();
116
1540
    for child in named_children(node) {
117
1540
        elements.push(parse_expression(
118
1540
            child,
119
1540
            source_code,
120
1540
            node,
121
1540
            symbols_ptr.clone(),
122
1540
            errors,
123
        )?);
124
    }
125
594
    Ok(AbstractLiteral::Set(elements))
126
594
}