-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
91 lines (75 loc) · 2.18 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use core::fmt;
use std::{env, fs::File, io::Write, path::Path};
use bitvec::{order::Lsb0, vec::BitVec};
const HIGHEST: u64 = 1024;
fn uints() -> impl Iterator<Item = u64> {
let first2: u32 = 11; // (highest as f64).log(2.0).round() as u32 + 1;
let first10: u32 = 4; // (highest as f64).log(10.0) as u32 + 1;
(0..(HIGHEST + 1))
.chain((first2..64).map(|i| 2u64.pow(i)))
.chain((first10..20).map(|i| 10u64.pow(i)))
}
pub enum LitCode {
U0,
U1,
ZeroBit(Box<LitCode>),
OneBit(Box<LitCode>),
}
impl fmt::Display for LitCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LitCode::ZeroBit(ref bits) => write!(f, "B<{}, _0>", bits),
LitCode::OneBit(ref bits) => write!(f, "B<{}, _1>", bits),
LitCode::U0 => write!(f, "_0"),
LitCode::U1 => write!(f, "_1"),
}
}
}
pub fn gen_uint(u: u64) -> LitCode {
let bits: BitVec<u64, Lsb0> = BitVec::from_element(u);
let mut bits = bits.into_iter().take(64 - u.leading_zeros() as usize).rev();
if bits.next().is_none() {
return LitCode::U0;
}
let mut current = LitCode::U1;
for is_bit in bits {
current = if is_bit {
LitCode::OneBit(Box::new(current))
} else {
LitCode::ZeroBit(Box::new(current))
};
}
current
}
fn main() {
println!("cargo:rerun-if-changed=build/main.rs"); // Allow caching the generation if `src/*` files change.
let out_dir = env::var("OUT_DIR").unwrap();
let dest = Path::new(&out_dir).join("consts.rs");
let mut f = File::create(&dest).unwrap();
// Header stuff here!
write!(
f,
"
/**
Type aliases for many constants.
This file is generated by `type_eval`'s build script.
We define aliases for
- Numbers 0 through {highest}
- Powers of 2 below `u64::MAX`
- Powers of 10 below `u64::MAX`
These alias definitions look like this:
```rust
use type_eval::prelude::*;
# #[allow(dead_code)]
type U6 = B<B<_1, _1>, _0>;
```
*/
use crate::prelude::*;
",
highest = HIGHEST,
)
.unwrap();
for u in uints() {
writeln!(f, " pub type U{} = {};", u, gen_uint(u)).unwrap();
}
}