Skip to main content

arcis_interpreter_proc_macros/
lib.rs

1use arcis_interpreter::{
2    arcis_type_macro,
3    assert_current_module_macro,
4    encrypted_mod_macro,
5    error_macro,
6    library_macro,
7    module_macro,
8};
9use proc_macro::TokenStream;
10
11/// Tells our arcis compiler to create encrypted instructions that mimic the rust module you wrote.
12/// Use `#[instruction]` to mark the functions that will be the entry points.
13#[proc_macro_attribute]
14pub fn encrypted(_attr: TokenStream, item: TokenStream) -> TokenStream {
15    module_macro(item.into()).into()
16}
17
18/// Validates an arcis library, trying to find errors.
19/// Allows to build a library that can be used in `#[encrypted]` instructions.
20///
21/// Will transform
22/// ```
23/// mod arcis_library {
24///     /* content */
25/// }
26/// ```
27/// into
28/// ```
29/// /* content */
30/// ```
31/// if it does not detect any errors.
32#[proc_macro_attribute]
33pub fn encrypted_library(_attr: TokenStream, item: TokenStream) -> TokenStream {
34    library_macro(item.into()).into()
35}
36
37/// Derives `ArcisType`, a trait that helps to use the type in automated tests.
38#[doc(hidden)]
39#[proc_macro_derive(ArcisType)]
40pub fn derive_arcis_type(input: TokenStream) -> TokenStream {
41    arcis_type_macro(input.into()).into()
42}
43
44/// An `#[instruction]`. Should be inside an `#[encrypted]` module.
45#[proc_macro_attribute]
46pub fn instruction(_attr: TokenStream, item: TokenStream) -> TokenStream {
47    error_macro(
48        item.into(),
49        "`#[instruction]` can only be used inside `#[encrypted]`.",
50    )
51    .into()
52}
53#[doc(hidden)]
54#[proc_macro_attribute]
55pub fn arcis_circuit(_attr: TokenStream, item: TokenStream) -> TokenStream {
56    error_macro(
57        item.into(),
58        "`#[arcis_circuit = \"...\"]` can only be used inside `#[encrypted]`.",
59    )
60    .into()
61}
62
63/// Use another file as a module in an `#[encrypted]` module.
64///
65/// Use `encrypted_mod!("path/to/my_module_name.rs")` or
66/// `encrypted_mod!("path/to/my_module.rs", my_module_name)`
67/// to use another file as a module. The path is relative to the current file.
68///
69/// The other file needs to look like this:
70///
71/// path/to/my_module.rs:
72/// ```
73/// use arcis::*;
74///
75/// #[encrypted_library]
76/// mod arcis_library {
77///     // Put your content here.
78///
79///     // Accessible through `my_module_name::MY_CONST`.
80///     pub const MY_CONST: u16 = 67;
81/// }
82/// ```
83/// And then it can be used it like this:
84///
85/// lib.rs:
86/// ```
87/// use arcis::*;
88///
89/// #[encrypted]
90/// mod circuits {
91///     use arcis::*;
92///
93///     // Allowing to use the contents of my_module.rs as `my_module_name::...`.
94///     encrypted_mod!("path/to/my_module.rs", my_module_name);
95///
96///     pub struct InputValues {
97///         v1: u8,
98///         v2: u8,
99///     }
100///
101///     #[instruction]
102///     pub fn add_together(input_ctxt: Enc<Shared, InputValues>) -> Enc<Shared, u16> {
103///         let input = input_ctxt.to_arcis();
104///         let mut sum = input.v1 as u16 + input.v2 as u16;
105///
106///         // Using the constant declared in the other file.
107///         sum += my_module_name::MY_CONST;
108///
109///         input_ctxt.owner.from_arcis(sum)
110///     }
111/// }
112/// ```
113#[proc_macro]
114pub fn encrypted_mod(input: TokenStream) -> TokenStream {
115    encrypted_mod_macro(input.into()).into()
116}
117
118/// Allows to use `crate::` in an #[encrypted] module.
119/// Use it like this: `assert_current_module!(crate::path::to::encrypted::module);`
120///
121/// Example lib.rs:
122/// ```
123/// use arcis::*;
124///
125/// #[encrypted]
126/// mod circuits {
127///     use arcis::*;
128///
129///     assert_current_module!(crate::circuits);
130///     // now I can use crate::circuits
131///
132///     const MY_CONST: usize = 0;
133///
134///     #[instruction]
135///     fn return_my_const() -> usize {
136///         crate::circuits::MY_CONST
137///     }
138/// }
139/// ```
140#[proc_macro]
141pub fn assert_current_module(input: TokenStream) -> TokenStream {
142    assert_current_module_macro(input.into()).into()
143}