Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions benchmark/biquad_f64.lyte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Biquad filter DSP benchmark
// Process 10 million samples through a lowpass filter
// Double-precision version using f32 literals cast to f64.
// Double-precision version

struct Biquad {
b0: f64, b1: f64, b2: f64,
Expand All @@ -11,28 +11,28 @@ struct Biquad {

// Design a 2nd-order lowpass (RBJ cookbook)
lpf(fc: f64, fs: f64, q: f64) -> Biquad {
var w0 = (2.0 as f64) * (3.14159265 as f64) * fc / fs
var alpha = sin(w0) / ((2.0 as f64) * q)
var w0 = 2.0f64 * 3.141592653589793f64 * fc / fs
var alpha = sin(w0) / (2.0f64 * q)
var cs = cos(w0)

var a0 = (1.0 as f64) + alpha
var inv = (1.0 as f64) / a0
var a0 = 1.0f64 + alpha
var inv = 1.0f64 / a0

var bq: Biquad
bq.b1 = ((1.0 as f64) - cs) * inv
bq.b0 = bq.b1 / (2.0 as f64)
bq.b1 = (1.0f64 - cs) * inv
bq.b0 = bq.b1 / 2.0f64
bq.b2 = bq.b0
bq.a1 = ((0.0 as f64) - (2.0 as f64) * cs) * inv
bq.a2 = ((1.0 as f64) - alpha) * inv
bq.x1 = 0.0 as f64
bq.x2 = 0.0 as f64
bq.y1 = 0.0 as f64
bq.y2 = 0.0 as f64
bq.a1 = (0.0f64 - 2.0f64 * cs) * inv
bq.a2 = (1.0f64 - alpha) * inv
bq.x1 = 0.0f64
bq.x2 = 0.0f64
bq.y1 = 0.0f64
bq.y2 = 0.0f64
return bq
}

main {
var bq = lpf(1000.0 as f64, 44100.0 as f64, 0.707 as f64)
var bq = lpf(1000.0f64, 44100.0f64, 0.707f64)
var b0 = bq.b0
var b1 = bq.b1
var b2 = bq.b2
Expand All @@ -44,16 +44,16 @@ main {
var y2 = bq.y2

var n = 10000000
var phase = 0.0 as f64
var freq = (440.0 as f64) / (44100.0 as f64)
var last_y = 0.0 as f64
var two_pi = (2.0 as f64) * (3.14159265 as f64)
var phase = 0.0f64
var freq = 440.0f64 / 44100.0f64
var last_y = 0.0f64
var two_pi = 2.0f64 * 3.141592653589793f64

// Process a 440 Hz sine wave through the filter
for i in 0 .. n {
var x = sin(phase * two_pi)
phase = phase + freq
if phase > (1.0 as f64) { phase = phase - (1.0 as f64) }
if phase > 1.0f64 { phase = phase - 1.0f64 }

var y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2
x2 = x1
Expand Down
5 changes: 3 additions & 2 deletions docs/GRAMMAR.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ digit = "0".."9" ;
id = ( alpha ) { alpha | digit } ;

integer = digit { digit } ;
uinteger = integer "u" ;
int_lit = integer [ "i32" | "u32" | "u" ] ;
real = digit { digit } "." digit { digit } ;
real_lit = real [ "f32" | "f64" ] ;
char_lit = "'" ( char | "\\" ( "\\" | "n" ) ) "'" ;
string_lit = '"' { any - '"' } '"' ;

Expand Down Expand Up @@ -90,7 +91,7 @@ postfix = atom { "(" [ exprlist ] ")" (* function call *)
} ;

atom = id
| integer | uinteger | real
| int_lit | real_lit
| char_lit | string_lit
| "true" | "false"
| "." id (* enum variant *)
Expand Down
24 changes: 21 additions & 3 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ Note for Lua users: Lua lets one variable hold different kinds of values over ti

| Type | What it is | Example values |
|------|------------|----------------|
| `i32` | A whole number (integer) | `42`, `-7`, `0` |
| `f32` | A decimal number (float) | `3.14`, `-0.5`, `1.0` |
| `i32` | A whole number (integer) | `42`, `-7`, `0`, `42i32` |
| `f32` | A decimal number (float) | `3.14`, `-0.5`, `1.0`, `1.0f32` |
| `bool` | True or false | `true`, `false` |
| `str` | Text (a string in quotes) | `"hello"` |
| `i8` | A very small whole number, used for individual characters | `65` (the letter `A`) |
| `u32` | A whole number that cannot be negative (unsigned) | `42`, `0` |
| `u32` | A whole number that cannot be negative (unsigned) | `42u32`, `42u`, `0u32` |

Single characters can also be written with single quotes: `'a'`, `'Z'`, `'\n'` (newline). This is called a character literal.

Expand All @@ -103,6 +103,24 @@ In audio and DSP work, you will use `f32` constantly. Audio signals, frequencies

**A note on `f64`:** The language grammar also defines an `f64` type, which is a higher-precision decimal number. In Audulus DSP work, `f32` is the type you'll usually use.

By default, whole-number literals are `i32`, and decimal literals are `f32`.

### Numeric literal suffixes

Numeric literals can include a type suffix when you need the literal itself to have a specific type:

```lyte
main {
var count = 1i32
var mask = 1u32
var also_unsigned = 1u
var gain = 1.0f32
var precise = 1.0f64
}
```

Use `as` when converting an existing value or expression from one type to another, such as `x as i32` or `(len - 2) as f32`.

### Why does static typing matter?

In audio DSP, you are doing a lot of math very quickly. If the language has to keep figuring out what kind of value something is while it runs, that adds overhead. By knowing the types up front, Lyte can build faster code. Here, **compile** just means “turn your code into something the computer can run.”
Expand Down
6 changes: 3 additions & 3 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2159,15 +2159,15 @@ mod tests {
// f32 if-expression in void context.
("f32 if in void ctx", r#"
main {
var x = 0.0 as f32
var x = 0.0f32
if true { x = 1.0 } else { x = 2.0 }
}
"#),
// f32 assignment RHS.
("f32 assign chain", r#"
main {
var x = 0.0 as f32
var y = 0.0 as f32
var x = 0.0f32
var y = 0.0f32
x = 1.5
y = x + x
}
Expand Down
6 changes: 3 additions & 3 deletions src/stack_optimize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,9 +727,9 @@ fn fuse(func: &mut StackFunction) {
// before the 3-op one so the longest match wins at each position.

// Constant-fold fw.f32.const v + dw.convert.f32_to_f64 → dw.f64.const.
// Widening f32→f64 is exact, so this is always valid; it both folds
// the many `<lit> as f64` conversions and exposes the constant to
// the d-window compare-jump fusion below.
// Widening f32→f64 is exact, so this is always valid; it folds explicit
// f32-to-f64 conversions and exposes the constant to the d-window
// compare-jump fusion below.
if i + 1 < len && !spans_target(i, 2) {
if let (StackOp::F32ConstF(v), StackOp::F32ToF64D) = (&ops[i], &ops[i + 1]) {
let v = *v as f64;
Expand Down
10 changes: 5 additions & 5 deletions stdlib.lyte
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ step(edge: f32, x: f32) -> f32 {
}

step(edge: f64, x: f64) -> f64 {
if x < edge { return 0.0 as f64 }
return 1.0 as f64
if x < edge { return 0.0f64 }
return 1.0f64
}

smoothstep(edge0: f32, edge1: f32, x: f32) -> f32 {
Expand All @@ -27,8 +27,8 @@ smoothstep(edge0: f32, edge1: f32, x: f32) -> f32 {
}

smoothstep(edge0: f64, edge1: f64, x: f64) -> f64 {
var t = clamp((x - edge0) / (edge1 - edge0), 0.0 as f64, 1.0 as f64)
t * t * ((3.0 as f64) - (2.0 as f64) * t)
var t = clamp((x - edge0) / (edge1 - edge0), 0.0f64, 1.0f64)
t * t * (3.0f64 - 2.0f64 * t)
}

mix(a: f32, b: f32, t: f32) -> f32 { a + t * (b - a) }
Expand Down Expand Up @@ -242,4 +242,4 @@ strcat(dst: [i8], src: [i8]) {
}
}
}
}
}
46 changes: 23 additions & 23 deletions tests/cases/f64_window.lyte
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ struct Acc { a: f64, b: f64, c: f64 }

approx(x: f64, y: f64) -> bool {
var d = x - y
if d < 0.0 as f64 { d = 0.0 as f64 - d }
return d < 0.0001 as f64
if d < 0.0f64 { d = 0.0f64 - d }
return d < 0.0001f64
}

// f64 argument and return value bridging across a call.
Expand All @@ -36,44 +36,44 @@ fma(a: f64, b: f64, c: f64) -> f64 {
}

main {
var x = 3.0 as f64
var y = 2.0 as f64
var x = 3.0f64
var y = 2.0f64

// Arithmetic.
assert(approx(x + y, 5.0 as f64))
assert(approx(x - y, 1.0 as f64))
assert(approx(x * y, 6.0 as f64))
assert(approx(x / y, 1.5 as f64))
assert(approx(0.0 as f64 - x, -3.0 as f64))
assert(approx(x + y, 5.0f64))
assert(approx(x - y, 1.0f64))
assert(approx(x * y, 6.0f64))
assert(approx(x / y, 1.5f64))
assert(approx(0.0f64 - x, -3.0f64))

// All six comparisons.
assert(x > y)
assert(y < x)
assert(x >= 3.0 as f64)
assert(y <= 2.0 as f64)
assert(x == 3.0 as f64)
assert(x >= 3.0f64)
assert(y <= 2.0f64)
assert(x == 3.0f64)
assert(x != y)

// Fused multiply-add sum chain: b0*x + b1*x1 - b2*x2.
var b0 = 1.0 as f64
var b1 = 2.0 as f64
var b2 = 0.5 as f64
var x1 = 4.0 as f64
var x2 = 6.0 as f64
var b0 = 1.0f64
var b1 = 2.0f64
var b2 = 0.5f64
var x1 = 4.0f64
var x2 = 6.0f64
var sum = b0 * x + b1 * x1 - b2 * x2
// 1*3 + 2*4 - 0.5*6 = 3 + 8 - 3 = 8
assert(approx(sum, 8.0 as f64))
assert(approx(sum, 8.0f64))

// f64 across a function call (argument + return bridging).
assert(approx(fma(x, y, 1.0 as f64), 7.0 as f64))
assert(approx(fma(x, y, 1.0f64), 7.0f64))

// Math intrinsic + struct store/load through the d-window.
var acc: Acc
acc.a = sqrt(16.0 as f64)
acc.b = acc.a * 2.0 as f64
acc.a = sqrt(16.0f64)
acc.b = acc.a * 2.0f64
acc.c = acc.a + acc.b
assert(approx(acc.c, 12.0 as f64))
assert(approx(acc.c, 12.0f64))

// Conversion round trip f64 -> i32.
print((x * y * 7.0 as f64) as i32)
print((x * y * 7.0f64) as i32)
}
4 changes: 2 additions & 2 deletions tests/cases/int_types.lyte
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ main {

// u32 arithmetic
var x: u32
x = 100 as u32
x = 100u32
var y: u32
y = 50 as u32
y = 50u32
assert(x as i32 - y as i32 == 50)

// u32 comparison
Expand Down
14 changes: 7 additions & 7 deletions tests/cases/int_types_f64.lyte
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@

approx(a: f64, b: f64) -> bool {
var d = a - b
if d < 0.0 as f64 { d = 0.0 as f64 - d }
return d < 0.0001 as f64
if d < 0.0f64 { d = 0.0f64 - d }
return d < 0.0001f64
}

main {
var x: f64
x = 3.0 as f64
x = 3.0f64
var y: f64
y = 2.0 as f64
y = 2.0f64

// f64 arithmetic with helper function
assert(approx(x + y, 5.0 as f64))
assert(approx(x - y, 1.0 as f64))
assert(approx(x * y, 6.0 as f64))
assert(approx(x + y, 5.0f64))
assert(approx(x - y, 1.0f64))
assert(approx(x * y, 6.0f64))

// f64 comparisons
assert(x > y)
Expand Down
4 changes: 2 additions & 2 deletions tests/cases/int_types_u32.lyte
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
main {
// u32 arithmetic
var a: u32
a = 100 as u32
a = 100u32
var b: u32
b = 40 as u32
b = 40u32
assert((a + b) as i32 == 140)
assert((a - b) as i32 == 60)
assert((a * b) as i32 == 4000)
Expand Down
6 changes: 3 additions & 3 deletions tests/cases/type_cast_f64.lyte
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@

main {
// i32 to f64
assert(100 as f64 == 100.0 as f64)
assert(100 as f64 == 100.0f64)

// f64 to i32 (truncates)
assert((3.9 as f64) as i32 == 3)

// f32 to f64 promotion
var x: f32
x = 2.5
assert(x as f64 == 2.5 as f64)
assert(x as f64 == 2.5f64)

// f64 to f32 demotion
var y: f64
y = 1.25 as f64
y = 1.25f64
assert(y as f32 == 1.25)
}
Loading