use crate::ast::*; use crate::parser::*; use nom::branch::*; use nom::combinator::*; use nom::multi::*; use nom::sequence::*; use nom::IResult; // ----------------------------------------------------------------------------- #[derive(Debug, Node)] pub struct LetDeclaration<'a> { pub nodes: ( Symbol<'a>, LetIdentifier<'a>, Option>>>, Symbol<'a>, Expression<'a>, Symbol<'a>, ), } #[derive(Debug, Node)] pub struct LetIdentifier<'a> { pub nodes: (Identifier<'a>,), } #[derive(Debug, Node)] pub struct LetPortList<'a> { pub nodes: (List, LetPortItem<'a>>,), } #[derive(Debug, Node)] pub struct LetPortItem<'a> { pub nodes: ( Vec>, LetFormalType<'a>, FormalPortIdentifier<'a>, Vec>, Option<(Symbol<'a>, Expression<'a>)>, ), } #[derive(Debug, Node)] pub enum LetFormalType<'a> { DataTypeOrImplicit(DataTypeOrImplicit<'a>), Untyped(Symbol<'a>), } #[derive(Debug, Node)] pub struct LetExpression<'a> { pub nodes: ( Option>, LetIdentifier<'a>, Option>>>, ), } #[derive(Debug, Node)] pub enum LetListOfArguments<'a> { Ordered(LetListOfArgumentsOrdered<'a>), Named(LetListOfArgumentsNamed<'a>), } #[derive(Debug, Node)] pub struct LetListOfArgumentsOrdered<'a> { pub nodes: ( List, Option>>, Vec<( Symbol<'a>, Symbol<'a>, Identifier<'a>, Paren<'a, Option>>, )>, ), } #[derive(Debug, Node)] pub struct LetListOfArgumentsNamed<'a> { pub nodes: ( List< Symbol<'a>, ( Symbol<'a>, Identifier<'a>, Paren<'a, Option>>, ), >, ), } #[derive(Debug, Node)] pub struct LetActualArg<'a> { pub nodes: (Expression<'a>,), } // ----------------------------------------------------------------------------- pub fn let_declaration(s: Span) -> IResult { let (s, a) = symbol("let")(s)?; let (s, b) = let_identifier(s)?; let (s, c) = opt(paren(opt(let_port_list)))(s)?; let (s, d) = symbol("=")(s)?; let (s, e) = expression(s)?; let (s, f) = symbol(";")(s)?; Ok(( s, LetDeclaration { nodes: (a, b, c, d, e, f), }, )) } pub fn let_identifier(s: Span) -> IResult { let (s, a) = identifier(s)?; Ok((s, LetIdentifier { nodes: (a,) })) } pub fn let_port_list(s: Span) -> IResult { let (s, a) = list(symbol(","), let_port_item)(s)?; Ok((s, LetPortList { nodes: (a,) })) } pub fn let_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; let (s, b) = let_formal_type(s)?; let (s, c) = formal_port_identifier(s)?; let (s, d) = many0(variable_dimension)(s)?; let (s, e) = opt(pair(symbol("="), expression))(s)?; Ok(( s, LetPortItem { nodes: (a, b, c, d, e), }, )) } pub fn let_formal_type(s: Span) -> IResult { alt(( map(data_type_or_implicit, |x| { LetFormalType::DataTypeOrImplicit(x) }), map(symbol("untyped"), |x| LetFormalType::Untyped(x)), ))(s) } pub fn let_expression(s: Span) -> IResult { let (s, a) = opt(package_scope)(s)?; let (s, b) = let_identifier(s)?; let (s, c) = opt(paren(opt(let_list_of_arguments)))(s)?; Ok((s, LetExpression { nodes: (a, b, c) })) } pub fn let_list_of_arguments(s: Span) -> IResult { alt((let_list_of_arguments_ordered, let_list_of_arguments_named))(s) } pub fn let_list_of_arguments_ordered(s: Span) -> IResult { let (s, a) = list(symbol(","), opt(let_actual_arg))(s)?; let (s, b) = many0(tuple(( symbol(","), symbol("."), identifier, paren(opt(let_actual_arg)), )))(s)?; Ok(( s, LetListOfArguments::Ordered(LetListOfArgumentsOrdered { nodes: (a, b) }), )) } pub fn let_list_of_arguments_named(s: Span) -> IResult { let (s, a) = list( symbol(","), triple(symbol("."), identifier, paren(opt(let_actual_arg))), )(s)?; Ok(( s, LetListOfArguments::Named(LetListOfArgumentsNamed { nodes: (a,) }), )) } pub fn let_actual_arg(s: Span) -> IResult { let (s, a) = expression(s)?; Ok((s, LetActualArg { nodes: (a,) })) }