-
Notifications
You must be signed in to change notification settings - Fork 27
some cleanups and new functionality for Tmr and Value #374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
82cf682
49b56d5
90e80b2
b0ea014
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| //! Source and target types of jet nodes need to be specified manually. | ||
|
|
||
| use crate::types::{self, Final, Type}; | ||
| use crate::Tmr; | ||
| use std::cmp; | ||
| use std::sync::Arc; | ||
|
|
||
|
|
@@ -30,6 +31,18 @@ use std::sync::Arc; | |
| #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] | ||
| pub struct TypeName(pub &'static [u8]); | ||
|
|
||
| impl PartialEq<Final> for TypeName { | ||
| fn eq(&self, other: &Final) -> bool { | ||
| self.tmr() == other.tmr() | ||
| } | ||
| } | ||
|
|
||
| impl PartialEq<TypeName> for Final { | ||
| fn eq(&self, other: &TypeName) -> bool { | ||
| self.tmr() == other.tmr() | ||
| } | ||
| } | ||
|
|
||
| impl TypeName { | ||
| /// Convert the type name into a type. | ||
| pub fn to_type<'brand>(&self, ctx: &types::Context<'brand>) -> Type<'brand> { | ||
|
|
@@ -70,6 +83,40 @@ impl TypeName { | |
| } | ||
| } | ||
|
|
||
| /// Compute the TMR of the type name. | ||
| pub fn tmr(&self) -> Tmr { | ||
| let mut stack = Vec::with_capacity(16); | ||
|
|
||
| for c in self.0.iter().rev() { | ||
| match c { | ||
| b'1' => stack.push(Tmr::unit()), | ||
| b'2' => stack.push(Tmr::TWO_TWO_N[0]), | ||
| b'c' => stack.push(Tmr::TWO_TWO_N[3]), | ||
| b's' => stack.push(Tmr::TWO_TWO_N[4]), | ||
| b'i' => stack.push(Tmr::TWO_TWO_N[5]), | ||
| b'l' => stack.push(Tmr::TWO_TWO_N[6]), | ||
| b'h' => stack.push(Tmr::TWO_TWO_N[8]), | ||
| b'+' | b'*' => { | ||
| let left = stack.pop().expect("Illegal type name syntax!"); | ||
| let right = stack.pop().expect("Illegal type name syntax!"); | ||
|
|
||
| match c { | ||
| b'+' => stack.push(Tmr::sum(left, right)), | ||
| b'*' => stack.push(Tmr::product(left, right)), | ||
| _ => unreachable!(), | ||
| } | ||
| } | ||
| _ => panic!("Illegal type name syntax!"), | ||
| } | ||
| } | ||
|
|
||
| if stack.len() == 1 { | ||
| stack.pop().unwrap() | ||
| } else { | ||
| panic!("Illegal type name syntax!") | ||
| } | ||
| } | ||
|
|
||
| /// Convert the type name into a type's bitwidth. | ||
| /// | ||
| /// This is more efficient than creating the type and computing its bit-width | ||
|
|
@@ -106,3 +153,26 @@ impl TypeName { | |
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use crate::jet::{Core, Jet}; | ||
|
|
||
| #[test] | ||
| fn all_jet_tmrs() { | ||
| for jet in &Core::ALL { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Core is probably sufficient, but there may be some types in Elements that are not in Core.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I considered that, but then I'd have to feature-gate the test and it seemed like the effort was not worth the additional coverage. |
||
| let source_final = jet.source_ty().to_final(); | ||
| let target_final = jet.target_ty().to_final(); | ||
|
|
||
| assert_eq!(*source_final, jet.source_ty()); | ||
| assert_eq!(jet.source_ty(), *source_final); | ||
| assert_eq!(source_final.tmr(), jet.source_ty().tmr()); | ||
| assert_eq!(source_final.bit_width(), jet.source_ty().to_bit_width()); | ||
|
|
||
| assert_eq!(*target_final, jet.target_ty()); | ||
| assert_eq!(jet.target_ty(), *target_final); | ||
| assert_eq!(target_final.tmr(), jet.target_ty().tmr()); | ||
| assert_eq!(target_final.bit_width(), jet.target_ty().to_bit_width()); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These repeated mappings might be a source of errors in future. Not how to clean it up though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, Rust is really bad at expressing abstract algorithms. Not much we can do.