teo-parser 0.3.0

Parser for Teo schema language
Documentation
use crate::ast::arith_expr::{ArithExpr, BinaryOperation, ArithExprOperator, UnaryOperation, UnaryPostfixOperation};
use crate::{parse_container_node_variables_cleanup, parse_container_node_variables_without_span, parse_insert_operator};
use crate::parser::parse_expression::parse_expression;
use crate::parser::parse_span::parse_span;
use crate::parser::parser_context::ParserContext;
use crate::parser::pest_parser::{Pair, EXPR_PRATT_PARSER, Rule};
use crate::traits::identifiable::Identifiable;

pub(super) fn parse_arith_expr(pair: Pair<'_>, context: &ParserContext) -> ArithExpr {
    let span = parse_span(&pair);
    let result = EXPR_PRATT_PARSER.map_primary(|primary| match primary.as_rule() {
        Rule::operand => {
            let expression = parse_expression(primary, context);
            ArithExpr::Expression(Box::new(expression))
        },
        _ => {
            context.insert_unparsed(parse_span(&primary));
            unreachable!()
        },
    }).map_prefix(|operator, rhs| {
        let (path, mut children) = parse_container_node_variables_without_span!(context);
        let op = match operator.as_rule() {
            Rule::BI_NEG => ArithExprOperator::BitNeg,
            Rule::NEG => ArithExprOperator::Neg,
            Rule::NOT => ArithExprOperator::Not,
            _ => unreachable!(),
        };
        parse_insert_operator!(context, operator, children, operator.as_str());
        let rhs_id = rhs.id();
        children.insert(rhs_id, rhs.into());
        let operation = UnaryOperation {
            span,
            path,
            children,
            op,
            rhs: rhs_id,
        };
        parse_container_node_variables_cleanup!(context);
        ArithExpr::UnaryOperation(operation)
    }).map_infix(|lhs, operator, rhs| {
        let op = match operator.as_rule() {
            Rule::ADD => ArithExprOperator::Add,
            Rule::SUB => ArithExprOperator::Sub,
            Rule::MUL => ArithExprOperator::Mul,
            Rule::DIV => ArithExprOperator::Div,
            Rule::MOD => ArithExprOperator::Mod,
            Rule::BI_AND => ArithExprOperator::BitAnd,
            Rule::BI_XOR => ArithExprOperator::BitXor,
            Rule::BI_OR => ArithExprOperator::BitOr,
            Rule::NULLISH_COALESCING => ArithExprOperator::NullishCoalescing,
            Rule::BI_LS => ArithExprOperator::BitLS,
            Rule::BI_RS => ArithExprOperator::BitRS,
            Rule::AND => ArithExprOperator::And,
            Rule::OR => ArithExprOperator::Or,
            Rule::GT => ArithExprOperator::Gt,
            Rule::GTE => ArithExprOperator::Gte,
            Rule::LT => ArithExprOperator::Lt,
            Rule::LTE => ArithExprOperator::Lte,
            Rule::EQ => ArithExprOperator::Eq,
            Rule::NEQ => ArithExprOperator::Neq,
            Rule::RANGE_CLOSE => ArithExprOperator::RangeClose,
            Rule::RANGE_OPEN => ArithExprOperator::RangeOpen,
            _ => unreachable!(),
        };
        let (path, mut children) = parse_container_node_variables_without_span!(context);
        let lhs_id = lhs.id();
        let rhs_id = rhs.id();
        children.insert(lhs_id, lhs.into());
        parse_insert_operator!(context, operator, children, operator.as_str());
        children.insert(rhs_id, rhs.into());
        let operation = BinaryOperation {
            span,
            path,
            children,
            op,
            lhs: lhs_id,
            rhs: rhs_id,
        };
        parse_container_node_variables_cleanup!(context);
        ArithExpr::BinaryOperation(operation)
    }).map_postfix(|lhs, operator| {
        let op = match operator.as_rule() {
            Rule::FORCE_UNWRAP => ArithExprOperator::ForceUnwrap,
            _ => unreachable!(),
        };
        let (path, mut children) = parse_container_node_variables_without_span!(context);
        let lhs_id = lhs.id();
        children.insert(lhs_id, lhs.into());
        parse_insert_operator!(context, operator, children, operator.as_str());
        let operation = UnaryPostfixOperation {
            span,
            path,
            children,
            op,
            lhs: lhs_id,
        };
        parse_container_node_variables_cleanup!(context);
        ArithExpr::UnaryPostfixOperation(operation)
    }).parse(pair.into_inner());
    result
}