diff --git a/src/parser.rs b/src/parser.rs index 84cf349..ecf3b48 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,3 +1,4 @@ +pub mod declaration; pub mod error; pub mod expression; mod literals; @@ -24,85 +25,13 @@ pub type IErr = GreedyError; // custom IResult type for VerboseError pub type IResult> = nom::IResult; +pub use crate::parser::declaration::{ + assign_statement, declaration, typename, Assign, NetDecl, TypeName, +}; pub use crate::parser::expression::{expression, Call, Expression, Operation}; pub use crate::parser::module::{module, Module, ModuleItem, PortDirection}; use crate::parser::tokens::{token, TokenKind as tk, TokenSpan}; -fn ws0<'a, F: 'a, O, E: ParseError>>( - inner: F, -) -> impl FnMut(Span<'a>) -> IResult, O, E> -where - F: FnMut(Span<'a>) -> IResult, O, E>, -{ - delimited(multispace0, inner, multispace0) -} - -fn identifier(input: Span) -> IResult { - recognize(pair( - alt((alpha1, tag("_"))), - many0(alt((alphanumeric1, tag("_")))), - ))(input) -} - -// TODO: allow recursive generics -// TODO: allow expressions again -fn typename(input: TokenSpan) -> IResult { - map( - tuple(( - token(tk::Ident), - opt(delimited(token(tk::LAngle), expression, token(tk::RAngle))), - )), - |(ident, _)| TypeName { - name: ident.span(), - generics: (), - }, - )(input) -} - -#[derive(Debug)] -pub struct TypeName<'a> { - name: Span<'a>, - generics: (), -} - -#[derive(Debug)] -pub struct NetDecl<'a> { - pub name: Span<'a>, - pub typ: TypeName<'a>, - pub value: Option>, -} - -#[derive(Debug)] -pub struct Assign<'a> { - pub lhs: &'a str, - pub expr: Expression<'a>, -} - -fn assign_statement(input: TokenSpan) -> IResult { - map( - separated_pair(token(tk::Ident), token(tk::EqAssign), expression), - |(lhs, expr)| Assign { - lhs: (*lhs.span().fragment()), - expr, - }, - )(input) -} - -// TODO: reallow assignments -fn declaration(i: TokenSpan) -> IResult { - map( - tuple(( - separated_pair(token(tk::Ident), token(tk::Colon), typename), - opt(preceded(token(tk::Assign), token(tk::Number))), - )), - |((ident, typ), _value)| NetDecl { - name: ident.span(), - typ, - value: None, - }, - )(i) -} - pub fn parse(input: TokenSpan) -> IResult { module(input) } diff --git a/src/parser/declaration.rs b/src/parser/declaration.rs new file mode 100644 index 0000000..6426fd3 --- /dev/null +++ b/src/parser/declaration.rs @@ -0,0 +1,67 @@ +use nom::{ + combinator::{map, opt}, + sequence::{delimited, preceded, separated_pair, tuple}, +}; + +use super::expression::{expression, Expression}; +use super::tokens::{token, TokenKind as tk, TokenSpan}; +use super::{IResult, Span}; + +// TODO: allow recursive generics +// TODO: allow expressions again +pub fn typename(input: TokenSpan) -> IResult { + map( + tuple(( + token(tk::Ident), + opt(delimited(token(tk::LAngle), expression, token(tk::RAngle))), + )), + |(ident, _)| TypeName { + name: ident.span(), + generics: (), + }, + )(input) +} + +#[derive(Debug)] +pub struct TypeName<'a> { + name: Span<'a>, + generics: (), +} + +#[derive(Debug)] +pub struct NetDecl<'a> { + pub name: Span<'a>, + pub typ: TypeName<'a>, + pub value: Option>, +} + +#[derive(Debug)] +pub struct Assign<'a> { + pub lhs: &'a str, + pub expr: Expression<'a>, +} + +pub fn assign_statement(input: TokenSpan) -> IResult { + map( + separated_pair(token(tk::Ident), token(tk::EqAssign), expression), + |(lhs, expr)| Assign { + lhs: (*lhs.span().fragment()), + expr, + }, + )(input) +} + +// TODO: reallow assignments +pub fn declaration(i: TokenSpan) -> IResult { + map( + tuple(( + separated_pair(token(tk::Ident), token(tk::Colon), typename), + opt(preceded(token(tk::Assign), token(tk::Number))), + )), + |((ident, typ), _value)| NetDecl { + name: ident.span(), + typ, + value: None, + }, + )(i) +} diff --git a/src/parser/literals.rs b/src/parser/literals.rs index 763b3b2..13301a4 100644 --- a/src/parser/literals.rs +++ b/src/parser/literals.rs @@ -1,8 +1,11 @@ use nom::{ - character::complete::{char, one_of}, + branch::alt, + bytes::complete::tag, + character::complete::{alpha1, alphanumeric1, char, multispace0, one_of}, combinator::{map, recognize}, + error::ParseError, multi::{many0, many1}, - sequence::{preceded, terminated}, + sequence::{delimited, pair, preceded, terminated}, }; use crate::parser::{IResult, Span}; @@ -23,6 +26,22 @@ pub fn hexadecimal(input: Span) -> IResult { )(input) } +pub fn ws0<'a, F: 'a, O, E: ParseError>>( + inner: F, +) -> impl FnMut(Span<'a>) -> IResult, O, E> +where + F: FnMut(Span<'a>) -> IResult, O, E>, +{ + delimited(multispace0, inner, multispace0) +} + +pub fn identifier(input: Span) -> IResult { + recognize(pair( + alt((alpha1, tag("_"))), + many0(alt((alphanumeric1, tag("_")))), + ))(input) +} + #[cfg(test)] mod test { use super::*; diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index b360669..42ee7d2 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -1,6 +1,9 @@ //! convert text into a token stream -use super::{identifier, ws0, IResult, Span}; +use super::{ + literals::{identifier, ws0}, + IResult, Span, +}; use nom::{ branch::alt, bytes::complete::tag,