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::RtlilWrite;
pub use callable::Callable;
pub use types::{Type, TypeStruct};
pub use types::{make_primitives, Type, TypeStruct};
mod callable;
pub mod typed_ir;
@ -64,7 +64,7 @@ struct Context<'ctx> {
/// map callable name to callable
callables: BTreeMap<String, Callable<'ctx>>,
/// types
types: Vec<TypeStruct<'ctx>>,
types: BTreeMap<String, TypeStruct<'ctx>>,
/// map signal name to Signal
signals: BTreeMap<String, Signal<'ctx>>,
}
@ -79,6 +79,12 @@ impl<'ctx> Context<'ctx> {
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(
@ -285,6 +291,8 @@ fn lower_comb(
) -> Result<(), CompileError> {
for (num, port) in pa_comb.ports.iter().enumerate() {
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(
port_id.clone(),
TODO_WIDTH,
@ -304,7 +312,7 @@ fn lower_comb(
module.add_wire(rtlil::Wire::new(
ret_id.clone(),
TODO_WIDTH,
Some(rtlil::PortOption::Input(99)),
Some(rtlil::PortOption::Output(99)),
));
let out_sig = lower_expression(ctx, module, &pa_comb.expr)?;
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))
.collect(),
signals: BTreeMap::new(),
types: vec![],
types: make_primitives().into_iter().collect(),
};
writer.write_line("autoidx 1");

View File

@ -7,7 +7,7 @@ pub struct TypeStruct<'ty> {
kind: TypeKind<'ty>,
}
pub enum TypeKind<'ty> {
enum TypeKind<'ty> {
/// Elaboration-time types
ElabType(ElabKind),
/// Signal/Wire of generic width
@ -58,7 +58,7 @@ impl<'ty> TypeStruct<'ty> {
/// a logic signal with known width
pub fn logic_width(width: u32) -> 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),
}
}
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
impl<'ty> ElabData<'ty> {
/// an integer
pub fn u32(val: u32) -> Self {
pub fn from_u32(val: u32) -> Self {
Self {
typ: &TypeStruct {
kind: TypeKind::ElabType(ElabKind::Num),
@ -81,4 +101,17 @@ impl<'ty> ElabData<'ty> {
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)]
pub struct TypeName<'a> {
name: Span<'a>,
generics: (),
pub name: Span<'a>,
pub generics: (),
}
#[derive(Debug)]

View File

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