Unverified Commit 783697bb authored by Robin Freyler's avatar Robin Freyler
Browse files

[lang] Add initial (unfinished) implementation of code gen

parent 5bc91193
use crate::{
ast,
hir,
};
use proc_macro2::{
Ident,
Span,
TokenStream,
};
use quote::{
quote,
ToTokens,
};
use syn::{
punctuated::Punctuated,
Token,
};
pub fn codegen(contract: &hir::Contract) -> proc_macro2::TokenStream {
let mut tokens = quote! {};
codegen_for_state(&mut tokens, contract);
codegen_for_messages(&mut tokens, contract);
tokens
}
fn codegen_for_state(tokens: &mut TokenStream, contract: &hir::Contract) {
let state_attrs_toks = {
let mut content = quote! {};
for attr in &contract.state.attrs {
attr.to_tokens(&mut content)
}
content
};
let struct_fields_toks = &contract.state.fields;
let name = &contract.name;
tokens.extend(quote! {
pdsl_model::state! {
#state_attrs_toks
struct #name
#struct_fields_toks
}
});
}
fn codegen_for_messages(tokens: &mut TokenStream, contract: &hir::Contract) {
let messages_content = {
let mut content = quote! {};
for (n, message) in contract.messages.iter().enumerate() {
for attr in &message.attrs {
attr.to_tokens(&mut content)
}
let msg_id =
syn::LitInt::new(n as u64, syn::IntSuffix::None, Span::call_site());
msg_id.to_tokens(&mut content);
<Token![=>]>::default().to_tokens(&mut content);
use crate::ident_ext::IdentExt as _;
use heck::CamelCase as _;
let camel_case_ident = Ident::new(
&message.sig.ident.to_owned_string().to_camel_case(),
message.sig.ident.span(),
);
camel_case_ident.to_tokens(&mut content);
let fn_decl = &message.sig.decl;
fn_decl.paren_tok.surround(&mut content, |inner_toks| {
let args_without_self = {
let mut args_without_self: Punctuated<ast::FnArg, Token![,]> =
Punctuated::new();
for fn_arg in fn_decl
.inputs.iter()
// Performing `skip(1)` here works because we already asserted
// that all messages have to start with either `&self` or `&mut self`.
.skip(1)
{
args_without_self.push(fn_arg.clone())
}
args_without_self
};
args_without_self.to_tokens(inner_toks)
});
fn_decl.output.to_tokens(&mut content);
<Token![;]>::default().to_tokens(&mut content);
}
content
};
tokens.extend(quote! {
use pdsl_model::messages;
pdsl_model::messages! {
#messages_content
}
})
}
......@@ -19,6 +19,7 @@ pub fn contract(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
mod errors;
mod ast;
mod gen;
mod hir;
mod parser;
mod ident_ext;
......@@ -27,9 +28,9 @@ use errors::Result;
fn contract_gen_inner(input: proc_macro::TokenStream) -> Result<proc_macro::TokenStream> {
let ast_contract = parser::parse_contract(input.clone())?;
let _hir_contract = hir::Contract::from_ast(&ast_contract)?;
let hir_contract = hir::Contract::from_ast(&ast_contract)?;
// gen::gir::generate(&hir_program)?;
// let tokens = gen::codegen(&hir_program);
// Ok(tokens.into())
Ok(proc_macro::TokenStream::new())
let tokens = gen::codegen(&hir_contract);
Ok(tokens.into())
// Ok(proc_macro::TokenStream::new())
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment