(
context: &mut ParserContext,
env: &mut Environment,
tokens: &[Token],
position: &mut usize,
)
| 2956 | } |
| 2957 | |
| 2958 | fn parse_prefix_unary_expression( |
| 2959 | context: &mut ParserContext, |
| 2960 | env: &mut Environment, |
| 2961 | tokens: &[Token], |
| 2962 | position: &mut usize, |
| 2963 | ) -> Result<Box<dyn Expr>, Box<Diagnostic>> { |
| 2964 | if *position < tokens.len() && is_prefix_unary_operator(&tokens[*position]) { |
| 2965 | let operator = &tokens[*position]; |
| 2966 | |
| 2967 | // Consume `+`, `-`, `!`, `~` operator |
| 2968 | *position += 1; |
| 2969 | |
| 2970 | let rhs = parse_prefix_unary_expression(context, env, tokens, position)?; |
| 2971 | let rhs_type = rhs.expr_type(); |
| 2972 | |
| 2973 | // Parse and Check side for unary `+` operator |
| 2974 | if operator.kind == TokenKind::Plus { |
| 2975 | // Can perform this operator between RHS |
| 2976 | if rhs_type.can_perform_plus_op() { |
| 2977 | return Ok(Box::new(UnaryExpr { |
| 2978 | right: rhs, |
| 2979 | operator: PrefixUnaryOperator::Plus, |
| 2980 | result_type: rhs_type.neg_op_result_type(), |
| 2981 | })); |
| 2982 | } |
| 2983 | |
| 2984 | // Return error if this operator can't be performed even with implicit cast |
| 2985 | return Err(Diagnostic::error(&format!( |
| 2986 | "Operator unary `+` can't be performed on type `{rhs_type}`" |
| 2987 | )) |
| 2988 | .with_location(operator.location) |
| 2989 | .as_boxed()); |
| 2990 | } |
| 2991 | |
| 2992 | // Parse and Check side for unary `-` operator |
| 2993 | if operator.kind == TokenKind::Minus { |
| 2994 | // Can perform this operator between RHS |
| 2995 | if rhs_type.can_perform_neg_op() { |
| 2996 | return Ok(Box::new(UnaryExpr { |
| 2997 | right: rhs, |
| 2998 | operator: PrefixUnaryOperator::Minus, |
| 2999 | result_type: rhs_type.neg_op_result_type(), |
| 3000 | })); |
| 3001 | } |
| 3002 | |
| 3003 | // Return error if this operator can't be performed even with implicit cast |
| 3004 | return Err(Diagnostic::error(&format!( |
| 3005 | "Operator unary `-` can't be performed on type `{rhs_type}`" |
| 3006 | )) |
| 3007 | .with_location(operator.location) |
| 3008 | .as_boxed()); |
| 3009 | } |
| 3010 | |
| 3011 | // Parse and Check side for unary `!`or `NOT` operator |
| 3012 | if operator.kind == TokenKind::Bang || operator.kind == TokenKind::Not { |
| 3013 | // Can perform this operator between RHS |
| 3014 | if rhs_type.can_perform_bang_op() { |
| 3015 | return Ok(Box::new(UnaryExpr { |
no test coverage detected
searching dependent graphs…