diff --git a/example/token/Makefile b/example/token/Makefile index bc06161..33efafc 100644 --- a/example/token/Makefile +++ b/example/token/Makefile @@ -9,8 +9,8 @@ deploy: build $(eval CONTRACT_ADDRESS := $(shell $(HMCLI) contract deploy --path=$(CONTRACT_CODE) --address=${ADDR1} --gas=1 --password=password --node=tcp://$(NODE_ADDR))) @echo "contract address is ${CONTRACT_ADDRESS}" -call: - $(HMCLI) contract call --address=${ADDR1} --contract=$(CONTRACT_ADDRESS) --gas=1 --func="app_main" --password=password --node=tcp://$(NODE_ADDR) +transfer: + $(HMCLI) contract call --address=${ADDR1} --contract=$(CONTRACT_ADDRESS) --gas=1 --func="transfer" --args ${ADDR2} --args 10 --argtypes=address,int64 --password=password --node=tcp://$(NODE_ADDR) build: cargo build --target=wasm32-unknown-unknown diff --git a/example/token/src/lib.rs b/example/token/src/lib.rs index 3c6a736..c7c5586 100644 --- a/example/token/src/lib.rs +++ b/example/token/src/lib.rs @@ -15,9 +15,7 @@ fn get_balance_from_addr(addr: &Address) -> Result { } #[contract] -pub fn transfer() -> R { - let to: Address = get_arg(0)?; - let amount: i64 = get_arg(1)?; +pub fn transfer(to: Address, amount: i64) -> R { let sender = get_sender()?; let from_balance = get_balance_from_addr(&sender)?; diff --git a/hmcdk/Cargo.lock b/hmcdk/Cargo.lock index 33905f5..9279996 100644 --- a/hmcdk/Cargo.lock +++ b/hmcdk/Cargo.lock @@ -62,8 +62,8 @@ dependencies = [ name = "hmcdk_codegen" version = "0.1.0" dependencies = [ - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -79,6 +79,14 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "proc-macro2" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quote" version = "0.6.13" @@ -87,6 +95,14 @@ dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.16" @@ -102,6 +118,16 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "syn" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "synstructure" version = "0.10.2" @@ -118,6 +144,11 @@ name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] "checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" @@ -127,8 +158,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/hmcdk/codegen/Cargo.toml b/hmcdk/codegen/Cargo.toml index 42d475a..7f452fb 100644 --- a/hmcdk/codegen/Cargo.toml +++ b/hmcdk/codegen/Cargo.toml @@ -5,8 +5,8 @@ authors = ["Jun Kimura "] edition = "2018" [dependencies] -syn = { version = "0.15.18", features = ["full", "extra-traits"] } -quote = "0.6.9" +syn = { version = "1.0", features = ["full", "extra-traits"] } +quote = "1.0" [lib] proc-macro = true diff --git a/hmcdk/codegen/src/lib.rs b/hmcdk/codegen/src/lib.rs index a6c5f85..b2f5679 100644 --- a/hmcdk/codegen/src/lib.rs +++ b/hmcdk/codegen/src/lib.rs @@ -2,21 +2,74 @@ extern crate proc_macro; use crate::proc_macro::TokenStream; use quote::quote; -use syn::{parse_macro_input, ItemFn}; +use syn::{parse_macro_input, parse_quote, ItemFn, FnArg, Type, Stmt, Pat, Ident}; +use std::ops::Deref; + +fn get_assignment_from_name_and_type(name: &Ident, ty: &Type, index: usize) -> Result { + match ty { + Type::Path(type_path) => { + let pair = type_path.path.segments.last().ok_or("internal error")?; + let ident = &pair.ident; + let a = parse_quote! { + let #name: #ident = get_arg(#index).unwrap(); + }; + Ok(a) + } + _ => Err("invalid arg type".to_string()) + } +} + +fn get_assignment_from_arg(arg: &FnArg, index: usize) -> Result<(&Ident, Stmt), String> { + match arg { + FnArg::Typed(pat_type) => { + match &pat_type.pat.deref() { + Pat::Ident(pat) => { + let pat = &pat.ident; + match get_assignment_from_name_and_type(pat, pat_type.ty.deref(), index) { + Ok(stmt) => Ok((pat, stmt)), + Err(err) => Err(err) + } + } + _ => Err("no parameter name".to_string()) + } + } + FnArg::Receiver(_receiver) => Err("receiver not supported".to_string()) + } +} #[proc_macro_attribute] pub fn contract(_attr: TokenStream, item: TokenStream) -> TokenStream { let mut ast = parse_macro_input!(item as ItemFn); - let org_name = &ast.ident; + let org_name = &ast.sig.ident; let export_name = format!("{}", org_name); let fn_name = syn::Ident::new(format!("__{}", org_name).as_str(), org_name.span()); + let decl = &ast.sig; + let inputs = &decl.inputs; + let mut c = 0; + let mut assignments = Vec::new(); + let mut arguments = Vec::new(); + for arg in inputs { + let a = get_assignment_from_arg(&arg, c); + c += 1; + match a { + Ok((ident, stmt)) => { + assignments.push(stmt); + arguments.push(ident); + } + Err(e) => { + eprintln!("{:?}", e); + } + } + } + let pre = quote! { #[cfg_attr(not(feature = "emulation"), export_name = #export_name)] pub fn #fn_name() -> i32 { use hmcdk::prelude::*; use hmcdk::api::{return_value, log}; - match #org_name() { + #(#assignments);* + match #org_name(#(#arguments),*) { Ok(Some(v)) => { match return_value(&v.to_bytes()) { 0 => 0,