Skip to content

Commit 05ee834

Browse files
committed
ergotree-proc-macro first commit
1 parent 41150b6 commit 05ee834

File tree

16 files changed

+387
-1
lines changed

16 files changed

+387
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ members = [
66
"ergoscript-compiler",
77
"ergotree-ir",
88
"ergotree-interpreter",
9+
"ergotree-macro",
910
"ergo-lib",
1011
"ergo-p2p",
1112
"ergo-chain-generation",

ergotree-interpreter/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,5 @@ ergotree-ir = { version = "^0.20.0", path = "../ergotree-ir", features = ["arbit
6262
ergoscript-compiler = { version = "^0.16.0", path = "../ergoscript-compiler" }
6363
proptest = "1.0.0"
6464
sigma-test-util = { version = "^0.3.0", path = "../sigma-test-util" }
65+
ergotree-macro = { version = "0.19", path = "../ergotree-macro"}
6566

ergotree-ir/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ strum_macros = "0.21"
3939
indexmap = "1.3.2"
4040
serde = { version = "1.0", features = ["derive"], optional = true }
4141
serde_json = { version = "1.0", features = ["arbitrary_precision"], optional = true }
42+
syn = { version = "1", features = ["parsing"], optional = true }
43+
quote = { version = "1", optional = true }
44+
proc-macro2 = { version = "1", optional = true }
4245

4346
[dependencies.proptest]
4447
# wasm support, via https://altsysrq.github.io/proptest-book/proptest/wasm.html
@@ -59,6 +62,7 @@ optional = true
5962
default = ["json"]
6063
arbitrary = ["proptest", "proptest-derive", "ergo-chain-types/arbitrary"]
6164
json = ["serde", "serde_json", "serde_with", "bounded-vec/serde"]
65+
ergotree-proc-macro = ["syn", "quote", "proc-macro2"]
6266

6367
[dev-dependencies]
6468
sigma-test-util = { version = "^0.3.0", path = "../sigma-test-util" }

ergotree-ir/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#![deny(rustdoc::broken_intra_doc_links)]
1515
#![deny(clippy::unwrap_used)]
1616
#![deny(clippy::expect_used)]
17-
#![deny(clippy::todo)]
17+
//#![deny(clippy::todo)]
1818
#![deny(clippy::unimplemented)]
1919
#![deny(clippy::panic)]
2020

ergotree-ir/src/mir/bool_to_sigma.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,28 @@ impl OneArgOpTryBuild for BoolToSigmaProp {
4444
}
4545
}
4646

47+
#[cfg(feature = "ergotree-proc-macro")]
48+
impl syn::parse::Parse for BoolToSigmaProp {
49+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
50+
let content;
51+
let _paren = syn::parenthesized!(content in input);
52+
let input = content.parse()?;
53+
Ok(Self {
54+
input: Box::new(input),
55+
})
56+
}
57+
}
58+
59+
#[cfg(feature = "ergotree-proc-macro")]
60+
impl quote::ToTokens for BoolToSigmaProp {
61+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
62+
let input = &*self.input;
63+
tokens.extend(quote::quote! {
64+
ergotree_ir::mir::bool_to_sigma::BoolToSigmaProp { input: Box::new(#input) }
65+
})
66+
}
67+
}
68+
4769
/// Arbitrary impl
4870
#[cfg(feature = "arbitrary")]
4971
mod arbitrary {

ergotree-ir/src/mir/coll_append.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,34 @@ impl SigmaSerializable for Append {
7575
}
7676
}
7777

78+
#[cfg(feature = "ergotree-proc-macro")]
79+
impl syn::parse::Parse for Append {
80+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
81+
let name: syn::Ident = input.parse()?;
82+
if name == "Append" {
83+
let content;
84+
let _paren = syn::parenthesized!(content in input);
85+
let input = Box::new(content.parse()?);
86+
let col_2 = Box::new(content.parse()?);
87+
88+
Ok(Append { input, col_2 })
89+
} else {
90+
Err(syn::Error::new_spanned(name, "Expected `Append`"))
91+
}
92+
}
93+
}
94+
95+
#[cfg(feature = "ergotree-proc-macro")]
96+
impl quote::ToTokens for Append {
97+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
98+
let input = &*self.input;
99+
let col_2 = &*self.col_2;
100+
tokens.extend(quote::quote! {
101+
ergotree_ir::mir::coll_append::Append { input: Box::new(#input), col_2: Box::new(#col_2) }
102+
})
103+
}
104+
}
105+
78106
#[cfg(test)]
79107
#[cfg(feature = "arbitrary")]
80108
#[allow(clippy::panic)]

ergotree-ir/src/mir/expr.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,108 @@ impl<T: TryFrom<Expr>> TryExtractFrom<Expr> for T {
370370
}
371371
}
372372

373+
#[cfg(feature = "ergotree-proc-macro")]
374+
impl syn::parse::Parse for Expr {
375+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
376+
let name: syn::Ident = input.parse()?;
377+
match name.to_string().as_str() {
378+
"FuncValue" => {
379+
let content;
380+
let _paren = syn::parenthesized!(content in input);
381+
382+
Ok(Expr::FuncValue(content.parse()?))
383+
}
384+
"BoolToSigmaProp" => Ok(Expr::BoolToSigmaProp(input.parse()?)),
385+
"ValUse" => Ok(Expr::ValUse(input.parse()?)),
386+
_ => Err(syn::Error::new_spanned(name, "Unknown `Expr` variant name")),
387+
}
388+
}
389+
}
390+
391+
#[cfg(feature = "ergotree-proc-macro")]
392+
impl quote::ToTokens for Expr {
393+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
394+
use quote::quote;
395+
tokens.extend(match self {
396+
Expr::Append(a) => {
397+
quote! { ergotree_ir::mir::expr::Expr::Append { #a } }
398+
}
399+
400+
Expr::Const(_) => todo!(),
401+
Expr::ConstPlaceholder(_) => todo!(),
402+
Expr::SubstConstants(_) => todo!(),
403+
Expr::ByteArrayToLong(_) => todo!(),
404+
Expr::ByteArrayToBigInt(_) => todo!(),
405+
Expr::LongToByteArray(_) => todo!(),
406+
Expr::Collection(_) => todo!(),
407+
Expr::Tuple(_) => todo!(),
408+
Expr::CalcBlake2b256(_) => todo!(),
409+
Expr::CalcSha256(_) => todo!(),
410+
Expr::Context => todo!(),
411+
Expr::Global => todo!(),
412+
Expr::GlobalVars(_) => todo!(),
413+
Expr::FuncValue(f) => {
414+
quote! { ergotree_ir::mir::expr::Expr::FuncValue(#f) }
415+
}
416+
Expr::Apply(_) => todo!(),
417+
Expr::MethodCall(_) => todo!(),
418+
Expr::ProperyCall(_) => todo!(),
419+
Expr::BlockValue(_) => todo!(),
420+
Expr::ValDef(_) => todo!(),
421+
Expr::ValUse(v) => {
422+
quote! { ergotree_ir::mir::expr::Expr::ValUse(#v) }
423+
}
424+
Expr::If(_) => todo!(),
425+
Expr::BinOp(_) => todo!(),
426+
Expr::And(_) => todo!(),
427+
Expr::Or(_) => todo!(),
428+
Expr::Xor(_) => todo!(),
429+
Expr::Atleast(_) => todo!(),
430+
Expr::LogicalNot(_) => todo!(),
431+
Expr::Negation(_) => todo!(),
432+
Expr::BitInversion(_) => todo!(),
433+
Expr::OptionGet(_) => todo!(),
434+
Expr::OptionIsDefined(_) => todo!(),
435+
Expr::OptionGetOrElse(_) => todo!(),
436+
Expr::ExtractAmount(_) => todo!(),
437+
Expr::ExtractRegisterAs(_) => todo!(),
438+
Expr::ExtractBytes(_) => todo!(),
439+
Expr::ExtractBytesWithNoRef(_) => todo!(),
440+
Expr::ExtractScriptBytes(_) => todo!(),
441+
Expr::ExtractCreationInfo(_) => todo!(),
442+
Expr::ExtractId(_) => todo!(),
443+
Expr::ByIndex(_) => todo!(),
444+
Expr::SizeOf(_) => todo!(),
445+
Expr::Slice(_) => todo!(),
446+
Expr::Fold(_) => todo!(),
447+
Expr::Map(_) => todo!(),
448+
Expr::Filter(_) => todo!(),
449+
Expr::Exists(_) => todo!(),
450+
Expr::ForAll(_) => todo!(),
451+
Expr::SelectField(_) => todo!(),
452+
Expr::BoolToSigmaProp(b) => {
453+
quote! { ergotree_ir::mir::expr::Expr::BoolToSigmaProp(#b) }
454+
}
455+
Expr::Upcast(_) => todo!(),
456+
Expr::Downcast(_) => todo!(),
457+
Expr::CreateProveDlog(_) => todo!(),
458+
Expr::CreateProveDhTuple(_) => todo!(),
459+
Expr::SigmaPropBytes(_) => todo!(),
460+
Expr::DecodePoint(_) => todo!(),
461+
Expr::SigmaAnd(_) => todo!(),
462+
Expr::SigmaOr(_) => todo!(),
463+
Expr::GetVar(_) => todo!(),
464+
Expr::DeserializeRegister(_) => todo!(),
465+
Expr::DeserializeContext(_) => todo!(),
466+
Expr::MultiplyGroup(_) => todo!(),
467+
Expr::Exponentiate(_) => todo!(),
468+
Expr::XorOf(_) => todo!(),
469+
Expr::TreeLookup(_) => todo!(),
470+
Expr::CreateAvlTree(_) => todo!(),
471+
});
472+
}
473+
}
474+
373475
#[cfg(feature = "arbitrary")]
374476
#[allow(clippy::unwrap_used)]
375477
#[allow(clippy::panic)]

ergotree-ir/src/mir/func_value.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,34 @@ pub struct FuncArg {
2424
pub tpe: SType,
2525
}
2626

27+
#[cfg(feature = "ergotree-proc-macro")]
28+
impl syn::parse::Parse for FuncArg {
29+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
30+
let content;
31+
let _paren = syn::parenthesized!(content in input);
32+
let id: syn::LitInt = content.parse()?;
33+
let value = id.base10_parse::<u32>()?;
34+
let idx = ValId(value);
35+
let _comma: syn::Token![,] = content.parse()?;
36+
let tpe = content.parse()?;
37+
Ok(FuncArg { idx, tpe })
38+
}
39+
}
40+
41+
#[cfg(feature = "ergotree-proc-macro")]
42+
impl quote::ToTokens for FuncArg {
43+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
44+
let idx = &self.idx;
45+
let tpe = &self.tpe;
46+
tokens.extend(quote::quote! {
47+
ergotree_ir::mir::func_value::FuncArg {
48+
idx: #idx,
49+
tpe: #tpe,
50+
}
51+
})
52+
}
53+
}
54+
2755
impl SigmaSerializable for FuncArg {
2856
fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
2957
self.idx.sigma_serialize(w)?;
@@ -97,6 +125,42 @@ impl SigmaSerializable for FuncValue {
97125
}
98126
}
99127

128+
#[cfg(feature = "ergotree-proc-macro")]
129+
impl syn::parse::Parse for FuncValue {
130+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
131+
let args = {
132+
let name: syn::Ident = input.parse()?;
133+
if name == "Vector" {
134+
let content;
135+
let _paren = syn::parenthesized!(content in input);
136+
let punctuated: syn::punctuated::Punctuated<FuncArg, syn::Token![,]> =
137+
content.parse_terminated(FuncArg::parse)?;
138+
punctuated.into_iter().collect()
139+
} else {
140+
return Err(syn::Error::new_spanned(name, "Expected `Vector`"));
141+
}
142+
};
143+
let _comma: syn::Token![,] = input.parse()?;
144+
let body: Expr = input.parse()?;
145+
Ok(FuncValue::new(args, body))
146+
}
147+
}
148+
149+
#[cfg(feature = "ergotree-proc-macro")]
150+
impl quote::ToTokens for FuncValue {
151+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
152+
let args = &self.args;
153+
let body = &*self.body;
154+
//let tpe = &self.tpe;
155+
tokens.extend(
156+
quote::quote! { ergotree_ir::mir::func_value::FuncValue::new(
157+
vec![#( #args),*],
158+
#body,
159+
)},
160+
)
161+
}
162+
}
163+
100164
#[cfg(test)]
101165
#[cfg(feature = "arbitrary")]
102166
#[allow(clippy::panic)]

ergotree-ir/src/mir/val_def.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ impl ValId {
3131
}
3232
}
3333

34+
#[cfg(feature = "ergotree-proc-macro")]
35+
impl syn::parse::Parse for ValId {
36+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
37+
let id: syn::LitInt = input.parse()?;
38+
let value = id.base10_parse::<u32>()?;
39+
Ok(ValId(value))
40+
}
41+
}
42+
43+
#[cfg(feature = "ergotree-proc-macro")]
44+
impl quote::ToTokens for ValId {
45+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
46+
let val_id = self.0;
47+
tokens.extend(quote::quote! { ergotree_ir::mir::val_def::ValId(#val_id) })
48+
}
49+
}
50+
3451
/** IR node for let-bound expressions `let x = rhs` which is ValDef.
3552
* These nodes are used to represent ErgoTrees after common sub-expression elimination.
3653
* This representation is more compact in serialized form.

ergotree-ir/src/mir/val_use.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,32 @@ impl SigmaSerializable for ValUse {
3838
}
3939
}
4040

41+
#[cfg(feature = "ergotree-proc-macro")]
42+
impl syn::parse::Parse for ValUse {
43+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
44+
let content;
45+
let _paren = syn::parenthesized!(content in input);
46+
let id: syn::LitInt = content.parse()?;
47+
let value = id.base10_parse::<u32>()?;
48+
let val_id = ValId(value);
49+
let _comma: syn::Token![,] = content.parse()?;
50+
let tpe = content.parse()?;
51+
52+
Ok(ValUse { val_id, tpe })
53+
}
54+
}
55+
56+
#[cfg(feature = "ergotree-proc-macro")]
57+
impl quote::ToTokens for ValUse {
58+
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
59+
let val_id = &self.val_id;
60+
let tpe = &self.tpe;
61+
tokens.extend(
62+
quote::quote! { ergotree_ir::mir::val_use::ValUse { val_id: #val_id, tpe: #tpe }},
63+
)
64+
}
65+
}
66+
4167
#[cfg(test)]
4268
#[cfg(feature = "arbitrary")]
4369
#[allow(clippy::panic)]

0 commit comments

Comments
 (0)