Skip to content

Commit

Permalink
ergotree-proc-macro first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kettlebell committed Oct 2, 2022
1 parent c838886 commit 40c9c87
Show file tree
Hide file tree
Showing 16 changed files with 387 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"ergoscript-compiler",
"ergotree-ir",
"ergotree-interpreter",
"ergotree-macro",
"ergo-lib",
"ergo-p2p",
"ergo-chain-generation",
Expand Down
1 change: 1 addition & 0 deletions ergotree-interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ ergotree-ir = { version = "^0.19.0", path = "../ergotree-ir", features = ["arbit
ergoscript-compiler = { version = "^0.15.0", path = "../ergoscript-compiler" }
proptest = "1.0.0"
sigma-test-util = { version = "^0.3.0", path = "../sigma-test-util" }
ergotree-macro = { version = "0.19", path = "../ergotree-macro"}

4 changes: 4 additions & 0 deletions ergotree-ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ strum_macros = "0.21"
indexmap = "1.3.2"
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", features = ["arbitrary_precision"], optional = true }
syn = { version = "1", features = ["parsing"], optional = true }
quote = { version = "1", optional = true }
proc-macro2 = { version = "1", optional = true }

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

[dev-dependencies]
sigma-test-util = { version = "^0.3.0", path = "../sigma-test-util" }
Expand Down
2 changes: 1 addition & 1 deletion ergotree-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::expect_used)]
#![deny(clippy::todo)]
//#![deny(clippy::todo)]
#![deny(clippy::unimplemented)]
#![deny(clippy::panic)]

