Skip to content

Commit

Permalink
Restored old swizzlegen code for generating swizzle tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
bitshifter committed Nov 11, 2024
1 parent bc0d551 commit b2b8d11
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ harness = false
[workspace]
members = [
"codegen",
"swizzlegen",
"test_no_std",
]

Expand Down
7 changes: 7 additions & 0 deletions swizzlegen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "swizzlegen"
version = "0.1.0"
authors = ["Cameron Hart <[email protected]>"]
edition = "2021"

[dependencies]
228 changes: 228 additions & 0 deletions swizzlegen/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
use std::fs::File;
use std::io::{Result, Write};

const E: [char; 4] = ['x', 'y', 'z', 'w']; // element name
const V: [&str; 4] = ["1", "2", "3", "4"]; // element value

fn write_swizzle_head(out: &mut impl Write) -> Result<()> {
writeln!(out, "// Generated by swizzlegen. Do not edit.")?;
Ok(())
}

fn write_loops_vec4<W, F4>(out: &mut W, size: usize, vec4fn: F4) -> Result<()>
where
W: Write,
F4: Fn(&mut W, usize, usize, usize, usize) -> Result<()>,
{
for e0 in 0..size {
for e1 in 0..size {
for e2 in 0..size {
for e3 in 0..size {
if size == 4 && e0 == 0 && e1 == 1 && e2 == 2 && e3 == 3 {
continue;
}
vec4fn(out, e0, e1, e2, e3)?;
}
}
}
}
Ok(())
}

fn write_loops_vec3<W, F3>(out: &mut W, size: usize, vec3fn: F3) -> Result<()>
where
W: Write,
F3: Fn(&mut W, usize, usize, usize) -> Result<()>,
{
for e0 in 0..size {
for e1 in 0..size {
for e2 in 0..size {
if size == 3 && e0 == 0 && e1 == 1 && e2 == 2 {
continue;
}
vec3fn(out, e0, e1, e2)?;
}
}
}
Ok(())
}

fn write_loops_vec2<W, F2>(out: &mut W, size: usize, vec2fn: F2) -> Result<()>
where
W: Write,
F2: Fn(&mut W, usize, usize) -> Result<()>,
{
for e0 in 0..size {
for e1 in 0..size {
if size == 2 && e0 == 0 && e1 == 1 {
continue;
}
vec2fn(out, e0, e1)?;
}
}
Ok(())
}

fn write_test_vec4(
out: &mut impl Write,
t: &str,
vec4t: &str,
vec3t: &str,
vec2t: &str,
) -> Result<()> {
const SIZE: usize = 4;

write!(
out,
r#"
glam_test!(test_{}_swizzles, {{
let v = {}(1_{}, 2_{}, 3_{}, 4_{});
"#,
vec4t, vec4t, t, t, t, t,
)?;

writeln!(out, " assert_eq!(v, v.xyzw());")?;

write_test_loops(out, SIZE, t, vec4t, vec3t, vec2t)?;

writeln!(out, "}});")?;

Ok(())
}

fn write_test_vec3(
out: &mut impl Write,
t: &str,
vec4t: &str,
vec3t: &str,
vec2t: &str,
) -> Result<()> {
const SIZE: usize = 3;

write!(
out,
r#"
glam_test!(test_{}_swizzles, {{
let v = {}(1_{}, 2_{}, 3_{});
"#,
vec3t, vec3t, t, t, t,
)?;

writeln!(out, " assert_eq!(v, v.xyz());")?;

write_test_loops(out, SIZE, t, vec4t, vec3t, vec2t)?;

writeln!(out, "}});")?;

Ok(())
}

fn write_test_vec2(
out: &mut impl Write,
t: &str,
vec4t: &str,
vec3t: &str,
vec2t: &str,
) -> Result<()> {
const SIZE: usize = 2;

write!(
out,
r#"
glam_test!(test_{}_swizzles, {{
let v = {}(1_{}, 2_{});
"#,
vec2t, vec2t, t, t,
)?;

writeln!(out, " assert_eq!(v, v.xy());")?;

write_test_loops(out, SIZE, t, vec4t, vec3t, vec2t)?;

writeln!(out, "}});")?;

Ok(())
}

fn write_test_loops(
out: &mut impl Write,
size: usize,
t: &str,
vec4t: &str,
vec3t: &str,
vec2t: &str,
) -> Result<()> {
write_loops_vec4(out, size, |out, e0, e1, e2, e3| {
writeln!(
out,
" assert_eq!(v.{}{}{}{}(), {}({}_{}, {}_{}, {}_{}, {}_{}));",
E[e0], E[e1], E[e2], E[e3], vec4t, V[e0], t, V[e1], t, V[e2], t, V[e3], t
)
})?;
write_loops_vec3(out, size, |out, e0, e1, e2| {
writeln!(
out,
" assert_eq!(v.{}{}{}(), {}({}_{}, {}_{}, {}_{}));",
E[e0], E[e1], E[e2], vec3t, V[e0], t, V[e1], t, V[e2], t,
)
})?;
write_loops_vec2(out, size, |out, e0, e1| {
writeln!(
out,
" assert_eq!(v.{}{}(), {}({}_{}, {}_{}));",
E[e0], E[e1], vec2t, V[e0], t, V[e1], t,
)
})?;
Ok(())
}

fn write_swizzle_tests_preamble(filename: &str) -> Result<impl Write> {
let mut out = File::create(filename)?;
write_swizzle_head(&mut out)?;
writeln!(
&mut out,
r#"#[macro_use]
mod support;
use glam::*;"#
)?;
Ok(out)
}

fn write_swizzle_tests_scalar(scalar_t: &str, prefix: &str) -> Result<()> {
let vec4_t = format!("{prefix}vec4");
let vec3_t = format!("{prefix}vec3");
let vec2_t = format!("{prefix}vec2");
let mut out = write_swizzle_tests_preamble(&format!("../tests/swizzles_{scalar_t}.rs"))?;
write_test_vec4(&mut out, scalar_t, &vec4_t, &vec3_t, &vec2_t)?;
if scalar_t == "f32" {
write_test_vec3(&mut out, "f32", "vec4", "vec3a", "vec2")?;
}
write_test_vec3(&mut out, scalar_t, &vec4_t, &vec3_t, &vec2_t)?;
write_test_vec2(&mut out, scalar_t, &vec4_t, &vec3_t, &vec2_t)?;
Ok(())
}

fn write_swizzle_tests() -> Result<()> {
write_swizzle_tests_scalar("f32", "")?;
write_swizzle_tests_scalar("f64", "d")?;

write_swizzle_tests_scalar("i64", "i64")?;
write_swizzle_tests_scalar("i32", "i")?;
write_swizzle_tests_scalar("i16", "i16")?;
write_swizzle_tests_scalar("i8", "i8")?;

write_swizzle_tests_scalar("u64", "u64")?;
write_swizzle_tests_scalar("u32", "u")?;
write_swizzle_tests_scalar("u16", "u16")?;
write_swizzle_tests_scalar("u8", "u8")?;

Ok(())
}

fn main() -> Result<()> {
// Change into `./codegen` dir for convenience to the user
std::env::set_current_dir(env!("CARGO_MANIFEST_DIR"))?;

write_swizzle_tests()?;
Ok(())
}

0 comments on commit b2b8d11

Please sign in to comment.