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, SymbolTable};
6
use conjure_cp_core::{domain_int, range};
7
use std::cell::RefCell;
8
use std::rc::Rc;
9
use tree_sitter::Node;
10

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

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

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

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

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

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

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