Skip to content

Commit

Permalink
chore: Add docs for each comptime method (#5802)
Browse files Browse the repository at this point in the history
# 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 <[email protected]>
Co-authored-by: Maxim Vezenov <[email protected]>
  • Loading branch information
3 people authored Aug 23, 2024
1 parent 637febf commit de0f8ee
Show file tree
Hide file tree
Showing 26 changed files with 1,024 additions and 24 deletions.
4 changes: 2 additions & 2 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
"keccakf",
"krate",
"libc",
"Linea",
"losslessly",
"lvalue",
"Maddiaa",
Expand Down Expand Up @@ -220,8 +221,7 @@
"wasi",
"wasmer",
"Weierstraß",
"zshell",
"Linea"
"zshell"
],
"ignorePaths": [
"./**/node_modules/**",
Expand Down
149 changes: 149 additions & 0 deletions docs/docs/noir/standard_library/meta/expr.md
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`.
55 changes: 55 additions & 0 deletions docs/docs/noir/standard_library/meta/function_def.md
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.
141 changes: 141 additions & 0 deletions docs/docs/noir/standard_library/meta/index.md
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
27 changes: 27 additions & 0 deletions docs/docs/noir/standard_library/meta/module.md
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 { ... }`).
Loading

0 comments on commit de0f8ee

Please sign in to comment.