meplang 0.1.8

An EVM low-level language that gives full control over the control flow of the smart contract.
Documentation
use pest::iterators::Pair;
use quick_impl::QuickImpl;

use super::variable::{RVariable, RVariableWithField};
use super::{RConcatenation, RHexAlias};
use crate::parser::parser::{get_next, map_unique_child, FromPair, Located, Rule};

#[derive(Debug, Clone, QuickImpl)]
pub enum RFunctionArg {
    #[quick_impl(impl From)]
    VariableWithField(RVariableWithField),
    #[quick_impl(impl From)]
    VariablesConcat(RConcatenation),
    #[quick_impl(impl From)]
    HexAlias(RHexAlias),
}

impl FromPair for RFunctionArg {
    fn from_pair(function_arg: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
        assert!(function_arg.as_rule() == Rule::function_arg);

        map_unique_child(function_arg, |child| match child.as_rule() {
            Rule::variable_with_field => Ok(RVariableWithField::from_pair(child)?.into()),
            Rule::concatenation => Ok(RConcatenation::from_pair(child)?.into()),
            Rule::hex_alias => Ok(RHexAlias::from_pair(child)?.into()),
            _ => unreachable!(),
        })
    }
}

#[derive(Debug, Clone)]
pub struct RFunction {
    pub name: Located<RVariable>,
    pub arg: Located<RFunctionArg>,
}

impl FromPair for RFunction {
    fn from_pair(function: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
        assert!(function.as_rule() == Rule::function);

        let mut function_inner = function.into_inner();

        let name = Located::<RVariable>::from_pair(get_next(&mut function_inner, Rule::variable))?;

        _ = get_next(&mut function_inner, Rule::open_paren);

        let arg = Located::<RFunctionArg>::from_pair(get_next(&mut function_inner, Rule::function_arg))?;

        _ = get_next(&mut function_inner, Rule::close_paren);
        assert!(function_inner.next() == None);

        Ok(Self { name, arg })
    }
}