1
use crate::errors::FatalParseError;
2
use crate::expression::parse_expression;
3
use crate::field;
4
use crate::parser::ParseContext;
5
use crate::util::TypecheckingContext;
6
use conjure_cp_core::ast::{Objective, OptimiseDirection};
7
use tree_sitter::Node;
8

            
9
17665
pub fn parse_objective_statement(
10
17665
    ctx: &mut ParseContext,
11
17665
    node: &Node,
12
17665
) -> Result<Option<Objective>, FatalParseError> {
13
17665
    let direction_node = field!(node, "direction");
14
17665
    let direction_str = &ctx.source_code[direction_node.start_byte()..direction_node.end_byte()];
15
17665
    let direction = match direction_str {
16
10513
        "minimising" => OptimiseDirection::Minimising,
17
7152
        "maximising" => OptimiseDirection::Maximising,
18
        _ => {
19
            return Err(FatalParseError::internal_error(
20
                format!("Unexpected objective direction: '{direction_str}'"),
21
                Some(direction_node.range()),
22
            ));
23
        }
24
    };
25

            
26
17665
    let Some(expression_node) = field!(recover, ctx, node, "expression") else {
27
        return Ok(None);
28
    };
29

            
30
17665
    let saved_context = ctx.typechecking_context;
31
17665
    let saved_inner_context = ctx.inner_typechecking_context;
32
17665
    ctx.typechecking_context = TypecheckingContext::Unknown;
33
17665
    ctx.inner_typechecking_context = TypecheckingContext::Unknown;
34

            
35
17665
    let parsed = parse_expression(ctx, expression_node);
36

            
37
17665
    ctx.typechecking_context = saved_context;
38
17665
    ctx.inner_typechecking_context = saved_inner_context;
39

            
40
17665
    let Some(expression) = parsed? else {
41
        return Ok(None);
42
    };
43

            
44
17665
    Ok(Some(Objective {
45
17665
        direction,
46
17665
        expression,
47
17665
    }))
48
17665
}