Expand Down
22 changes: 22 additions & 0 deletions ergotree-ir/src/mir/bool_to_sigma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ impl OneArgOpTryBuild for BoolToSigmaProp {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for BoolToSigmaProp {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let content;
let _paren = syn::parenthesized!(content in input);
let input = content.parse()?;
Ok(Self {
input: Box::new(input),
})
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for BoolToSigmaProp {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let input = &*self.input;
tokens.extend(quote::quote! {
ergotree_ir::mir::bool_to_sigma::BoolToSigmaProp { input: Box::new(#input) }
})
}
}

/// Arbitrary impl
#[cfg(feature = "arbitrary")]
mod arbitrary {
Expand Down
28 changes: 28 additions & 0 deletions ergotree-ir/src/mir/coll_append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,34 @@ impl SigmaSerializable for Append {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for Append {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let name: syn::Ident = input.parse()?;
if name == "Append" {
let content;
let _paren = syn::parenthesized!(content in input);
let input = Box::new(content.parse()?);
let col_2 = Box::new(content.parse()?);

Ok(Append { input, col_2 })
} else {
Err(syn::Error::new_spanned(name, "Expected `Append`"))
}
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for Append {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let input = &*self.input;
let col_2 = &*self.col_2;
tokens.extend(quote::quote! {
ergotree_ir::mir::coll_append::Append { input: Box::new(#input), col_2: Box::new(#col_2) }
})
}
}

#[cfg(test)]
#[cfg(feature = "arbitrary")]
#[allow(clippy::panic)]
Expand Down
102 changes: 102 additions & 0 deletions ergotree-ir/src/mir/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,108 @@ impl<T: TryFrom<Expr>> TryExtractFrom<Expr> for T {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for Expr {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let name: syn::Ident = input.parse()?;
match name.to_string().as_str() {
"FuncValue" => {
let content;
let _paren = syn::parenthesized!(content in input);

Ok(Expr::FuncValue(content.parse()?))
}
"BoolToSigmaProp" => Ok(Expr::BoolToSigmaProp(input.parse()?)),
"ValUse" => Ok(Expr::ValUse(input.parse()?)),
_ => Err(syn::Error::new_spanned(name, "Unknown `Expr` variant name")),
}
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for Expr {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
use quote::quote;
tokens.extend(match self {
Expr::Append(a) => {
quote! { ergotree_ir::mir::expr::Expr::Append { #a } }
}

Expr::Const(_) => todo!(),
Expr::ConstPlaceholder(_) => todo!(),
Expr::SubstConstants(_) => todo!(),
Expr::ByteArrayToLong(_) => todo!(),
Expr::ByteArrayToBigInt(_) => todo!(),
Expr::LongToByteArray(_) => todo!(),
Expr::Collection(_) => todo!(),
Expr::Tuple(_) => todo!(),
Expr::CalcBlake2b256(_) => todo!(),
Expr::CalcSha256(_) => todo!(),
Expr::Context => todo!(),
Expr::Global => todo!(),
Expr::GlobalVars(_) => todo!(),
Expr::FuncValue(f) => {
quote! { ergotree_ir::mir::expr::Expr::FuncValue(#f) }
}
Expr::Apply(_) => todo!(),
Expr::MethodCall(_) => todo!(),
Expr::ProperyCall(_) => todo!(),
Expr::BlockValue(_) => todo!(),
Expr::ValDef(_) => todo!(),
Expr::ValUse(v) => {
quote! { ergotree_ir::mir::expr::Expr::ValUse(#v) }
}
Expr::If(_) => todo!(),
Expr::BinOp(_) => todo!(),
Expr::And(_) => todo!(),
Expr::Or(_) => todo!(),
Expr::Xor(_) => todo!(),
Expr::Atleast(_) => todo!(),
Expr::LogicalNot(_) => todo!(),
Expr::Negation(_) => todo!(),
Expr::BitInversion(_) => todo!(),
Expr::OptionGet(_) => todo!(),
Expr::OptionIsDefined(_) => todo!(),
Expr::OptionGetOrElse(_) => todo!(),
Expr::ExtractAmount(_) => todo!(),
Expr::ExtractRegisterAs(_) => todo!(),
Expr::ExtractBytes(_) => todo!(),
Expr::ExtractBytesWithNoRef(_) => todo!(),
Expr::ExtractScriptBytes(_) => todo!(),
Expr::ExtractCreationInfo(_) => todo!(),
Expr::ExtractId(_) => todo!(),
Expr::ByIndex(_) => todo!(),
Expr::SizeOf(_) => todo!(),
Expr::Slice(_) => todo!(),
Expr::Fold(_) => todo!(),
Expr::Map(_) => todo!(),
Expr::Filter(_) => todo!(),
Expr::Exists(_) => todo!(),
Expr::ForAll(_) => todo!(),
Expr::SelectField(_) => todo!(),
Expr::BoolToSigmaProp(b) => {
quote! { ergotree_ir::mir::expr::Expr::BoolToSigmaProp(#b) }
}
Expr::Upcast(_) => todo!(),
Expr::Downcast(_) => todo!(),
Expr::CreateProveDlog(_) => todo!(),
Expr::CreateProveDhTuple(_) => todo!(),
Expr::SigmaPropBytes(_) => todo!(),
Expr::DecodePoint(_) => todo!(),
Expr::SigmaAnd(_) => todo!(),
Expr::SigmaOr(_) => todo!(),
Expr::GetVar(_) => todo!(),
Expr::DeserializeRegister(_) => todo!(),
Expr::DeserializeContext(_) => todo!(),
Expr::MultiplyGroup(_) => todo!(),
Expr::Exponentiate(_) => todo!(),
Expr::XorOf(_) => todo!(),
Expr::TreeLookup(_) => todo!(),
Expr::CreateAvlTree(_) => todo!(),
});
}
}

#[cfg(feature = "arbitrary")]
#[allow(clippy::unwrap_used)]
#[allow(clippy::panic)]
Expand Down
64 changes: 64 additions & 0 deletions ergotree-ir/src/mir/func_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@ pub struct FuncArg {
pub tpe: SType,
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for FuncArg {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let content;
let _paren = syn::parenthesized!(content in input);
let id: syn::LitInt = content.parse()?;
let value = id.base10_parse::<u32>()?;
let idx = ValId(value);
let _comma: syn::Token![,] = content.parse()?;
let tpe = content.parse()?;
Ok(FuncArg { idx, tpe })
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for FuncArg {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let idx = &self.idx;
let tpe = &self.tpe;
tokens.extend(quote::quote! {
ergotree_ir::mir::func_value::FuncArg {
idx: #idx,
tpe: #tpe,
}
})
}
}

impl SigmaSerializable for FuncArg {
fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
self.idx.sigma_serialize(w)?;
Expand Down Expand Up @@ -97,6 +125,42 @@ impl SigmaSerializable for FuncValue {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for FuncValue {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let args = {
let name: syn::Ident = input.parse()?;
if name == "Vector" {
let content;
let _paren = syn::parenthesized!(content in input);
let punctuated: syn::punctuated::Punctuated<FuncArg, syn::Token![,]> =
content.parse_terminated(FuncArg::parse)?;
punctuated.into_iter().collect()
} else {
return Err(syn::Error::new_spanned(name, "Expected `Vector`"));
}
};
let _comma: syn::Token![,] = input.parse()?;
let body: Expr = input.parse()?;
Ok(FuncValue::new(args, body))
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for FuncValue {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let args = &self.args;
let body = &*self.body;
//let tpe = &self.tpe;
tokens.extend(
quote::quote! { ergotree_ir::mir::func_value::FuncValue::new(
vec![#( #args),*],
#body,
)},
)
}
}

#[cfg(test)]
#[cfg(feature = "arbitrary")]
#[allow(clippy::panic)]
Expand Down
17 changes: 17 additions & 0 deletions ergotree-ir/src/mir/val_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ impl ValId {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for ValId {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let id: syn::LitInt = input.parse()?;
let value = id.base10_parse::<u32>()?;
Ok(ValId(value))
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for ValId {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let val_id = self.0;
tokens.extend(quote::quote! { ergotree_ir::mir::val_def::ValId(#val_id) })
}
}

/** IR node for let-bound expressions `let x = rhs` which is ValDef.
* These nodes are used to represent ErgoTrees after common sub-expression elimination.
* This representation is more compact in serialized form.
Expand Down
26 changes: 26 additions & 0 deletions ergotree-ir/src/mir/val_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ impl SigmaSerializable for ValUse {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for ValUse {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let content;
let _paren = syn::parenthesized!(content in input);
let id: syn::LitInt = content.parse()?;
let value = id.base10_parse::<u32>()?;
let val_id = ValId(value);
let _comma: syn::Token![,] = content.parse()?;
let tpe = content.parse()?;

Ok(ValUse { val_id, tpe })
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for ValUse {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let val_id = &self.val_id;
let tpe = &self.tpe;
tokens.extend(
quote::quote! { ergotree_ir::mir::val_use::ValUse { val_id: #val_id, tpe: #tpe }},
)
}
}

#[cfg(test)]
#[cfg(feature = "arbitrary")]
#[allow(clippy::panic)]
Expand Down
44 changes: 44 additions & 0 deletions ergotree-ir/src/types/stype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,50 @@ impl From<SFunc> for SType {
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl syn::parse::Parse for SType {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let name: syn::Ident = input.parse()?;
match name.to_string().as_str() {
"SBoolean" => Ok(SType::SBoolean),
_ => Err(syn::Error::new_spanned(
name,
"Unknown `SType` variant name",
)),
}
}
}

#[cfg(feature = "ergotree-proc-macro")]
impl quote::ToTokens for SType {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
use quote::quote;
tokens.extend(match self {
SType::STypeVar(_) => todo!(),
SType::SAny => todo!(),
SType::SUnit => todo!(),
SType::SBoolean => quote! { ergotree_ir::types::stype::SType::SBoolean },
SType::SByte => todo!(),
SType::SShort => todo!(),
SType::SInt => todo!(),
SType::SLong => todo!(),
SType::SBigInt => todo!(),
SType::SGroupElement => todo!(),
SType::SSigmaProp => todo!(),
SType::SBox => todo!(),
SType::SAvlTree => todo!(),
SType::SOption(_) => todo!(),
SType::SColl(_) => todo!(),
SType::STuple(_) => todo!(),
SType::SFunc(_) => todo!(),
SType::SContext => todo!(),
SType::SHeader => todo!(),
SType::SPreHeader => todo!(),
SType::SGlobal => todo!(),
})
}
}

/// Conversion to SType
pub trait LiftIntoSType {
/// get SType
Expand Down
Loading

0 comments on commit 40c9c87

Please sign in to comment.