Compare commits

..

2 Commits

Author SHA1 Message Date
NotAFile b848d5d3ea add comments to lexer 2022-04-05 00:03:48 +02:00
NotAFile 0307d0537c add match lowering 2022-04-05 00:03:05 +02:00
5 changed files with 76 additions and 10 deletions

View File

@ -66,17 +66,52 @@ fn lower_expression(
Ok(rtlil::SigSpec::Wire(expr_wire_name)) Ok(rtlil::SigSpec::Wire(expr_wire_name))
} }
ExprKind::Literal(lit) => Ok(rtlil::SigSpec::Const( ExprKind::Literal(lit) => Ok(rtlil::SigSpec::Const(
todo!(), ctx.types
.elab_as_u32(lit)
.expect("const does not fit in 32 bits") as i64,
ctx.types.get_width(expr.typ).expect("signal has no size"), ctx.types.get_width(expr.typ).expect("signal has no size"),
)), )),
ExprKind::Match(_) => todo!(), ExprKind::Match(match_) => {
let cases = match_
.arms
.iter()
.map(|(pat, val)| {
Ok((
lower_expression(ctx, module, pat)?,
rtlil::CaseRule {
assign: vec![(
rtlil::SigSpec::Wire(expr_wire_name.clone()),
lower_expression(ctx, module, val)?,
)],
switches: vec![],
},
))
})
.collect::<Result<Vec<_>, CompileError>>()
.unwrap();
let root_switch = rtlil::SwitchRule {
signal: lower_expression(ctx, module, &match_.expr)?,
cases,
};
let root_case = rtlil::CaseRule {
assign: vec![],
switches: vec![root_switch],
};
let proc = rtlil::Process {
id: module.make_genid("match"),
root_case,
sync_rules: vec![],
};
module.add_process(proc);
Ok(rtlil::SigSpec::Wire(expr_wire_name))
}
} }
} }
fn lower_comb( fn lower_comb(
ctx: &mut Context, ctx: &mut Context,
module: &mut rtlil::Module, module: &mut rtlil::Module,
block: typed_ir::Block, block: &typed_ir::Block,
) -> Result<(), CompileError> { ) -> Result<(), CompileError> {
for (num, sig) in block.signals.iter().enumerate() { for (num, sig) in block.signals.iter().enumerate() {
let sig_id = format!("\\$sig_{}", sig.id.0); let sig_id = format!("\\$sig_{}", sig.id.0);
@ -101,7 +136,7 @@ fn lower_comb(
Ok(()) Ok(())
} }
pub fn lower_block(context: &mut Context, block: typed_ir::Block) -> Result<String, CompileError> { pub fn lower_block(context: &mut Context, block: &typed_ir::Block) -> Result<String, CompileError> {
let mut writer = rtlil::ILWriter::new(); let mut writer = rtlil::ILWriter::new();
let mut ir_module = rtlil::Module::new(make_pubid("test")); let mut ir_module = rtlil::Module::new(make_pubid("test"));

View File

@ -150,6 +150,16 @@ impl TypingContext {
} }
} }
pub fn elab_as_u32(&self, data: &ElabData) -> Option<u32> {
match &data.value {
ElabValue::Infer => None,
ElabValue::Concrete(val) => match val {
ElabValueData::U32(val) => Some(*val),
ElabValueData::Bytes(_val) => None,
},
}
}
pub fn make_logic_size(&self, width: u32) -> Type { pub fn make_logic_size(&self, width: u32) -> Type {
let widthnum = self.make_elabnum_u32(width); let widthnum = self.make_elabnum_u32(width);
self.parameterize(self.primitives.logic, &[GenericArg::Elab(widthnum)]) self.parameterize(self.primitives.logic, &[GenericArg::Elab(widthnum)])

View File

@ -41,7 +41,7 @@ fn main() {
.expect("error reading file"); .expect("error reading file");
let input: &str = input.as_str(); let input: &str = input.as_str();
let input = parser::Span::new(input); let input = parser::Span::new(input);
let lexed = parser::tokens::lex(input).unwrap(); let lexed = parser::tokens::lex(input).expect("failed to lex");
let tokens = parser::tokens::TokenSpan::new(&lexed.1); let tokens = parser::tokens::TokenSpan::new(&lexed.1);
let parsed = parser::parse(tokens); let parsed = parser::parse(tokens);
match parsed { match parsed {
@ -61,6 +61,7 @@ fn main() {
let mut frontendcontext = crate::frontend::Context::new(); let mut frontendcontext = crate::frontend::Context::new();
let typed = frontendcontext.type_module(res.1); let typed = frontendcontext.type_module(res.1);
if let Ok(module) = typed { if let Ok(module) = typed {
let mut typed_modules = vec![];
for block in module.blocks { for block in module.blocks {
if opt.debug { if opt.debug {
let mut pretty_block = String::new(); let mut pretty_block = String::new();
@ -77,9 +78,10 @@ fn main() {
.unwrap(); .unwrap();
println!("{}", &pretty_block); println!("{}", &pretty_block);
} }
typed_modules.push(typed_inferred);
} }
let typed_inferred = typed_modules.first().unwrap();
// TODO: be able to determine modules that are fully parameterized // TODO: be able to determine modules that are fully parameterized
/*
let lowered = frontend::lowering::lower_block(&mut frontendcontext, typed_inferred); let lowered = frontend::lowering::lower_block(&mut frontendcontext, typed_inferred);
match lowered { match lowered {
Ok(res) => { Ok(res) => {
@ -91,7 +93,6 @@ fn main() {
} }
Err(err) => eprintln!("{:#?}", err), Err(err) => eprintln!("{:#?}", err),
} }
*/
} else { } else {
eprintln!("{:#?}", typed); eprintln!("{:#?}", typed);
} }

View File

@ -87,7 +87,7 @@ impl InputPos for Span<'_> {
} }
fn tokspan_to_range(input: TokenSpan) -> std::ops::Range<usize> { fn tokspan_to_range(input: TokenSpan) -> std::ops::Range<usize> {
let first = input.first().unwrap().span().position(); let first = input.first().expect("eof in token").span().position();
let last_span = input.last().unwrap().span(); let last_span = input.last().unwrap().span();
let last = last_span.position() + last_span.len(); let last = last_span.position() + last_span.len();
first..last first..last

View File

@ -7,11 +7,12 @@ use super::{
}; };
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::tag, bytes::complete::{is_not, tag},
character::complete::{anychar, digit1}, character::complete::{anychar, digit1, line_ending},
combinator::{consumed, map, recognize}, combinator::{consumed, map, recognize},
error::ParseError, error::ParseError,
multi::many0, multi::many0,
sequence::tuple,
InputTake, InputTake,
}; };
use std::fmt; use std::fmt;
@ -85,8 +86,11 @@ pub enum TokenKind {
State, State,
Proc, Proc,
Comb, Comb,
// whitespace
Comment,
// Error // Error
Error, Error,
Eof,
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -147,6 +151,11 @@ pub fn token<'a>(kind: TokenKind) -> impl FnMut(TokenSpan<'a>) -> IResult<TokenS
nom::error::ErrorKind::Eof, nom::error::ErrorKind::Eof,
))); )));
}; };
// TODO: HACKS HACKS HACKS EWW
if next.kind == TokenKind::Comment {
let (_, tail) = input.take_split(1);
return token(kind)(tail);
}
if next.kind == kind { if next.kind == kind {
let rest = TokenSpan::with_pos(&input.rest[1..], input.pos + 1); let rest = TokenSpan::with_pos(&input.rest[1..], input.pos + 1);
Ok((rest, next)) Ok((rest, next))
@ -159,6 +168,7 @@ pub fn token<'a>(kind: TokenKind) -> impl FnMut(TokenSpan<'a>) -> IResult<TokenS
pub fn lex(input: Span) -> IResult<Span, Vec<Token>> { pub fn lex(input: Span) -> IResult<Span, Vec<Token>> {
many0(ws0(alt(( many0(ws0(alt((
lex_keywords, lex_keywords,
lex_trivials,
lex_literals, lex_literals,
lex_braces, lex_braces,
lex_punctuation, lex_punctuation,
@ -227,3 +237,13 @@ fn lex_keywords(input: Span) -> IResult<Span, Token> {
|(span, kind)| Token::new(span, kind), |(span, kind)| Token::new(span, kind),
)(input) )(input)
} }
fn lex_trivials(input: Span) -> IResult<Span, Token> {
map(
consumed(alt((map(
tuple((tag("//"), is_not("\r\n"), line_ending)),
|_| TokenKind::Comment,
),))),
|(span, kind)| Token::new(span, kind),
)(input)
}