futilehdl/src/parser/declaration.rs

68 lines
1.6 KiB
Rust

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<TokenSpan, TypeName> {
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<Span<'a>>,
}
#[derive(Debug)]
pub struct Assign<'a> {
pub lhs: &'a str,
pub expr: Expression<'a>,
}
pub fn assign_statement(input: TokenSpan) -> IResult<TokenSpan, Assign> {
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<TokenSpan, NetDecl> {
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)
}