Skip to content

Commit

Permalink
Preliminary resource-list refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
willtunnels committed Aug 26, 2024
1 parent b089341 commit 8967f86
Show file tree
Hide file tree
Showing 41 changed files with 3,304 additions and 3,570 deletions.
78 changes: 69 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ walkdir = "2.4.0"

[dependencies]
find_clang = { path = "./find_clang" }
morphic_macros = { path = "./morphic_macros" }
lalrpop-util = "0.20.0"
im-rc = "15.1.0"
stacker = "0.1.15"
Expand All @@ -33,6 +34,8 @@ id_collections = "1.0.1"
id_graph_sccs = "0.1.1"
once_cell = "1.19.0"
num-traits = "0.2.19"
hashbrown = "0.14.5"
rustc-hash = "2.0.0"

# Error handling
anyhow = "1.0.75"
Expand All @@ -44,4 +47,4 @@ rand_distr = "0.4.3"
rand_pcg = "0.3.1"

[workspace]
members = ["benchmark", "find_clang"]
members = ["benchmark", "find_clang", "morphic_macros"]
2 changes: 1 addition & 1 deletion benchmark/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "benchmark"
version = "0.1.0"
authors = ["William Brandon <[email protected]>"]
authors = ["William Brandon"]
edition = "2021"

[dependencies]
Expand Down
13 changes: 13 additions & 0 deletions morphic_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "morphic_macros"
version = "0.1.0"
authors = ["Benjamin Driscoll"]
edition = "2021"

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0.86"
quote = "1.0.36"
syn = { version = "2.0.72", features = ["extra-traits", "parsing"] }
142 changes: 142 additions & 0 deletions morphic_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use quote::{quote, ToTokens};
use syn::spanned::Spanned;
use syn::Error;

mod parse;

// We expect the data structures we emit to be declared in this module of the main Morphic crate.
#[allow(non_snake_case)]
fn DATA_MODULE() -> proc_macro2::TokenStream {
"crate::data::borrow_model".parse().unwrap()
}

fn declare_term(term: &parse::Term) -> proc_macro2::TokenStream {
let data_module = DATA_MODULE();
match term {
parse::Term::Var(var) => {
let var = var.inner.to_string();
quote! {
#data_module::RawTerm::Var(#var.to_string())
}
}
parse::Term::App(name, args) => {
let name = name.inner.to_string();
let args = args.iter().map(|arg| declare_term(arg)).collect::<Vec<_>>();
quote! {
#data_module::RawTerm::App(#name.to_string(), vec![#(#args),*])
}
}
parse::Term::Tuple(fields) => {
let fields = fields
.iter()
.map(|field| declare_term(field))
.collect::<Vec<_>>();
quote! {
#data_module::RawTerm::Tuple(vec![#(#fields),*])
}
}
}
}

fn declare_prop_expr(prop_expr: &parse::PropExpr) -> proc_macro2::TokenStream {
let data_module = DATA_MODULE();
let type_var = prop_expr.type_var.inner.to_string();
let prop = prop_expr.prop.inner.to_string();
quote! {
#data_module::RawPropExpr {
type_var: #type_var.to_string(),
prop: #prop.to_string(),
}
}
}

fn declare_constr(constr: &parse::Constr) -> proc_macro2::TokenStream {
let data_module = DATA_MODULE();
let lhs = declare_prop_expr(&constr.lhs);
let rhs = declare_prop_expr(&constr.rhs);
quote! {
#data_module::RawConstr {
lhs: #lhs,
rhs: #rhs,
}
}
}

fn declare_option<T: ToTokens>(opt: &Option<T>) -> proc_macro2::TokenStream {
match opt {
Some(inner) => quote! { Some(#inner) },
None => quote! { None },
}
}

fn declare_args(args: &parse::Args) -> Result<proc_macro2::TokenStream, Error> {
let data_module = DATA_MODULE();
let mut fixed = Vec::new();
let mut variadic = None;
for (i, arg) in args.iter().enumerate() {
match arg {
parse::Arg::Fixed(arg) => {
fixed.push(declare_term(arg));
}
parse::Arg::Variadic(arg, dots) => {
if i + 1 == args.len() {
variadic = Some(declare_term(arg));
} else {
return Err(Error::new(dots.span(), "variadic argument must be last"));
}
}
}
}
let variadic = declare_option(&variadic);
Ok(quote! {
#data_module::RawArgs {
fixed: vec![#(#fixed),*],
variadic: #variadic,
}
})
}

fn declare_signature(sig: &parse::Signature) -> Result<proc_macro2::TokenStream, Error> {
let data_module = DATA_MODULE();
let attrs = &sig.attrs;
let pub_token = &sig.pub_token;
let name = &sig.name.inner;
let args = declare_args(&sig.args)?;
let ret = declare_term(&sig.ret);
let constrs = match &sig.where_clause {
Some(where_clause) => where_clause
.constrs
.iter()
.map(|constr| declare_constr(constr))
.collect::<Vec<_>>(),
None => Vec::new(),
};
Ok(quote! {
#(#attrs)*
#[allow(non_upper_case_globals)]
#pub_token static #name: ::once_cell::sync::Lazy<Signature> = ::once_cell::sync::Lazy::new(|| {
#data_module::resolve_signature(#data_module::RawSignature {
args: #args,
ret: #ret,
constrs: vec![#(#constrs),*],
})
.unwrap()
});
})
}

#[proc_macro]
pub fn declare_signatures(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = syn::parse_macro_input!(input as parse::Input);

let sigs = input
.sigs
.iter()
.map(|sig| declare_signature(sig))
.collect::<Result<Vec<_>, _>>();

proc_macro::TokenStream::from(match sigs {
Ok(sigs) => quote! { #(#sigs)* },
Err(err) => err.to_compile_error(),
})
}
Loading

0 comments on commit 8967f86

Please sign in to comment.