split up parser into folder
This commit is contained in:
parent
7238d6991c
commit
c2628102cc
|
@ -140,7 +140,7 @@ pub fn lower_module(pa_module: parser::Module) -> Result<String, CompileError> {
|
||||||
parser::ModuleItem::Assign(assignment) => {
|
parser::ModuleItem::Assign(assignment) => {
|
||||||
lower_assignment(&context, &mut ir_module, assignment)?
|
lower_assignment(&context, &mut ir_module, assignment)?
|
||||||
}
|
}
|
||||||
parser::ModuleItem::Proc(proc) => todo!("lowering process")
|
parser::ModuleItem::Proc(proc) => todo!("lowering process"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ir_module.write_rtlil(&mut writer);
|
ir_module.write_rtlil(&mut writer);
|
||||||
|
|
|
@ -4,11 +4,11 @@ mod literals;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod rtlil;
|
mod rtlil;
|
||||||
|
|
||||||
|
use nom::error::convert_error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use nom::error::convert_error;
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
#[structopt(name = "example", about = "An example of StructOpt usage.")]
|
#[structopt(name = "example", about = "An example of StructOpt usage.")]
|
||||||
|
|
147
src/parser.rs
147
src/parser.rs
|
@ -1,3 +1,6 @@
|
||||||
|
mod module;
|
||||||
|
mod proc;
|
||||||
|
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::tag,
|
bytes::complete::tag,
|
||||||
|
@ -17,6 +20,7 @@ pub type Span<'a> = LocatedSpan<&'a str>;
|
||||||
pub type IResult<I, O, E = VerboseError<I>> = nom::IResult<I, O, E>;
|
pub type IResult<I, O, E = VerboseError<I>> = nom::IResult<I, O, E>;
|
||||||
|
|
||||||
use crate::literals::hexadecimal;
|
use crate::literals::hexadecimal;
|
||||||
|
pub use crate::parser::module::{module, Module, ModuleItem, PortDirection};
|
||||||
|
|
||||||
fn ws0<'a, F: 'a, O, E: ParseError<Span<'a>>>(
|
fn ws0<'a, F: 'a, O, E: ParseError<Span<'a>>>(
|
||||||
inner: F,
|
inner: F,
|
||||||
|
@ -49,56 +53,6 @@ pub struct NetDecl<'a> {
|
||||||
pub value: Option<(u64, u64)>,
|
pub value: Option<(u64, u64)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum PortDirection {
|
|
||||||
Input,
|
|
||||||
Output,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PortDecl<'a> {
|
|
||||||
pub pos: Span<'a>,
|
|
||||||
pub direction: PortDirection,
|
|
||||||
pub net: NetDecl<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Module<'a> {
|
|
||||||
pub name: &'a str,
|
|
||||||
pub ports: Vec<PortDecl<'a>>,
|
|
||||||
pub items: Vec<ModuleItem<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ModuleItem<'a> {
|
|
||||||
Assign(Assign<'a>),
|
|
||||||
Proc(ProcBlock<'a>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ProcBlock<'a> {
|
|
||||||
pub net: Span<'a>,
|
|
||||||
pub items: Vec<ProcStatement<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ProcStatement<'a> {
|
|
||||||
IfElse(IfElseBlock),
|
|
||||||
Assign,
|
|
||||||
Match(MatchBlock<'a>),
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: postponed because annoying to implement
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct IfElseBlock {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct MatchBlock<'a> {
|
|
||||||
expr: Expression<'a>,
|
|
||||||
arms: Vec<(&'a str, ProcStatement<'a>)>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Assign<'a> {
|
pub struct Assign<'a> {
|
||||||
pub lhs: &'a str,
|
pub lhs: &'a str,
|
||||||
|
@ -140,27 +94,6 @@ fn declaration(i: Span) -> IResult<Span, NetDecl> {
|
||||||
)(i)
|
)(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn port_decl(i: Span) -> IResult<Span, PortDecl> {
|
|
||||||
map(
|
|
||||||
consumed(tuple((
|
|
||||||
alt((
|
|
||||||
map(tag("input"), |_| PortDirection::Input),
|
|
||||||
map(tag("output"), |_| PortDirection::Output),
|
|
||||||
)),
|
|
||||||
declaration,
|
|
||||||
))),
|
|
||||||
|(pos, (direction, net))| PortDecl {
|
|
||||||
pos,
|
|
||||||
direction,
|
|
||||||
net,
|
|
||||||
},
|
|
||||||
)(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ports_list(input: Span) -> IResult<Span, Vec<PortDecl>> {
|
|
||||||
separated_list0(ws0(char(',')), ws0(port_decl))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn operation(input: Span) -> IResult<Span, Operation> {
|
fn operation(input: Span) -> IResult<Span, Operation> {
|
||||||
// temporarily given up on before I learn the shunting yard algorithm
|
// temporarily given up on before I learn the shunting yard algorithm
|
||||||
alt((
|
alt((
|
||||||
|
@ -212,11 +145,9 @@ fn assign_statement(input: Span) -> IResult<Span, Assign> {
|
||||||
ws0(terminated(tag("assign"), multispace1)),
|
ws0(terminated(tag("assign"), multispace1)),
|
||||||
map(
|
map(
|
||||||
separated_pair(ws0(identifier), char('='), ws0(expression)),
|
separated_pair(ws0(identifier), char('='), ws0(expression)),
|
||||||
|(lhs, expr)| {
|
|(lhs, expr)| Assign {
|
||||||
Assign {
|
lhs: (*lhs.fragment()),
|
||||||
lhs: (*lhs.fragment()),
|
expr,
|
||||||
expr,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ws0(char(';')),
|
ws0(char(';')),
|
||||||
|
@ -224,70 +155,6 @@ fn assign_statement(input: Span) -> IResult<Span, Assign> {
|
||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// parse a statement that is valid inside a proc block
|
|
||||||
fn proc_statement(input: Span) -> IResult<Span, ProcStatement> {
|
|
||||||
map(
|
|
||||||
nom::character::complete::anychar,
|
|
||||||
|_| {
|
|
||||||
ProcStatement::Match(MatchBlock {
|
|
||||||
expr: Expression::Ident("asdf"),
|
|
||||||
arms: Vec::new(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn proc_block(input: Span) -> IResult<Span, ProcBlock> {
|
|
||||||
context(
|
|
||||||
"proc block",
|
|
||||||
map(
|
|
||||||
tuple((
|
|
||||||
ws0(tag("proc")),
|
|
||||||
ws0(delimited(char('('), ws0(identifier), char(')'))),
|
|
||||||
ws0(delimited(char('{'), many0(ws0(proc_statement)), char('}')))
|
|
||||||
)),
|
|
||||||
|(_, net, items)| {
|
|
||||||
ProcBlock {
|
|
||||||
net,
|
|
||||||
items,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)(input)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn module_item(input: Span) -> IResult<Span, ModuleItem> {
|
|
||||||
alt((
|
|
||||||
map(assign_statement, |assig| ModuleItem::Assign(assig)),
|
|
||||||
map(proc_block, |proc| ModuleItem::Proc(proc)),
|
|
||||||
))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// parse a top-level module declaration
|
|
||||||
pub fn module(input: Span) -> IResult<Span, Module> {
|
|
||||||
context(
|
|
||||||
"module",
|
|
||||||
map(
|
|
||||||
tuple((
|
|
||||||
tag("module"),
|
|
||||||
ws0(identifier),
|
|
||||||
ws0(delimited(char('('), ws0(ports_list), char(')'))),
|
|
||||||
ws0(delimited(
|
|
||||||
char('{'),
|
|
||||||
many1(ws0(module_item)),
|
|
||||||
char('}'),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
|(_, name, ports, items)| Module {
|
|
||||||
name: (*name.fragment()),
|
|
||||||
ports,
|
|
||||||
items,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse(input: Span) -> IResult<Span, Module> {
|
pub fn parse(input: Span) -> IResult<Span, Module> {
|
||||||
module(input)
|
module(input)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
use nom::{
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete::{alpha1, alphanumeric1, char, multispace0, multispace1, u64 as decimal},
|
||||||
|
combinator::{consumed, map, opt, recognize},
|
||||||
|
error::{context, ParseError, VerboseError},
|
||||||
|
multi::{many0, many1, separated_list0},
|
||||||
|
sequence::{delimited, pair, preceded, separated_pair, terminated, tuple},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::parser::proc::{proc_block, ProcBlock};
|
||||||
|
use crate::parser::{
|
||||||
|
assign_statement, declaration, identifier, intliteral, widthspec, ws0, Assign, IResult,
|
||||||
|
NetDecl, Span,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum PortDirection {
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct PortDecl<'a> {
|
||||||
|
pub pos: Span<'a>,
|
||||||
|
pub direction: PortDirection,
|
||||||
|
pub net: NetDecl<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Module<'a> {
|
||||||
|
pub name: &'a str,
|
||||||
|
pub ports: Vec<PortDecl<'a>>,
|
||||||
|
pub items: Vec<ModuleItem<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ModuleItem<'a> {
|
||||||
|
Assign(Assign<'a>),
|
||||||
|
Proc(ProcBlock<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn port_decl(i: Span) -> IResult<Span, PortDecl> {
|
||||||
|
map(
|
||||||
|
consumed(tuple((
|
||||||
|
alt((
|
||||||
|
map(tag("input"), |_| PortDirection::Input),
|
||||||
|
map(tag("output"), |_| PortDirection::Output),
|
||||||
|
)),
|
||||||
|
declaration,
|
||||||
|
))),
|
||||||
|
|(pos, (direction, net))| PortDecl {
|
||||||
|
pos,
|
||||||
|
direction,
|
||||||
|
net,
|
||||||
|
},
|
||||||
|
)(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ports_list(input: Span) -> IResult<Span, Vec<PortDecl>> {
|
||||||
|
separated_list0(ws0(char(',')), ws0(port_decl))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn module_item(input: Span) -> IResult<Span, ModuleItem> {
|
||||||
|
alt((
|
||||||
|
map(assign_statement, |assig| ModuleItem::Assign(assig)),
|
||||||
|
map(proc_block, |proc| ModuleItem::Proc(proc)),
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// parse a top-level module declaration
|
||||||
|
pub fn module(input: Span) -> IResult<Span, Module> {
|
||||||
|
context(
|
||||||
|
"module",
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
tag("module"),
|
||||||
|
ws0(identifier),
|
||||||
|
ws0(delimited(char('('), ws0(ports_list), char(')'))),
|
||||||
|
ws0(delimited(char('{'), many1(ws0(module_item)), char('}'))),
|
||||||
|
)),
|
||||||
|
|(_, name, ports, items)| Module {
|
||||||
|
name: (*name.fragment()),
|
||||||
|
ports,
|
||||||
|
items,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)(input)
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
use nom::{
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete::{alpha1, alphanumeric1, char, multispace0, multispace1, u64 as decimal},
|
||||||
|
combinator::{consumed, map, opt, recognize},
|
||||||
|
error::{context, ParseError, VerboseError},
|
||||||
|
multi::{many0, many1, separated_list0},
|
||||||
|
sequence::{delimited, pair, preceded, separated_pair, terminated, tuple},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::parser::{identifier, ws0, Expression, IResult, Span};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProcBlock<'a> {
|
||||||
|
pub net: Span<'a>,
|
||||||
|
pub items: Vec<ProcStatement<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ProcStatement<'a> {
|
||||||
|
IfElse(IfElseBlock),
|
||||||
|
Assign,
|
||||||
|
Match(MatchBlock<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: postponed because annoying to implement
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct IfElseBlock {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MatchBlock<'a> {
|
||||||
|
expr: Expression<'a>,
|
||||||
|
arms: Vec<(&'a str, ProcStatement<'a>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// parse a statement that is valid inside a proc block
|
||||||
|
fn proc_statement(input: Span) -> IResult<Span, ProcStatement> {
|
||||||
|
map(nom::character::complete::anychar, |_| {
|
||||||
|
ProcStatement::Match(MatchBlock {
|
||||||
|
expr: Expression::Ident("asdf"),
|
||||||
|
arms: Vec::new(),
|
||||||
|
})
|
||||||
|
})(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn proc_block(input: Span) -> IResult<Span, ProcBlock> {
|
||||||
|
context(
|
||||||
|
"proc block",
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
ws0(tag("proc")),
|
||||||
|
ws0(delimited(char('('), ws0(identifier), char(')'))),
|
||||||
|
ws0(delimited(char('{'), many0(ws0(proc_statement)), char('}'))),
|
||||||
|
)),
|
||||||
|
|(_, net, items)| ProcBlock { net, items },
|
||||||
|
),
|
||||||
|
)(input)
|
||||||
|
}
|
|
@ -144,7 +144,8 @@ impl Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_connection(&mut self, target: &str, source: &str) {
|
pub fn add_connection(&mut self, target: &str, source: &str) {
|
||||||
self.connections.push((SigSpec::wire(target), SigSpec::wire(source)))
|
self.connections
|
||||||
|
.push((SigSpec::wire(target), SigSpec::wire(source)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_cell(&mut self, cell: Cell) {
|
pub fn add_cell(&mut self, cell: Cell) {
|
||||||
|
@ -200,7 +201,8 @@ impl Cell {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_connection(&mut self, from: &str, to: &str) {
|
pub fn add_connection(&mut self, from: &str, to: &str) {
|
||||||
self.connections.push((SigSpec::wire(from), SigSpec::wire(to)))
|
self.connections
|
||||||
|
.push((SigSpec::wire(from), SigSpec::wire(to)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue