Skip to content

Commit

Permalink
Implement fract (#1040)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis authored Jan 7, 2025
1 parent 92018b5 commit e0dcec4
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
8 changes: 8 additions & 0 deletions alan/src/compile/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,14 @@ test_gpgpu!(gpu_fma => r#"
stdout "10.0\n";
);

test_gpgpu!(gpu_fract => r#"
export fn main {
let b = GBuffer([1.0.f32, 3.14.f32]);
b.map(fn (val: gf32) = val.fract).read{f32}.map(fn (v: f32) = v.string(2)).join(", ").print;
}"#;
stdout "0.00, 0.14\n";
);

// TODO: Fix u64 numeric constants to get u64 bitwise tests in the new test suite
test!(u64_bitwise => r#"
prefix u64 as ~ precedence 10
Expand Down
13 changes: 9 additions & 4 deletions alan/test.ln
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ export fn{Test} main {
.assert(eq, 1.5.f32.saturate, 1.0.f32))
.it('dot').assert(eq, {f32[2]}(3.f32, 4.f32) *. {f32[2]}(3.f32, 4.f32), 25.f32)
.it('inverseSqrt').assert(eq, 4.f32.inverseSqrt, 0.5.f32)
.it('fma').assert(eq, 2.f32.fma(3.f32, 4.f32), 10.f32);
.it('fma').assert(eq, 2.f32.fma(3.f32, 4.f32), 10.f32)
.it('fract').assert(eq, 3.14.f32.fract.string(2), 0.14.f32.string(2));

test.describe("Basic math tests f64")
.it("add")
Expand Down Expand Up @@ -497,7 +498,8 @@ export fn{Test} main {
.assert(eq, 1.5.saturate, 1.0))
.it('dot').assert(eq, {f64[2]}(3.0, 4.0) *. {f64[2]}(3.0, 4.0), 25.0)
.it('inverseSqrt').assert(eq, 25.0.inverseSqrt, 0.2)
.it('fma').assert(eq, 2.0.fma(3.0, 4.0), 10.0);
.it('fma').assert(eq, 2.0.fma(3.0, 4.0), 10.0)
.it('fract').assert(eq, 3.14.fract.string(2), 0.14.string(2));

test.describe("Basic math tests")
.it("grouping")
Expand Down Expand Up @@ -972,7 +974,8 @@ export fn{Test} main {
eq,
(fma([2.0, 3.0, 4.0], [3.0, 4.0, 2.0], [4.0, 2.0, 3.0])!!)
.map(fn (v: f64) = string(v, 1)).join(', '),
'10.0, 14.0, 11.0');
'10.0, 14.0, 11.0')
.it('fract').assert(eq, [1.0, 3.14].fract.map(fn (v: f64) = v.string(2)).join(', '), '0.00, 0.14');

test.describe("Buffers")
.it("join", fn (test: Mut{Testing}) {
Expand Down Expand Up @@ -1056,7 +1059,9 @@ export fn{Test} main {
eq,
fma({f64[3]}(2.0, 3.0, 4.0), {f64[3]}(3.0, 4.0, 2.0), {f64[3]}(4.0, 2.0, 3.0))
.map(fn (v: f64) = string(v, 1)).join(', '),
'10.0, 14.0, 11.0');
'10.0, 14.0, 11.0')
.it('fract')
.assert(eq, {f64[2]}(1.0, 3.14).fract.map(fn (v: f64) = v.string(2)).join(', '), '0.00, 0.14');

test.describe("Conditionals")
.it("if function")
Expand Down
17 changes: 17 additions & 0 deletions alan_compiler/src/std/root.ln
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,8 @@ fn{Rs} inverseSqrt (v: f32) = {Method{"recip"} :: f32 -> f32}(sqrt(v));
fn{Js} inverseSqrt (v: f32) = 1.0.f32 / sqrt(v);
fn{Rs} fma Method{"mul_add"} :: (f32, Deref{f32}, Deref{f32}) -> f32;
fn{Js} fma "((a, b, c) => new alan_std.F32(a.val * b.val + c.val))" <- RootBacking :: (f32, f32, f32) -> f32;
fn{Rs} fract Method{"fract"} :: f32 -> f32;
fn{Js} fract "((a) => new alan_std.F32(a.val % 1))" <- RootBacking :: f32 -> f32;

fn{Rs} add Infix{"+"} :: (f64, f64) -> f64;
fn{Js} add "((a, b) => new alan_std.F64(a.val + b.val))" <- RootBacking :: (f64, f64) -> f64;
Expand Down Expand Up @@ -707,6 +709,8 @@ fn{Rs} inverseSqrt (v: f64) = {Method{"recip"} :: f64 -> f64}(sqrt(v));
fn{Js} inverseSqrt (v: f64) = 1.0 / sqrt(v);
fn{Rs} fma Method{"mul_add"} :: (f64, Deref{f64}, Deref{f64}) -> f64;
fn{Js} fma "((a, b, c) => new alan_std.F32(a.val * b.val + c.val))" <- RootBacking :: (f64, f64, f64) -> f64;
fn{Rs} fract Method{"fract"} :: f64 -> f64;
fn{Js} fract "((a) => new alan_std.F64(a.val % 1))" <- RootBacking :: f64 -> f64;

/// Unsigned Integer-related functions and function bindings
fn{Rs} add Method{"wrapping_add"} :: (u8, Deref{u8}) -> u8;
Expand Down Expand Up @@ -1355,6 +1359,8 @@ fn fma(a: f64[], b: f64[], c: f64[]) -> Fallible{f64[]} {
return Error{f64[]}("Fused multiply-add on arrays requires equal-length arrays");
});
}
fn fract(a: f32[]) = a.map(fract);
fn fract(a: f64[]) = a.map(fract);

/// Buffer related bindings
fn{Rs} get{T, S} "alan_std::getbuffer" <- RootBacking :: (T[S], i64) -> T?;
Expand Down Expand Up @@ -1420,6 +1426,8 @@ fn inverseSqrt{S}(buf: f32[S]) = buf.map(inverseSqrt);
fn inverseSqrt{S}(buf: f64[S]) = buf.map(inverseSqrt);
fn fma{S}(a: Buffer{f32, S}, b: Buffer{f32, S}, c: Buffer{f32, S}) = a.map(fn (v: f32, i: i64) = v.fma(b[i]!!, c[i]!!));
fn fma{S}(a: Buffer{f64, S}, b: Buffer{f64, S}, c: Buffer{f64, S}) = a.map(fn (v: f64, i: i64) = v.fma(b[i]!!, c[i]!!));
fn fract{S}(a: Buffer{f32, S}) = a.map(fract);
fn fract{S}(a: Buffer{f64, S}) = a.map(fract);

/// Dictionary-related bindings
fn{Rs} Dict{K, V} "alan_std::OrderedHashMap::new" <- RootBacking :: () -> Dict{K, V};
Expand Down Expand Up @@ -4118,6 +4126,15 @@ fn fma(a: gvec2f, b: gvec2f, c: gvec2f) = gFma(a, b, c);
fn fma(a: gvec3f, b: gvec3f, c: gvec3f) = gFma(a, b, c);
fn fma(a: gvec4f, b: gvec4f, c: gvec4f) = gFma(a, b, c);

fn gFract{I}(a: I) {
let varName = 'fract('.concat(a.varName).concat(')');
return {I}(varName, a.statements, a.buffers);
}
fn fract(a: gf32) = gFract(a);
fn fract(a: gvec2f) = gFract(a);
fn fract(a: gvec3f) = gFract(a);
fn fract(a: gvec4f) = gFract(a);

fn gadd{A, B}(a: A, b: B) {
let varName = '('.concat(a.varName).concat(' + ').concat(b.varName).concat(')');
let statements = a.statements.concat(b.statements);
Expand Down

0 comments on commit e0dcec4

Please sign in to comment.