add preliminary type lookup

This commit is contained in:
NotAFile 2022-02-06 21:02:55 +01:00
parent dfc74b4b24
commit 83bb8d9292
4 changed files with 52 additions and 11 deletions

View File

@ -6,7 +6,7 @@ use crate::parser::expression::Expression;
use crate::rtlil; use crate::rtlil;
use crate::rtlil::RtlilWrite; use crate::rtlil::RtlilWrite;
pub use callable::Callable; pub use callable::Callable;
pub use types::{Type, TypeStruct}; pub use types::{make_primitives, Type, TypeStruct};
mod callable; mod callable;
pub mod typed_ir; pub mod typed_ir;
@ -64,7 +64,7 @@ struct Context<'ctx> {
/// map callable name to callable /// map callable name to callable
callables: BTreeMap<String, Callable<'ctx>>, callables: BTreeMap<String, Callable<'ctx>>,
/// types /// types
types: Vec<TypeStruct<'ctx>>, types: BTreeMap<String, TypeStruct<'ctx>>,
/// map signal name to Signal /// map signal name to Signal
signals: BTreeMap<String, Signal<'ctx>>, signals: BTreeMap<String, Signal<'ctx>>,
} }
@ -79,6 +79,12 @@ impl<'ctx> Context<'ctx> {
CompileError::new(CompileErrorKind::UndefinedReference(signame.to_owned())) CompileError::new(CompileErrorKind::UndefinedReference(signame.to_owned()))
}) })
} }
fn try_get_type(&self, typename: &str) -> Result<Type, CompileError> {
self.types.get(typename).ok_or_else(|| {
CompileError::new(CompileErrorKind::UndefinedReference(typename.to_owned()))
})
}
} }
fn lower_process_statement( fn lower_process_statement(
@ -285,6 +291,8 @@ fn lower_comb(
) -> Result<(), CompileError> { ) -> Result<(), CompileError> {
for (num, port) in pa_comb.ports.iter().enumerate() { for (num, port) in pa_comb.ports.iter().enumerate() {
let port_id = make_pubid(port.net.name.fragment()); let port_id = make_pubid(port.net.name.fragment());
let port_tyname = &port.net.typ;
ctx.try_get_type(port_tyname.name.fragment())?;
module.add_wire(rtlil::Wire::new( module.add_wire(rtlil::Wire::new(
port_id.clone(), port_id.clone(),
TODO_WIDTH, TODO_WIDTH,
@ -304,7 +312,7 @@ fn lower_comb(
module.add_wire(rtlil::Wire::new( module.add_wire(rtlil::Wire::new(
ret_id.clone(), ret_id.clone(),
TODO_WIDTH, TODO_WIDTH,
Some(rtlil::PortOption::Input(99)), Some(rtlil::PortOption::Output(99)),
)); ));
let out_sig = lower_expression(ctx, module, &pa_comb.expr)?; let out_sig = lower_expression(ctx, module, &pa_comb.expr)?;
module.add_connection(&rtlil::SigSpec::Wire(ret_id), &out_sig); module.add_connection(&rtlil::SigSpec::Wire(ret_id), &out_sig);
@ -320,7 +328,7 @@ pub fn lower_module(pa_module: parser::Module) -> Result<String, CompileError> {
.map(|clb| (clb.name().to_owned(), clb)) .map(|clb| (clb.name().to_owned(), clb))
.collect(), .collect(),
signals: BTreeMap::new(), signals: BTreeMap::new(),
types: vec![], types: make_primitives().into_iter().collect(),
}; };
writer.write_line("autoidx 1"); writer.write_line("autoidx 1");

View File

@ -7,7 +7,7 @@ pub struct TypeStruct<'ty> {
kind: TypeKind<'ty>, kind: TypeKind<'ty>,
} }
pub enum TypeKind<'ty> { enum TypeKind<'ty> {
/// Elaboration-time types /// Elaboration-time types
ElabType(ElabKind), ElabType(ElabKind),
/// Signal/Wire of generic width /// Signal/Wire of generic width
@ -58,7 +58,7 @@ impl<'ty> TypeStruct<'ty> {
/// a logic signal with known width /// a logic signal with known width
pub fn logic_width(width: u32) -> Self { pub fn logic_width(width: u32) -> Self {
Self { Self {
kind: TypeKind::Logic(ElabData::u32(width)), kind: TypeKind::Logic(ElabData::from_u32(width)),
} }
} }
@ -68,12 +68,32 @@ impl<'ty> TypeStruct<'ty> {
kind: TypeKind::ElabType(ElabKind::Num), kind: TypeKind::ElabType(ElabKind::Num),
} }
} }
pub fn bit_width(&self) -> Option<u32> {
match &self.kind {
// elab types are not representable in hardware
TypeKind::ElabType(_) => None,
TypeKind::Logic(data) => data.try_u32(),
TypeKind::UInt(_) => todo!(),
// callables are not representable in hardware
TypeKind::Callable => None,
}
}
pub fn genparam_count(&self) -> u32 {
match self.kind {
TypeKind::ElabType(_) => todo!(),
TypeKind::Logic(_) => 1,
TypeKind::UInt(_) => 1,
TypeKind::Callable => todo!(),
}
}
} }
/// Helper functions to create primitive elaboration values /// Helper functions to create primitive elaboration values
impl<'ty> ElabData<'ty> { impl<'ty> ElabData<'ty> {
/// an integer /// an integer
pub fn u32(val: u32) -> Self { pub fn from_u32(val: u32) -> Self {
Self { Self {
typ: &TypeStruct { typ: &TypeStruct {
kind: TypeKind::ElabType(ElabKind::Num), kind: TypeKind::ElabType(ElabKind::Num),
@ -81,4 +101,17 @@ impl<'ty> ElabData<'ty> {
value: ElabValue::Concrete(ElabValueData::U32(val)), value: ElabValue::Concrete(ElabValueData::U32(val)),
} }
} }
/// return Some(u32) if this is a number
pub fn try_u32(&self) -> Option<u32> {
// TODO: assert this is actually a number
match self.value {
ElabValue::Infer => None,
ElabValue::Concrete(_) => todo!(),
}
}
}
pub fn make_primitives() -> Vec<(String, TypeStruct<'static>)> {
vec![("Logic".to_string(), TypeStruct::logic_infer())]
} }

View File

@ -24,8 +24,8 @@ pub fn typename(input: TokenSpan) -> IResult<TokenSpan, TypeName> {
#[derive(Debug)] #[derive(Debug)]
pub struct TypeName<'a> { pub struct TypeName<'a> {
name: Span<'a>, pub name: Span<'a>,
generics: (), pub generics: (),
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -80,8 +80,8 @@ fn unary(input: TokenSpan) -> IResult<TokenSpan, Expression> {
fn bitop_kind(input: TokenSpan) -> IResult<TokenSpan, BinOpKind> { fn bitop_kind(input: TokenSpan) -> IResult<TokenSpan, BinOpKind> {
alt(( alt((
map(token(tk::BitXor), |_| BinOpKind::Xor), map(token(tk::BitXor), |_| BinOpKind::Xor),
map(token(tk::BitOr), |_| BinOpKind::Xor), map(token(tk::BitOr), |_| BinOpKind::Or),
map(token(tk::BitAnd), |_| BinOpKind::Xor), map(token(tk::BitAnd), |_| BinOpKind::And),
))(input) ))(input)
} }