feat(stdlib): 2D Vector type + Vector.* namespace (issue #25)
Some checks failed
docs / build-and-deploy (push) Has been cancelled
Some checks failed
docs / build-and-deploy (push) Has been cancelled
Implement the Vec.* half of #25 under the proper (de-abbreviated) name Vector, unblocking it with a self-contained value type instead of waiting on the full #1 type system. A Vector is two Q16.16 fixed components (x, y) packed into one i64 — a true by-value type that lives in a register and never allocates (reuses the new `long`/i64 support; llty maps `Vector` to i64). Fifteen operations, all deterministic fixed-point reusing fx_mul/fx_div/fx_lerp and the @fn_fx_* prelude: make/zero/x/y, add/sub/scale/dot, length/distance/normalize/lerp, rotate/angle/from_angle. New selfhost/emit_vector.ludic (wired into emit_ns_call + the frag list), the `Vector` primitive type in llty and the grammars/LSP/JetBrains tokens, docs (type-vector + 15 Vector.* pages + section), and a registered test. Reseeded; C-free fixpoint holds; all suites green (45/25/29); site + check.py OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2e0047514b
commit
121053e179
30 changed files with 13740 additions and 11881 deletions
21
docs/language/types/type-vector.md
Normal file
21
docs/language/types/type-vector.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
id: type-vector
|
||||
name: Vector
|
||||
category: types
|
||||
kind: type
|
||||
tokens: Vector
|
||||
sig: Vector
|
||||
tip: A 2D vector — two fixed components (x, y), copied by value.
|
||||
order: 13
|
||||
---
|
||||
|
||||
<code>Vector</code> is a 2D vector: two Q16.16 <code>fixed</code> components, <code>x</code> and <code>y</code>, packed into a single value that is copied by value and never heap-allocates. It is the natural type for positions, velocities, directions, and offsets. Build one with <code>Vector.make(x, y)</code> (or <code>Vector.zero()</code>), read the parts with <code>Vector.x</code> / <code>Vector.y</code>, and combine them with the <code>Vector.*</code> math — add, scale, dot, length, normalize, rotate, and the rest. Every operation is deterministic fixed-point, so results are bit-identical on every platform.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let velocity: Vector = Vector.scale(Vector.from_angle(heading), speed)
|
||||
position = Vector.add(position, velocity)
|
||||
}
|
||||
}
|
||||
```
|
||||
7
docs/language/vector/_section.md
Normal file
7
docs/language/vector/_section.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
id: vector
|
||||
title: Vector
|
||||
order: 7
|
||||
---
|
||||
|
||||
2D vector math for positions, velocities, and directions. A <code>Vector</code> is a pair of Q16.16 fixed components packed into one value, so it is copied by value and never allocates. Every operation is deterministic integer fixed-point — bit-identical on every platform, the same guarantee the rest of the runtime gives. Arguments are positional; angles are in radians.
|
||||
22
docs/language/vector/vector-add.md
Normal file
22
docs/language/vector/vector-add.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-add
|
||||
name: Vector.add
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.add
|
||||
sig: Vector.add(a, b) -> Vector
|
||||
tip: Component-wise sum a + b.
|
||||
order: 4
|
||||
ns: Vector
|
||||
member: add
|
||||
---
|
||||
|
||||
Returns the component-wise sum <code>a + b</code> — the workhorse for stepping a position by a velocity each frame.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
pos = Vector.add(pos, velocity)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-angle.md
Normal file
22
docs/language/vector/vector-angle.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-angle
|
||||
name: Vector.angle
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.angle
|
||||
sig: Vector.angle(v) -> fixed
|
||||
tip: The angle of a vector in radians.
|
||||
order: 13
|
||||
ns: Vector
|
||||
member: angle
|
||||
---
|
||||
|
||||
Returns the angle of <code>v</code> in radians, measured from +x, in the range -pi..pi (via <code>atan2</code>). Feed it back into <code>Vector.from_angle</code> or <code>Vector.rotate</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let heading = Vector.angle(velocity)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-distance.md
Normal file
22
docs/language/vector/vector-distance.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-distance
|
||||
name: Vector.distance
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.distance
|
||||
sig: Vector.distance(a, b) -> fixed
|
||||
tip: The distance between two points.
|
||||
order: 9
|
||||
ns: Vector
|
||||
member: distance
|
||||
---
|
||||
|
||||
Returns the distance between points <code>a</code> and <code>b</code> — <code>Vector.length(Vector.sub(a, b))</code>. Handy for range checks and proximity triggers.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
if Vector.distance(pos, target) < 8.0 { arrived() }
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-dot.md
Normal file
22
docs/language/vector/vector-dot.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-dot
|
||||
name: Vector.dot
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.dot
|
||||
sig: Vector.dot(a, b) -> fixed
|
||||
tip: The dot product of two vectors.
|
||||
order: 7
|
||||
ns: Vector
|
||||
member: dot
|
||||
---
|
||||
|
||||
Returns the dot product <code>ax*bx + ay*by</code> as a <code>fixed</code>. Zero when the vectors are perpendicular; use it to project one vector onto another or to test facing.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let facing = Vector.dot(forward, toTarget)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-from_angle.md
Normal file
22
docs/language/vector/vector-from_angle.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-from_angle
|
||||
name: Vector.from_angle
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.from_angle
|
||||
sig: Vector.from_angle(a) -> Vector
|
||||
tip: A unit vector pointing at an angle.
|
||||
order: 14
|
||||
ns: Vector
|
||||
member: from_angle
|
||||
---
|
||||
|
||||
Returns the unit vector <code>(cos a, sin a)</code> pointing at <code>a</code> radians. Scale it by a speed to launch a projectile in a chosen direction.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let shot = Vector.scale(Vector.from_angle(aim), 200.0)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-length.md
Normal file
22
docs/language/vector/vector-length.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-length
|
||||
name: Vector.length
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.length
|
||||
sig: Vector.length(v) -> fixed
|
||||
tip: The length (magnitude) of a vector.
|
||||
order: 8
|
||||
ns: Vector
|
||||
member: length
|
||||
---
|
||||
|
||||
Returns the Euclidean length of <code>v</code>, computed with the deterministic fixed-point square root. When you only need to compare magnitudes, comparing <code>Vector.dot(v, v)</code> avoids the square root.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let speed = Vector.length(velocity)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-lerp.md
Normal file
22
docs/language/vector/vector-lerp.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-lerp
|
||||
name: Vector.lerp
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.lerp
|
||||
sig: Vector.lerp(a, b, t) -> Vector
|
||||
tip: Linear interpolation between two vectors.
|
||||
order: 11
|
||||
ns: Vector
|
||||
member: lerp
|
||||
---
|
||||
|
||||
Returns the component-wise linear interpolation between <code>a</code> and <code>b</code> by <code>t</code> (a <code>fixed</code> in 0.0..1.0). Great for smoothing a camera toward a target.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
camera = Vector.lerp(camera, target, 0.1)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-make.md
Normal file
22
docs/language/vector/vector-make.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-make
|
||||
name: Vector.make
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.make
|
||||
sig: Vector.make(x, y) -> Vector
|
||||
tip: Build a vector from x and y components.
|
||||
order: 0
|
||||
ns: Vector
|
||||
member: make
|
||||
---
|
||||
|
||||
Builds a <code>Vector</code> from its <code>x</code> and <code>y</code> components (both <code>fixed</code>). This is the usual way to make a position or a velocity; read the parts back with <code>Vector.x</code> and <code>Vector.y</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let pos = Vector.make(64.0, 32.0)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-normalize.md
Normal file
22
docs/language/vector/vector-normalize.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-normalize
|
||||
name: Vector.normalize
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.normalize
|
||||
sig: Vector.normalize(v) -> Vector
|
||||
tip: A unit vector in the same direction.
|
||||
order: 10
|
||||
ns: Vector
|
||||
member: normalize
|
||||
---
|
||||
|
||||
Returns a unit-length vector pointing the same way as <code>v</code>. The zero vector maps to itself, so this never divides by zero. Scale the result by a speed to build a velocity.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let dir = Vector.normalize(Vector.sub(target, pos))
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-rotate.md
Normal file
22
docs/language/vector/vector-rotate.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-rotate
|
||||
name: Vector.rotate
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.rotate
|
||||
sig: Vector.rotate(v, angle) -> Vector
|
||||
tip: Rotate a vector by an angle in radians.
|
||||
order: 12
|
||||
ns: Vector
|
||||
member: rotate
|
||||
---
|
||||
|
||||
Returns <code>v</code> rotated counter-clockwise by <code>angle</code> radians, using the deterministic fixed-point sine table. Positive angles turn toward +y.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let aimed = Vector.rotate(forward, spin)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-scale.md
Normal file
22
docs/language/vector/vector-scale.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-scale
|
||||
name: Vector.scale
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.scale
|
||||
sig: Vector.scale(v, s) -> Vector
|
||||
tip: Scale a vector by a scalar.
|
||||
order: 6
|
||||
ns: Vector
|
||||
member: scale
|
||||
---
|
||||
|
||||
Returns <code>v</code> scaled by the <code>fixed</code> factor <code>s</code>. Multiply a direction by a speed, or a velocity by delta-time.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let step = Vector.scale(direction, speed)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-sub.md
Normal file
22
docs/language/vector/vector-sub.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-sub
|
||||
name: Vector.sub
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.sub
|
||||
sig: Vector.sub(a, b) -> Vector
|
||||
tip: Component-wise difference a - b.
|
||||
order: 5
|
||||
ns: Vector
|
||||
member: sub
|
||||
---
|
||||
|
||||
Returns the component-wise difference <code>a - b</code> — the vector that points from <code>b</code> to <code>a</code>. Pair it with <code>Vector.length</code> or <code>Vector.normalize</code> to get a distance or a direction.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let toTarget = Vector.sub(target, pos)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-x.md
Normal file
22
docs/language/vector/vector-x.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-x
|
||||
name: Vector.x
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.x
|
||||
sig: Vector.x(v) -> fixed
|
||||
tip: The x component of a vector.
|
||||
order: 2
|
||||
ns: Vector
|
||||
member: x
|
||||
---
|
||||
|
||||
Returns the <code>x</code> component of <code>v</code> as a <code>fixed</code>. The companion of <code>Vector.y</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let px = Vector.x(pos)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-y.md
Normal file
22
docs/language/vector/vector-y.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-y
|
||||
name: Vector.y
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.y
|
||||
sig: Vector.y(v) -> fixed
|
||||
tip: The y component of a vector.
|
||||
order: 3
|
||||
ns: Vector
|
||||
member: y
|
||||
---
|
||||
|
||||
Returns the <code>y</code> component of <code>v</code> as a <code>fixed</code>. The companion of <code>Vector.x</code>.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
let py = Vector.y(pos)
|
||||
}
|
||||
}
|
||||
```
|
||||
22
docs/language/vector/vector-zero.md
Normal file
22
docs/language/vector/vector-zero.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
id: vector-zero
|
||||
name: Vector.zero
|
||||
category: vector
|
||||
kind: namespace-method
|
||||
tokens: Vector.zero
|
||||
sig: Vector.zero() -> Vector
|
||||
tip: The zero vector, (0, 0).
|
||||
order: 1
|
||||
ns: Vector
|
||||
member: zero
|
||||
---
|
||||
|
||||
Returns the zero vector <code>(0, 0)</code> — a convenient identity for accumulating a sum of vectors or clearing a velocity.
|
||||
|
||||
```ludic
|
||||
program Demo {
|
||||
handler Step phase Update {
|
||||
var velocity = Vector.zero()
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue