-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Add docs for each comptime method (#5802)
# Description ## Problem\* Resolves <!-- Link to GitHub Issue --> ## Summary\* Adds docs for each comptime method that's been added. ## Additional Context ## Documentation\* Check one: - [ ] No documentation needed. - [x] Documentation included in this PR. - [ ] **[For Experimental Features]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --------- Co-authored-by: TomAFrench <tom@tomfren.ch> Co-authored-by: Maxim Vezenov <mvezenov@gmail.com>
- Loading branch information
1 parent
637febf
commit de0f8ee
Showing
26 changed files
with
1,024 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
--- | ||
title: Expr | ||
--- | ||
|
||
`std::meta::expr` contains methods on the built-in `Expr` type for quoted, syntactically valid expressions. | ||
|
||
## Methods | ||
|
||
### as_array | ||
|
||
#include_code as_array noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is an array, this returns a slice of each element in the array. | ||
|
||
### as_integer | ||
|
||
#include_code as_integer noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this element is an integer literal, return the integer as a field | ||
as well as whether the integer is negative (true) or not (false). | ||
|
||
### as_binary_op | ||
|
||
#include_code as_binary_op noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a binary operator operation `<lhs> <op> <rhs>`, | ||
return the left-hand side, operator, and the right-hand side of the operation. | ||
|
||
### as_block | ||
|
||
#include_code as_block noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a block `{ stmt1; stmt2; ...; stmtN }`, return | ||
a slice containing each statement. | ||
|
||
### as_bool | ||
|
||
#include_code as_bool noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a boolean literal, return that literal. | ||
|
||
### as_comptime | ||
|
||
#include_code as_comptime noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a `comptime { stmt1; stmt2; ...; stmtN }` block, | ||
return each statement in the block. | ||
|
||
### as_function_call | ||
|
||
#include_code as_function_call noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a function call `foo(arg1, ..., argN)`, return | ||
the function and a slice of each argument. | ||
|
||
### as_if | ||
|
||
#include_code as_if noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is an `if condition { then_branch } else { else_branch }`, | ||
return the condition, then branch, and else branch. If there is no else branch, | ||
`None` is returned for that branch instead. | ||
|
||
### as_index | ||
|
||
#include_code as_index noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is an index into an array `array[index]`, return the | ||
array and the index. | ||
|
||
### as_member_access | ||
|
||
#include_code as_member_access noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a member access `foo.bar`, return the struct/tuple | ||
expression and the field. The field will be represented as a quoted value. | ||
|
||
### as_repeated_element_array | ||
|
||
#include_code as_repeated_element_array noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a repeated element array `[elem; length]`, return | ||
the repeated element and the length expressions. | ||
|
||
### as_repeated_element_slice | ||
|
||
#include_code as_repeated_element_slice noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a repeated element slice `[elem; length]`, return | ||
the repeated element and the length expressions. | ||
|
||
### as_slice | ||
|
||
#include_code as_slice noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a slice literal `&[elem1, ..., elemN]`, | ||
return each element of the slice. | ||
|
||
### as_tuple | ||
|
||
#include_code as_tuple noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a tuple `(field1, ..., fieldN)`, | ||
return each element of the tuple. | ||
|
||
### as_unary_op | ||
|
||
#include_code as_unary_op noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is a unary operation `<op> <rhs>`, | ||
return the unary operator as well as the right-hand side expression. | ||
|
||
### as_unsafe | ||
|
||
#include_code as_unsafe noir_stdlib/src/meta/expr.nr rust | ||
|
||
If this expression is an `unsafe { stmt1; ...; stmtN }` block, | ||
return each statement inside in a slice. | ||
|
||
### has_semicolon | ||
|
||
#include_code has_semicolon noir_stdlib/src/meta/expr.nr rust | ||
|
||
`true` if this expression is trailed by a semicolon. E.g. | ||
|
||
``` | ||
comptime { | ||
let expr1 = quote { 1 + 2 }.as_expr().unwrap(); | ||
let expr2 = quote { 1 + 2; }.as_expr().unwrap(); | ||
assert(expr1.as_binary_op().is_some()); | ||
assert(expr2.as_binary_op().is_some()); | ||
assert(!expr1.has_semicolon()); | ||
assert(expr2.has_semicolon()); | ||
} | ||
``` | ||
|
||
### is_break | ||
|
||
#include_code is_break noir_stdlib/src/meta/expr.nr rust | ||
|
||
`true` if this expression is `break`. | ||
|
||
### is_continue | ||
|
||
#include_code is_continue noir_stdlib/src/meta/expr.nr rust | ||
|
||
`true` if this expression is `continue`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
title: FunctionDefinition | ||
--- | ||
|
||
`std::meta::function_def` contains methods on the built-in `FunctionDefinition` type representing | ||
a function definition in the source program. | ||
|
||
## Methods | ||
|
||
### name | ||
|
||
#include_code name noir_stdlib/src/meta/function_def.nr rust | ||
|
||
Returns the name of the function. | ||
|
||
### parameters | ||
|
||
#include_code parameters noir_stdlib/src/meta/function_def.nr rust | ||
|
||
Returns each parameter of the function as a tuple of (parameter pattern, parameter type). | ||
|
||
### return_type | ||
|
||
#include_code return_type noir_stdlib/src/meta/function_def.nr rust | ||
|
||
The return type of the function. | ||
|
||
### set_body | ||
|
||
#include_code set_body noir_stdlib/src/meta/function_def.nr rust | ||
|
||
Mutate the function body to a new expression. This is only valid | ||
on functions in the current crate which have not yet been resolved. | ||
This means any functions called at compile-time are invalid targets for this method. | ||
|
||
Requires the new body to be a valid expression. | ||
|
||
### set_parameters | ||
|
||
#include_code set_parameters noir_stdlib/src/meta/function_def.nr rust | ||
|
||
Mutates the function's parameters to a new set of parameters. This is only valid | ||
on functions in the current crate which have not yet been resolved. | ||
This means any functions called at compile-time are invalid targets for this method. | ||
|
||
Expects a slice of (parameter pattern, parameter type) for each parameter. Requires | ||
each parameter pattern to be a syntactically valid parameter. | ||
|
||
### set_return_type | ||
|
||
#include_code set_return_type noir_stdlib/src/meta/function_def.nr rust | ||
|
||
Mutates the function's return type to a new type. This is only valid | ||
on functions in the current crate which have not yet been resolved. | ||
This means any functions called at compile-time are invalid targets for this method. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
--- | ||
title: Metaprogramming | ||
description: Noir's Metaprogramming API | ||
keywords: [metaprogramming, comptime, macros, macro, quote, unquote] | ||
--- | ||
|
||
`std::meta` is the entry point for Noir's metaprogramming API. This consists of `comptime` functions | ||
and types used for inspecting and modifying Noir programs. | ||
|
||
## Functions | ||
|
||
### type_of | ||
|
||
#include_code type_of noir_stdlib/src/meta/mod.nr rust | ||
|
||
Returns the type of a variable at compile-time. | ||
|
||
Example: | ||
```rust | ||
comptime { | ||
let x: i32 = 1; | ||
let x_type: Type = std::meta::type_of(x); | ||
|
||
assert_eq(x_type, quote { i32 }.as_type()); | ||
} | ||
``` | ||
|
||
### unquote | ||
|
||
#include_code unquote noir_stdlib/src/meta/mod.nr rust | ||
|
||
Unquotes the passed-in token stream where this function was called. | ||
|
||
Example: | ||
```rust | ||
comptime { | ||
let code = quote { 1 + 2 }; | ||
|
||
// let x = 1 + 2; | ||
let x = unquote!(code); | ||
} | ||
``` | ||
|
||
### derive | ||
|
||
#include_code derive noir_stdlib/src/meta/mod.nr rust | ||
|
||
Attribute placed on struct definitions. | ||
|
||
Creates a trait impl for each trait passed in as an argument. | ||
To do this, the trait must have a derive handler registered | ||
with `derive_via` beforehand. The traits in the stdlib that | ||
can be derived this way are `Eq`, `Ord`, `Default`, and `Hash`. | ||
|
||
Example: | ||
```rust | ||
#[derive(Eq, Default)] | ||
struct Foo<T> { | ||
x: i32, | ||
y: T, | ||
} | ||
|
||
fn main() { | ||
let foo1 = Foo::default(); | ||
let foo2 = Foo { x: 0, y: &[0] }; | ||
assert_eq(foo1, foo2); | ||
} | ||
``` | ||
|
||
### derive_via | ||
|
||
#include_code derive_via_signature noir_stdlib/src/meta/mod.nr rust | ||
|
||
Attribute placed on trait definitions. | ||
|
||
Registers a function to create impls for the given trait | ||
when the trait is used in a `derive` call. Users may use | ||
this to register their own functions to enable their traits | ||
to be derived by `derive`. | ||
|
||
Because this function requires a function as an argument which | ||
should produce a trait impl for any given struct, users may find | ||
it helpful to use a function like `std::meta::make_trait_impl` to | ||
help creating these impls. | ||
|
||
Example: | ||
```rust | ||
#[derive_via(derive_do_nothing)] | ||
trait DoNothing { | ||
fn do_nothing(self); | ||
} | ||
|
||
comptime fn derive_do_nothing(s: StructDefinition) -> Quoted { | ||
let typ = s.as_type(); | ||
quote { | ||
impl DoNothing for $typ { | ||
fn do_nothing(self) { | ||
println("Nothing"); | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
As another example, `derive_eq` in the stdlib is used to derive the `Eq` | ||
trait for any struct. It makes use of `make_trait_impl` to do this: | ||
|
||
#include_code derive_eq noir_stdlib/src/cmp.nr rust | ||
|
||
### make_trait_impl | ||
|
||
#include_code make_trait_impl noir_stdlib/src/meta/mod.nr rust | ||
|
||
A helper function to more easily create trait impls while deriving traits. | ||
|
||
Note that this function only works for traits which: | ||
1. Have only one method | ||
2. Have no generics on the trait itself. | ||
- E.g. Using this on a trait such as `trait Foo<T> { ... }` will result in the | ||
generated impl incorrectly missing the `T` generic. | ||
|
||
If your trait fits these criteria then `make_trait_impl` is likely the easiest | ||
way to write your derive handler. The arguments are as follows: | ||
|
||
- `s`: The struct to make the impl for | ||
- `trait_name`: The name of the trait to derive. E.g. `quote { Eq }`. | ||
- `function_signature`: The signature of the trait method to derive. E.g. `fn eq(self, other: Self) -> bool`. | ||
- `for_each_field`: An operation to be performed on each field. E.g. `|name| quote { (self.$name == other.$name) }`. | ||
- `join_fields_with`: A separator to join each result of `for_each_field` with. | ||
E.g. `quote { & }`. You can also use an empty `quote {}` for no separator. | ||
- `body`: The result of the field operations are passed into this function for any final processing. | ||
This is the place to insert any setup/teardown code the trait requires. If the trait doesn't require | ||
any such code, you can return the body as-is: `|body| body`. | ||
|
||
Example deriving `Hash`: | ||
|
||
#include_code derive_hash noir_stdlib/src/hash/mod.nr rust | ||
|
||
Example deriving `Ord`: | ||
|
||
#include_code derive_ord noir_stdlib/src/cmp.nr rust |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
--- | ||
title: Module | ||
--- | ||
|
||
`std::meta::module` contains methods on the built-in `Module` type which represents a module in the source program. | ||
Note that this type represents a module generally, it isn't limited to only `mod my_submodule { ... }` | ||
declarations in the source program. | ||
|
||
## Methods | ||
|
||
### name | ||
|
||
#include_code name noir_stdlib/src/meta/module.nr rust | ||
|
||
Returns the name of the module. | ||
|
||
### functions | ||
|
||
#include_code functions noir_stdlib/src/meta/module.nr rust | ||
|
||
Returns each function in the module. | ||
|
||
### is_contract | ||
|
||
#include_code is_contract noir_stdlib/src/meta/module.nr rust | ||
|
||
`true` if this module is a contract module (was declared via `contract foo { ... }`). |
Oops, something went wrong.