8.6 KiB
Cordial Language Reference
Cordial is the primary source language for the Cord geometry system. It compiles to a trigonometric intermediate representation (TrigGraph) which can be evaluated as an f64 reference, compiled to WGSL shaders for GPU raymarching, or lowered to pure CORDIC shift-and-add arithmetic.
File extension: .crd
Variables
let r = 5
let height = 2 * pi
let s: Obj = sphere(r)
letintroduces a new variable.: Objtype annotation marks a variable as a renderable 3D object.- Variables can be reassigned:
r = 10(noleton reassignment).
Constants
| Name | Value |
|---|---|
pi, PI |
3.14159... |
e, E |
2.71828... |
x |
Input X coord |
y |
Input Y coord |
z |
Input Z coord |
reg |
NaN register |
x, y, z are the spatial coordinates — use them to build
mathematical expressions and SDF fields directly.
Arithmetic
| Syntax | Operation |
|---|---|
a + b |
Addition |
a - b |
Subtraction |
a * b |
Multiplication |
a / b |
Division |
a ^ b |
Power (²,³ optimized) |
-a |
Negation |
Precedence: unary > power > multiplicative > additive.
Parentheses for grouping: (a + b) * c.
Comments
// line comment
/= also a line comment
/* block comment */
/* nested /* block */ comments */
Trig Functions
| Function | Aliases | Description |
|---|---|---|
sin(x) |
Sine | |
cos(x) |
Cosine | |
tan(x) |
Tangent | |
asin(x) |
arcsin |
Inverse sine |
acos(x) |
arccos, arcos |
Inverse cosine |
atan(x) |
arctan |
Inverse tangent |
sinh(x) |
Hyperbolic sine | |
cosh(x) |
Hyperbolic cosine | |
tanh(x) |
Hyperbolic tangent | |
asinh(x) |
arcsinh |
Inverse hyperbolic sine |
acosh(x) |
arccosh, arcosh |
Inverse hyperbolic cosine |
atanh(x) |
arctanh |
Inverse hyperbolic tangent |
Math Functions
| Function | Aliases | Description |
|---|---|---|
sqrt(x) |
Square root | |
exp(x) |
e^x | |
ln(x) |
log |
Natural logarithm |
abs(x) |
Absolute value | |
hypot(a, b) |
√(a² + b²) | |
atan2(y, x) |
Two-argument arctangent | |
min(a, b) |
Minimum | |
max(a, b) |
Maximum | |
length(a, b) |
mag |
Magnitude (2D or 3D) |
mix(a, b, t) |
lerp |
Linear interpolation |
clip(x, lo, hi) |
clamp |
Clamp to range |
smoothstep(e0, e1, x) |
Hermite interpolation | |
quantize(x, step) |
Snap to grid |
SDF Primitives
These construct signed distance fields centered at the origin. All dimensions are half-extents (centered geometry).
| Function | Arguments | Description |
|---|---|---|
sphere(r) |
radius | Sphere |
box(hx, hy, hz) |
half-extents | Axis-aligned box |
cylinder(r, h) |
radius, half-height | Z-axis cylinder |
ngon(n, side) |
sides (≥3), side length | Regular polygon prism |
N-gon(side) |
side length | Shorthand: 6-gon(2) = hexagonal prism |
Transforms
Transforms take an SDF as the first argument and modify its coordinate space.
| Function | Aliases | Arguments | Description |
|---|---|---|---|
translate(sdf, tx, ty, tz) |
mov, move |
SDF + offsets | Translate |
rotate_x(sdf, angle) |
rx |
SDF + radians | Rotate around X |
rotate_y(sdf, angle) |
ry |
SDF + radians | Rotate around Y |
rotate_z(sdf, angle) |
rz |
SDF + radians | Rotate around Z |
scale(sdf, factor) |
SDF + uniform scale | Uniform scale | |
mirror_x(sdf) |
mx |
SDF | Mirror across YZ plane |
mirror_y(sdf) |
my |
SDF | Mirror across XZ plane |
mirror_z(sdf) |
mz |
SDF | Mirror across XY plane |
CSG Boolean Operations
| Function | Aliases | Arguments | Description |
|---|---|---|---|
union(a, b) |
two SDFs | Union (min) | |
intersect(a, b) |
two SDFs | Intersection (max) | |
diff(a, b) |
subtract |
two SDFs | Difference (max(a, -b)) |
Waveform Functions
| Function | Arguments | Description |
|---|---|---|
saw(x) |
input | Sawtooth wave |
tri(x) |
input | Triangle wave |
square(x) |
input | Square wave |
DSP / Signal Functions
| Function | Arguments | Description |
|---|---|---|
am(signal, carrier, depth) |
Amplitude modulation | |
fm(signal, carrier, index) |
Frequency modulation | |
lpf(signal, cutoff) |
Low-pass filter approximation | |
hpf(signal, cutoff) |
High-pass filter approximation | |
bpf(signal, lo, hi) |
Band-pass filter approximation | |
dft(signal, n) |
Discrete Fourier approximation | |
hilbert(x) |
envelope |
Analytic signal envelope |
phase(x) |
Instantaneous phase |
User-Defined Functions
f(a, b) = a^2 + b^2
let result = f(3, 4)
Define with name(params) = body. Body extends to the next
newline or semicolon. Functions are expanded inline at each call site.
Schematics (sch)
Schematics are parameterized multi-statement blocks — like functions but
with full block bodies containing let bindings, intermediate variables,
and arbitrary nesting. The last expression is the return value.
sch Bracket(w, h, t) {
let plate: Obj = box(w, h, t)
let rib: Obj = box(t, h/2, t)
union(plate, translate(rib, w/2, 0, 0))
}
let b = Bracket(10, 5, 0.5)
cast(b)
Schematics can call other schematics and user-defined functions. They can contain any number of statements.
sch Peg(r, h) {
let shaft = cylinder(r, h)
let head = translate(sphere(r * 1.5), 0, 0, h)
union(shaft, head)
}
sch PegRow(n, spacing) {
map(i, 0..n) { translate(Peg(0.5, 3), i * spacing, 0, 0) }
}
Iteration (map)
map evaluates a body for each integer in a range and unions all
results. Iteration is unrolled at parse time — the TrigGraph is a DAG
with no runtime loops.
map(variable, start..end) { body }
variable— bound to each integer in[start, end)start..end— exclusive range; bounds must resolve to constantsbody— any expression or block; can reference the iteration variable- All iterations are unioned (min)
- Max 1024 iterations
Examples
// Row of 5 spheres along X
let row = map(i, 0..5) { translate(sphere(1), i * 3, 0, 0) }
// Ring of 8 spheres
let ring = map(i, 0..8) {
rotate_z(translate(sphere(0.5), 5, 0, 0), i * pi/4)
}
// Grid using nested maps inside a schematic
sch Grid(nx, ny, spacing) {
map(i, 0..nx) {
map(j, 0..ny) {
translate(sphere(0.4), i * spacing, j * spacing, 0)
}
}
}
let g = Grid(4, 6, 2)
cast()
Since map is an expression, it works anywhere: inside let bindings,
as arguments to functions, inside schematic bodies, or nested in other maps.
Rendering with cast()
Nothing renders without an explicit cast() call.
| Syntax | Effect |
|---|---|
cast() |
Render all defined variables |
cast(name) |
Render a specific variable |
name.cast() |
Dot syntax (Obj-typed variables only) |
Multiple cast() calls accumulate. The GUI provides a Render button
that inserts cast() automatically when new variables exist since
the last cast.
Example
let a: Obj = sphere(3)
let b: Obj = box(4, 2, 1)
let c: Obj = translate(a, 5, 0, 0)
cast()
This renders a, b, and c as a union. Without cast(), nothing appears.
Plotting with plot()
| Syntax | Effect |
|---|---|
plot() |
Plot all bare expressions |
plot(expr) |
Plot a specific expression |
The GUI provides a Plot button that inserts plot() when new
expressions exist since the last plot.
Example
sin(x) * exp(-x^2)
plot()
Complete Example
// Bolt head: hexagonal prism with a sphere on top
let head: Obj = 6-gon(3)
let dome: Obj = translate(sphere(3.2), 0, 0, 1.5)
let cap: Obj = intersect(head, dome)
// Shaft
let shaft: Obj = cylinder(1.2, 8)
let bolt: Obj = union(translate(cap, 0, 0, 8), shaft)
// Cross hole
let slot: Obj = box(0.4, 3, 10)
let slot2: Obj = rotate_z(slot, pi/2)
let cross: Obj = union(slot, slot2)
let final: Obj = diff(bolt, cross)
cast(final)
Schematics + Iteration
// Reusable peg schematic
sch Peg(r, h) {
let shaft = cylinder(r, h)
let head = translate(sphere(r * 1.5), 0, 0, h)
union(shaft, head)
}
// Base plate with a ring of pegs
let plate: Obj = box(20, 20, 1)
let pegs: Obj = map(i, 0..8) {
rotate_z(translate(Peg(0.5, 3), 8, 0, 1), i * pi/4)
}
let assembly: Obj = union(plate, pegs)
cast(assembly)