Cells and functions
Cells and functions look alike but do different jobs: a cell describes layout, a function computes a value.
Cells
A cell describes layout and can be placed inside other cells:
use std::layout::rect;
cell pad(width: Float, height: Float) {
rect("met1", x0=0., y0=0., w=width, h=height);
}
Calling pad(100., 80.) gives you a cell value. Pass it to inst to place it. Both rect and inst are in the std::layout module; the use line brings rect into scope.
Functions
A function computes a value. Its last expression is the return value:
fn half(value: Float) -> Float {
value / 2.
}
A function can also emit geometry or constraints into the scope it's called from:
fn align_left(a: Rect, b: Rect) {
eq(a.x0, b.x0);
}
Arguments and return types
Argument types are written name: Type, and the return type follows ->. Some argument types can be inferred, but writing them out gives clearer call sites and error messages.
use std::layout::crect;
fn inset_bounds(rect_: Rect, amount: Float) -> Rect {
crect(
x0=rect_.x0 + amount,
y0=rect_.y0 + amount,
x1=rect_.x1 - amount,
y1=rect_.y1 - amount,
)
}
Bindings and order
let introduces an immutable binding:
let bounds = std::layout::bbox(child);
A let can also take a struct apart. The pattern names the struct and binds its fields: a bare name binds the field of that name, field: other binds it under another name, and field: _ drops it. The pattern must name every field unless it ends in .., and field patterns do not nest.
let Size { w, h: height } = size;
let ViaParams { layer, .. } = params;
At the top of a cell, each name a pattern binds is a field of the cell, like any other let.
Top-level declarations are resolved across the whole module, so a cell can call a function declared further down the file.
Public fields
The top-level let bindings of a cell are its fields. An instance of the cell can read a field only if the cell declares it with pub let. The other fields are private to the cell.
use std::layout::{inst, rect};
cell pad(width: Float, height: Float) {
pub let metal = rect("met1", x0=0., y0=0., w=width, h=height);
let margin = 10.;
}
cell top() {
let p = inst(pad(100., 80.), x=0., y=0.);
rect("met2", x0=p.metal.x0, y0=p.metal.y0, w=p.metal.w, h=20.);
}
Here p.metal is readable, but p.margin is an error because margin is private.
pubapplies only to aletat the top level of a cell body. Apub letin a function, loop, branch, or block is an error.- A
pub letwith a pattern, such aspub let Size { w, h } = size;, makes every name the pattern binds public. - If a name is bound more than once, the last binding is the field, and its
pubdecides whether the field is public.