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 enum FunctionDataTypeOrImplicit<'a> { DataTypeOrVoid(DataTypeOrVoid<'a>), ImplicitDataType(ImplicitDataType<'a>), } #[derive(Debug, Node)] pub struct FunctionDeclaration<'a> { pub nodes: ( Symbol<'a>, Option>, FunctionBodyDeclaration<'a>, ), } #[derive(Debug, Node)] pub enum FunctionBodyDeclaration<'a> { WithoutPort(FunctionBodyDeclarationWithoutPort<'a>), WithPort(FunctionBodyDeclarationWithPort<'a>), } #[derive(Debug, Node)] pub struct FunctionBodyDeclarationWithoutPort<'a> { pub nodes: ( FunctionDataTypeOrImplicit<'a>, Option>, FunctionIdentifier<'a>, Symbol<'a>, Vec>, Vec>, Symbol<'a>, Option<(Symbol<'a>, FunctionIdentifier<'a>)>, ), } #[derive(Debug, Node)] pub struct FunctionBodyDeclarationWithPort<'a> { pub nodes: ( FunctionDataTypeOrImplicit<'a>, Option>, FunctionIdentifier<'a>, Paren<'a, Option>>, Symbol<'a>, Vec>, Vec>, Symbol<'a>, Option<(Symbol<'a>, FunctionIdentifier<'a>)>, ), } #[derive(Debug, Node)] pub enum InterfaceIdentifierOrClassScope<'a> { InterfaceIdentifier((InterfaceIdentifier<'a>, Symbol<'a>)), ClassScope(ClassScope<'a>), } #[derive(Debug, Node)] pub struct FunctionPrototype<'a> { pub nodes: ( Symbol<'a>, DataTypeOrVoid<'a>, FunctionIdentifier<'a>, Option>>>, ), } #[derive(Debug, Node)] pub enum DpiImportExport<'a> { ImportFunction(DpiImportExportImportFunction<'a>), ImportTask(DpiImportExportImportTask<'a>), ExportFunction(DpiImportExportExportFunction<'a>), ExportTask(DpiImportExportExportTask<'a>), } #[derive(Debug, Node)] pub struct DpiImportExportImportFunction<'a> { pub nodes: ( Symbol<'a>, DpiSpecString<'a>, Option>, Option<(CIdentifier<'a>, Symbol<'a>)>, DpiFunctionProto<'a>, Symbol<'a>, ), } #[derive(Debug, Node)] pub struct DpiImportExportImportTask<'a> { pub nodes: ( Symbol<'a>, DpiSpecString<'a>, Option>, Option<(CIdentifier<'a>, Symbol<'a>)>, DpiTaskProto<'a>, Symbol<'a>, ), } #[derive(Debug, Node)] pub struct DpiImportExportExportFunction<'a> { pub nodes: ( Symbol<'a>, DpiSpecString<'a>, Option<(CIdentifier<'a>, Symbol<'a>)>, Symbol<'a>, FunctionIdentifier<'a>, Symbol<'a>, ), } #[derive(Debug, Node)] pub struct DpiImportExportExportTask<'a> { pub nodes: ( Symbol<'a>, DpiSpecString<'a>, Option<(CIdentifier<'a>, Symbol<'a>)>, Symbol<'a>, TaskIdentifier<'a>, Symbol<'a>, ), } #[derive(Debug, Node)] pub enum DpiSpecString<'a> { DpiC(Symbol<'a>), Dpi(Symbol<'a>), } #[derive(Debug, Node)] pub enum DpiFunctionImportProperty<'a> { Context(Symbol<'a>), Pure(Symbol<'a>), } #[derive(Debug, Node)] pub enum DpiTaskImportProperty<'a> { Context(Symbol<'a>), } #[derive(Debug, Node)] pub struct DpiFunctionProto<'a> { pub nodes: (FunctionPrototype<'a>,), } #[derive(Debug, Node)] pub struct DpiTaskProto<'a> { pub nodes: (TaskPrototype<'a>,), } // ----------------------------------------------------------------------------- #[trace] pub fn function_data_type_or_implicit(s: Span) -> IResult { alt(( map(data_type_or_void, |x| { FunctionDataTypeOrImplicit::DataTypeOrVoid(x) }), map(implicit_data_type, |x| { FunctionDataTypeOrImplicit::ImplicitDataType(x) }), ))(s) } #[trace] pub fn function_declaration(s: Span) -> IResult { let (s, a) = symbol("function")(s)?; let (s, b) = opt(lifetime)(s)?; let (s, c) = function_body_declaration(s)?; Ok((s, FunctionDeclaration { nodes: (a, b, c) })) } #[trace] pub fn function_body_declaration(s: Span) -> IResult { alt(( function_body_declaration_without_port, function_body_declaration_with_port, ))(s) } #[trace] pub fn function_body_declaration_without_port(s: Span) -> IResult { let (s, a) = function_data_type_or_implicit(s)?; let (s, b) = opt(interface_identifier_or_class_scope)(s)?; let (s, c) = function_identifier(s)?; let (s, d) = symbol(";")(s)?; let (s, e) = many0(tf_item_declaration)(s)?; let (s, f) = many0(function_statement_or_null)(s)?; let (s, g) = symbol("endfunction")(s)?; let (s, h) = opt(pair(symbol(":"), function_identifier))(s)?; Ok(( s, FunctionBodyDeclaration::WithoutPort(FunctionBodyDeclarationWithoutPort { nodes: (a, b, c, d, e, f, g, h), }), )) } #[trace] pub fn function_body_declaration_with_port(s: Span) -> IResult { let (s, a) = function_data_type_or_implicit(s)?; let (s, b) = opt(interface_identifier_or_class_scope)(s)?; let (s, c) = function_identifier(s)?; let (s, d) = paren(opt(tf_port_list))(s)?; let (s, e) = symbol(";")(s)?; let (s, f) = many0(block_item_declaration)(s)?; let (s, g) = many0(function_statement_or_null)(s)?; let (s, h) = symbol("endfunction")(s)?; let (s, i) = opt(pair(symbol(":"), function_identifier))(s)?; Ok(( s, FunctionBodyDeclaration::WithPort(FunctionBodyDeclarationWithPort { nodes: (a, b, c, d, e, f, g, h, i), }), )) } #[trace] pub fn interface_identifier_or_class_scope( s: Span, ) -> IResult { alt(( map(pair(interface_identifier, symbol(".")), |x| { InterfaceIdentifierOrClassScope::InterfaceIdentifier(x) }), map(class_scope, |x| { InterfaceIdentifierOrClassScope::ClassScope(x) }), ))(s) } #[trace] pub fn function_prototype(s: Span) -> IResult { let (s, a) = symbol("function")(s)?; let (s, b) = data_type_or_void(s)?; let (s, c) = function_identifier(s)?; let (s, d) = opt(paren(opt(tf_port_list)))(s)?; Ok(( s, FunctionPrototype { nodes: (a, b, c, d), }, )) } #[trace] pub fn dpi_import_export(s: Span) -> IResult { alt(( dpi_import_export_import_function, dpi_import_export_import_task, dpi_import_export_export_function, dpi_import_export_export_task, ))(s) } #[trace] pub fn dpi_import_export_import_function(s: Span) -> IResult { let (s, a) = symbol("import")(s)?; let (s, b) = dpi_spec_string(s)?; let (s, c) = opt(dpi_function_import_property)(s)?; let (s, d) = opt(pair(c_identifier, symbol("=")))(s)?; let (s, e) = dpi_function_proto(s)?; let (s, f) = symbol(";")(s)?; Ok(( s, DpiImportExport::ImportFunction(DpiImportExportImportFunction { nodes: (a, b, c, d, e, f), }), )) } #[trace] pub fn dpi_import_export_import_task(s: Span) -> IResult { let (s, a) = symbol("import")(s)?; let (s, b) = dpi_spec_string(s)?; let (s, c) = opt(dpi_task_import_property)(s)?; let (s, d) = opt(pair(c_identifier, symbol("=")))(s)?; let (s, e) = dpi_task_proto(s)?; let (s, f) = symbol(";")(s)?; Ok(( s, DpiImportExport::ImportTask(DpiImportExportImportTask { nodes: (a, b, c, d, e, f), }), )) } #[trace] pub fn dpi_import_export_export_function(s: Span) -> IResult { let (s, a) = symbol("export")(s)?; let (s, b) = dpi_spec_string(s)?; let (s, c) = opt(pair(c_identifier, symbol("=")))(s)?; let (s, d) = symbol("function")(s)?; let (s, e) = function_identifier(s)?; let (s, f) = symbol(";")(s)?; Ok(( s, DpiImportExport::ExportFunction(DpiImportExportExportFunction { nodes: (a, b, c, d, e, f), }), )) } #[trace] pub fn dpi_import_export_export_task(s: Span) -> IResult { let (s, a) = symbol("export")(s)?; let (s, b) = dpi_spec_string(s)?; let (s, c) = opt(pair(c_identifier, symbol("=")))(s)?; let (s, d) = symbol("task")(s)?; let (s, e) = task_identifier(s)?; let (s, f) = symbol(";")(s)?; Ok(( s, DpiImportExport::ExportTask(DpiImportExportExportTask { nodes: (a, b, c, d, e, f), }), )) } #[trace] pub fn dpi_spec_string(s: Span) -> IResult { alt(( map(symbol("DPI-C"), |x| DpiSpecString::DpiC(x)), map(symbol("DPI"), |x| DpiSpecString::Dpi(x)), ))(s) } #[trace] pub fn dpi_function_import_property(s: Span) -> IResult { alt(( map(symbol("context"), |x| DpiFunctionImportProperty::Context(x)), map(symbol("pure"), |x| DpiFunctionImportProperty::Pure(x)), ))(s) } #[trace] pub fn dpi_task_import_property(s: Span) -> IResult { let (s, a) = symbol("context")(s)?; Ok((s, DpiTaskImportProperty::Context(a))) } #[trace] pub fn dpi_function_proto(s: Span) -> IResult { let (s, a) = function_prototype(s)?; Ok((s, DpiFunctionProto { nodes: (a,) })) } #[trace] pub fn dpi_task_proto(s: Span) -> IResult { let (s, a) = task_prototype(s)?; Ok((s, DpiTaskProto { nodes: (a,) })) }