diff --git a/src/frontend.rs b/src/frontend.rs index 2346c2e..a1995f0 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -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>, /// types - types: Vec>, + types: BTreeMap>, /// map signal name to Signal signals: BTreeMap>, } @@ -79,6 +79,12 @@ impl<'ctx> Context<'ctx> { CompileError::new(CompileErrorKind::UndefinedReference(signame.to_owned())) }) } + + fn try_get_type(&self, typename: &str) -> Result { + 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 { .map(|clb| (clb.name().to_owned(), clb)) .collect(), signals: BTreeMap::new(), - types: vec![], + types: make_primitives().into_iter().collect(), }; writer.write_line("autoidx 1"); diff --git a/src/frontend/types.rs b/src/frontend/types.rs index 7ef306c..a217325 100644 --- a/src/frontend/types.rs +++ b/src/frontend/types.rs @@ -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 { + 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 { + // 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())] } diff --git a/src/parser/declaration.rs b/src/parser/declaration.rs index 6426fd3..dca1de8 100644 --- a/src/parser/declaration.rs +++ b/src/parser/declaration.rs @@ -24,8 +24,8 @@ pub fn typename(input: TokenSpan) -> IResult { #[derive(Debug)] pub struct TypeName<'a> { - name: Span<'a>, - generics: (), + pub name: Span<'a>, + pub generics: (), } #[derive(Debug)] diff --git a/src/parser/expression.rs b/src/parser/expression.rs index c7320e1..77d48b6 100644 --- a/src/parser/expression.rs +++ b/src/parser/expression.rs @@ -80,8 +80,8 @@ fn unary(input: TokenSpan) -> IResult { fn bitop_kind(input: TokenSpan) -> IResult { 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) }