// (C) Copyright 2016 Jethro G. Beekman
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A C expression parser and evaluator.
//!
//! This crate provides methods for parsing and evaluating simple C expressions. In general, the
//! crate can handle most arithmetic expressions that would appear in macros or the definition of
//! constants, as well as string and character constants.
//!
//! The main entry point for is [`token::parse`], which parses a byte string and returns its
//! evaluated value.
#![warn(rust_2018_idioms)]
#![warn(missing_docs)]
#![allow(deprecated)]

pub mod nom {
    //! nom's result types, re-exported.
    pub use nom::{error::ErrorKind, Err, IResult, Needed};
}
pub mod expr;
pub mod literal;
pub mod token;

/// Parsing errors specific to C parsing
#[derive(Debug)]
pub enum ErrorKind {
    /// Expected the specified token
    ExactToken(token::Kind, &'static [u8]),
    /// Expected one of the specified tokens
    ExactTokens(token::Kind, &'static [&'static str]),
    /// Expected a token of the specified kind
    TypedToken(token::Kind),
    /// An unknown identifier was encountered
    UnknownIdentifier,
    /// An invalid literal was encountered.
    ///
    /// When encountered, this generally means a bug exists in the data that
    /// was passed in or the parsing logic.
    InvalidLiteral,
    /// A full parse was requested, but data was left over after parsing finished.
    Partial,
    /// An error occurred in an underlying nom parser.
    Parser(nom::ErrorKind),
}

impl From<nom::ErrorKind> for ErrorKind {
    fn from(k: nom::ErrorKind) -> Self {
        ErrorKind::Parser(k)
    }
}

impl From<u32> for ErrorKind {
    fn from(_: u32) -> Self {
        ErrorKind::InvalidLiteral
    }
}

/// Parsing errors specific to C parsing.
///
/// This is a superset of `(I, nom::ErrorKind)` that includes the additional errors specified by
/// [`ErrorKind`].
#[derive(Debug)]
pub struct Error<I> {
    /// The remainder of the input stream at the time of the error.
    pub input: I,
    /// The error that occurred.
    pub error: ErrorKind,
}

impl<I> From<(I, nom::ErrorKind)> for Error<I> {
    fn from(e: (I, nom::ErrorKind)) -> Self {
        Self::from((e.0, ErrorKind::from(e.1)))
    }
}

impl<I> From<(I, ErrorKind)> for Error<I> {
    fn from(e: (I, ErrorKind)) -> Self {
        Self {
            input: e.0,
            error: e.1,
        }
    }
}

impl<I> ::nom::error::ParseError<I> for Error<I> {
    fn from_error_kind(input: I, kind: nom::ErrorKind) -> Self {
        Self {
            input,
            error: kind.into(),
        }
    }

    fn append(_: I, _: nom::ErrorKind, other: Self) -> Self {
        other
    }
}

// in lieu of https://github.com/Geal/nom/issues/1010
trait ToCexprResult<I, O> {
    fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>>;
}
impl<I, O, E> ToCexprResult<I, O> for nom::IResult<I, O, E>
where
    Error<I>: From<E>,
{
    fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>> {
        match self {
            Ok(v) => Ok(v),
            Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)),
            Err(nom::Err::Error(e)) => Err(nom::Err::Error(e.into())),
            Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e.into())),
        }
    }
}

/// If the input result indicates a succesful parse, but there is data left,
/// return an `Error::Partial` instead.
pub fn assert_full_parse<'i, I: 'i, O, E>(
    result: nom::IResult<&'i [I], O, E>,
) -> nom::IResult<&'i [I], O, Error<&'i [I]>>
where
    Error<&'i [I]>: From<E>,
{
    match result.to_cexpr_result() {
        Ok((rem, output)) => {
            if rem.is_empty() {
                Ok((rem, output))
            } else {
                Err(nom::Err::Error((rem, ErrorKind::Partial).into()))
            }
        }
        Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)),
        Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e)),
        Err(nom::Err::Error(e)) => Err(nom::Err::Error(e)),
    }
}
