From faf92307e235d0c226e26a139d4e9b6ae3973c65 Mon Sep 17 00:00:00 2001 From: NotAFile Date: Thu, 3 Feb 2022 01:55:12 +0100 Subject: [PATCH] start implementing state adt --- doc/examples/identity.fut | 4 ++-- src/frontend.rs | 4 +++- src/parser/adt.rs | 43 +++++++++++++++++++++++++++++++-------- src/parser/comb.rs | 31 ++++++++++++++++------------ src/parser/mod.rs | 3 ++- src/parser/module.rs | 25 ++++++++++++++++------- src/parser/tokens.rs | 26 +++++++++++++++-------- 7 files changed, 94 insertions(+), 42 deletions(-) diff --git a/doc/examples/identity.fut b/doc/examples/identity.fut index b8e2700..0f85c16 100644 --- a/doc/examples/identity.fut +++ b/doc/examples/identity.fut @@ -1,6 +1,6 @@ -module identity ( +comb identity ( a: Logic ) -> Logic { - assign x = a; + a } diff --git a/src/frontend.rs b/src/frontend.rs index 00cba25..ad1ec7d 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -286,7 +286,7 @@ fn lower_assignment( pub fn lower_module(pa_module: parser::Module) -> Result { let mut writer = rtlil::ILWriter::new(); - let mut ir_module = rtlil::Module::new(make_pubid(pa_module.name.fragment())); + let mut ir_module = rtlil::Module::new(make_pubid("test")); let mut context = Context { callables: get_builtins() .into_iter() @@ -297,6 +297,7 @@ pub fn lower_module(pa_module: parser::Module) -> Result { }; writer.write_line("autoidx 1"); + /* for (idx, port) in pa_module.ports.iter().enumerate() { // FIXME: Actually resolve types let sigtype = TypeStruct::logic_width(TODO_WIDTH); @@ -328,5 +329,6 @@ pub fn lower_module(pa_module: parser::Module) -> Result { } } ir_module.write_rtlil(&mut writer); + */ Ok(writer.finish()) } diff --git a/src/parser/adt.rs b/src/parser/adt.rs index 5b5abaf..a52515c 100644 --- a/src/parser/adt.rs +++ b/src/parser/adt.rs @@ -1,16 +1,40 @@ use super::declaration::{declaration, NetDecl}; use super::tokens::{token, Token, TokenKind as tk, TokenSpan}; use super::IResult; -use nom::multi::many0; +use nom::multi::separated_list0; use nom::sequence::tuple; use nom::{ - combinator::{cut, map}, + combinator::{cut, map, opt}, sequence::{delimited, preceded}, }; +#[derive(Debug)] pub struct StateBlock<'a> { - name: Token<'a>, - items: Vec>, + pub name: Token<'a>, + pub variants: Vec>, +} + +#[derive(Debug)] +pub struct StateVariant<'a> { + pub name: Token<'a>, + pub params: Option>>, +} + +fn state_variant(input: TokenSpan) -> IResult { + map( + tuple(( + token(tk::Ident), + opt(delimited( + token(tk::LParen), + separated_list0(token(tk::Comma), token(tk::Ident)), + token(tk::RParen), + )), + )), + |(name, param)| StateVariant { + name: name.clone(), + params: param, + }, + )(input) } pub fn state(input: TokenSpan) -> IResult { @@ -19,12 +43,13 @@ pub fn state(input: TokenSpan) -> IResult { token(tk::State), cut(tuple(( token(tk::Ident), - delimited(token(tk::LBrace), many0(declaration), token(tk::RBrace)), + delimited( + token(tk::LBrace), + separated_list0(token(tk::Comma), state_variant), + token(tk::RBrace), + ), ))), ), - |(name, items)| StateBlock { - name: name.clone(), - items, - }, + |(name, variants)| StateBlock { name, variants }, )(input) } diff --git a/src/parser/comb.rs b/src/parser/comb.rs index ccfcdb5..5d06dae 100644 --- a/src/parser/comb.rs +++ b/src/parser/comb.rs @@ -1,18 +1,24 @@ -use super::module::inputs_list; -use super::tokens::TokenKind as tk; -use crate::parser::tokens::token; -use crate::parser::typename; -use crate::parser::IResult; -use crate::parser::Module; -use crate::parser::TokenSpan; -use nom::combinator::cut; -use nom::combinator::map; -use nom::multi::many0; +use super::{ + module::inputs_list, + module::PortDecl, + tokens::{token, TokenKind as tk, TokenSpan}, + typename, IResult, Span, +}; use nom::sequence::delimited; use nom::sequence::preceded; use nom::sequence::tuple; +use nom::{ + combinator::{cut, map}, + multi::many0, +}; -pub fn comb_block(input: TokenSpan) -> IResult { +#[derive(Debug)] +pub struct CombBlock<'a> { + pub name: Span<'a>, + pub ports: Vec>, +} + +pub fn comb_block(input: TokenSpan) -> IResult { map( preceded( token(tk::Comb), @@ -27,11 +33,10 @@ pub fn comb_block(input: TokenSpan) -> IResult { ), ))), ), - |(name, inputs, _ret, _items)| Module { + |(name, inputs, _ret, _items)| CombBlock { // TODO: bring back returns name: name.span(), ports: inputs, - items: todo!(), }, )(input) } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index cbf4a63..f221913 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -23,9 +23,10 @@ pub use crate::parser::declaration::{ pub use crate::parser::expression::{expression, Call, Expression, Operation}; pub use crate::parser::module::{module, Module, ModuleItem, PortDirection}; use crate::parser::tokens::TokenSpan; +use nom::combinator::all_consuming; pub fn parse(input: TokenSpan) -> IResult { - module(input) + all_consuming(module)(input) } #[cfg(test)] diff --git a/src/parser/module.rs b/src/parser/module.rs index df58bd4..f25d22f 100644 --- a/src/parser/module.rs +++ b/src/parser/module.rs @@ -1,10 +1,16 @@ -use nom::{combinator::map, multi::separated_list0}; +use nom::{ + branch::alt, + combinator::map, + multi::{many1, separated_list0}, +}; use crate::parser::{ + adt::{state, StateBlock}, + comb::{comb_block, CombBlock}, declaration, proc::ProcBlock, tokens::{token, TokenKind as tk, TokenSpan}, - Assign, IResult, NetDecl, Span, + IResult, NetDecl, Span, }; #[derive(Debug)] @@ -21,15 +27,14 @@ pub struct PortDecl<'a> { #[derive(Debug)] pub struct Module<'a> { - pub name: Span<'a>, - pub ports: Vec>, pub items: Vec>, } #[derive(Debug)] pub enum ModuleItem<'a> { - Assign(Assign<'a>), + Comb(CombBlock<'a>), Proc(ProcBlock<'a>), + State(StateBlock<'a>), } fn port_decl(i: TokenSpan) -> IResult { @@ -43,8 +48,14 @@ pub fn inputs_list(input: TokenSpan) -> IResult> { separated_list0(token(tk::Comma), port_decl)(input) } -pub fn module(_input: TokenSpan) -> IResult { - todo!(); +pub fn module(input: TokenSpan) -> IResult { + map( + many1(alt(( + map(state, ModuleItem::State), + map(comb_block, ModuleItem::Comb), + ))), + |items| Module { items }, + )(input) } #[cfg(test)] diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index 2cc4427..dacf634 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -3,18 +3,20 @@ use super::{ error::{Error, InputPos}, literals::{identifier, ws0}, - IResult, Span, + IErr, IResult, Span, }; use nom::{ branch::alt, bytes::complete::tag, character::complete::{anychar, digit1}, combinator::{consumed, map, recognize}, + error::ParseError, multi::many0, + InputTake, }; use std::fmt; -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct Token<'a> { span: Span<'a>, kind: TokenKind, @@ -38,7 +40,7 @@ impl<'a> Token<'a> { Self { span, kind } } - pub fn span(&self) -> Span { + pub fn span(self) -> Span<'a> { self.span } pub fn kind(&self) -> TokenKind { @@ -85,7 +87,7 @@ pub enum TokenKind { Error, } -#[derive(Debug, Clone)] +#[derive(Debug, Copy, Clone)] pub struct TokenSpan<'a> { rest: &'a [Token<'a>], pos: usize, @@ -106,7 +108,7 @@ impl<'a> TokenSpan<'a> { } } -impl nom::InputTake for TokenSpan<'_> { +impl InputTake for TokenSpan<'_> { fn take(&self, count: usize) -> Self { TokenSpan::with_pos(&self.rest[..count], self.pos + count) } @@ -133,10 +135,16 @@ impl InputPos for TokenSpan<'_> { } /// combinator that matches a token kind -pub fn token<'a>(kind: TokenKind) -> impl FnMut(TokenSpan<'a>) -> IResult { +pub fn token<'a>(kind: TokenKind) -> impl FnMut(TokenSpan<'a>) -> IResult { move |input: TokenSpan| { - let next = &input.rest[0]; - let kind = kind; + let next = if let Some(i) = input.rest.first() { + *i + } else { + return Err(nom::Err::Error(Error::from_error_kind( + input, + nom::error::ErrorKind::Eof, + ))); + }; if next.kind == kind { let rest = TokenSpan::with_pos(&input.rest[1..], input.pos + 1); Ok((rest, next)) @@ -210,7 +218,7 @@ fn lex_keywords(input: Span) -> IResult { map(tag("match"), |_| TokenKind::Match), map(tag("proc"), |_| TokenKind::Proc), map(tag("comb"), |_| TokenKind::Comb), - map(tag("state"), |_| TokenKind::Proc), + map(tag("state"), |_| TokenKind::State), ))), |(span, kind)| Token::new(span, kind), )(input)