Skip to content
Merged
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
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,27 @@ arc run --cell 'top(pitch * 4., -width / 2.)'
arc run --cell 'array(cons(250., cons(350., [])), Mode::Fast)'
```

Parameters declared with a default value are keyword parameters. They are
passed by name, may be omitted, and must follow the positional parameters. A
default is an ordinary expression evaluated at each call; it may refer to the
parameters declared before it and to module-level items, and its type must match
the declared type exactly:

```rust
cell via(layer: String, w: Float, h: Float = w, n: Int = 1) {
// ...
}

cell top() {
let square = inst(via("met1", 100.));
let stack = inst(via("met1", 100., h=300., n=3));
}
```

Positional parameters cannot be passed by name, and keyword parameters cannot be
passed positionally. Keyword arguments also work in cell invocations:
`arc run --cell 'via("met1", 100., n=3)'`.

GDS imports are zero-argument cells. A module-qualified entry such as
`"macros::sram"` can be referenced as `lib::macros::sram()` or imported with
`use lib::macros::sram;`. Paths in the manifest are relative to `Argon.toml`,
Expand Down
1 change: 1 addition & 0 deletions crates/compiler/src/ast/annotated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ impl<S, T: AstMetadata> AstTransformer for AstAnnotationPass<S, T> {
input: &super::ArgDecl<Self::InputS, Self::InputMetadata>,
_name: &super::Ident<Self::OutputS, Self::OutputMetadata>,
_ty: &super::TySpec<Self::OutputS, Self::OutputMetadata>,
_default: &Option<super::Expr<Self::OutputS, Self::OutputMetadata>>,
) -> <Self::OutputMetadata as AstMetadata>::ArgDecl {
input.metadata.clone()
}
Expand Down
18 changes: 16 additions & 2 deletions crates/compiler/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,12 @@ pub struct KwArgValue<S, T: AstMetadata> {
pub metadata: T::KwArgValue,
}

/// A parameter of a cell or function; `default` makes it a keyword parameter.
#[derive_where(Debug, Clone, Serialize, Deserialize; S)]
pub struct ArgDecl<S, T: AstMetadata> {
pub name: Ident<S, T>,
pub ty: TySpec<S, T>,
pub default: Option<Expr<S, T>>,
pub metadata: T::ArgDecl,
}

Expand Down Expand Up @@ -580,6 +582,7 @@ pub trait AstTransformer {
input: &ArgDecl<Self::InputS, Self::InputMetadata>,
name: &Ident<Self::OutputS, Self::OutputMetadata>,
ty: &TySpec<Self::OutputS, Self::OutputMetadata>,
default: &Option<Expr<Self::OutputS, Self::OutputMetadata>>,
) -> <Self::OutputMetadata as AstMetadata>::ArgDecl;
fn dispatch_scope(
&mut self,
Expand Down Expand Up @@ -972,8 +975,19 @@ pub trait AstTransformer {
) -> ArgDecl<Self::OutputS, Self::OutputMetadata> {
let name = self.transform_ident(&input.name);
let ty = self.transform_ty_spec(&input.ty);
let metadata = self.dispatch_arg_decl(input, &name, &ty);
ArgDecl { name, ty, metadata }
// The default is visited before the parameter is dispatched, so it can
// see earlier parameters but not this one.
let default = input
.default
.as_ref()
.map(|default| self.transform_expr(default));
let metadata = self.dispatch_arg_decl(input, &name, &ty, &default);
ArgDecl {
name,
ty,
default,
metadata,
}
}

fn transform_scope(
Expand Down
14 changes: 14 additions & 0 deletions crates/compiler/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,20 @@ mod tests {
assert_eq!(rect.x1.0, 20.);
}

#[test]
fn execution_accepts_keyword_cell_arguments() {
let source = temp_source(
"kwargs",
"cell top(w: Float = 100., h: Float = w) {\n\
let r = rect(\"met1\", x0=0., y0=0., x1=w, y1=h);\n\
}\n",
);
let rect = compiled_rect("kwargs-default", source.clone(), "top()");
assert_eq!((rect.x1.0, rect.y1.0), (100., 100.));
let rect = compiled_rect("kwargs-explicit", source, "top(w=300.)");
assert_eq!((rect.x1.0, rect.y1.0), (300., 300.));
}

#[test]
fn out_of_range_cell_argument_is_reported_cleanly() {
let source = temp_source("out-of-range-arg", "cell top(n: Int) {}\n");
Expand Down
Loading
Loading