diff options
Diffstat (limited to '')
-rw-r--r-- | dhall_generator/src/dhall_expr.rs | 57 | ||||
-rw-r--r-- | dhall_generator/src/dhall_type.rs | 4 | ||||
-rw-r--r-- | dhall_generator/src/lib.rs | 13 |
3 files changed, 65 insertions, 9 deletions
diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index 9da23b6..d0c5733 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -5,19 +5,29 @@ use proc_macro2::TokenStream; use quote::quote; use std::collections::BTreeMap; -pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +pub fn expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input_str = input.to_string(); let expr: SubExpr<X, Import> = parse_expr(&input_str).unwrap(); let no_import = - |_: &Import| -> X { panic!("Don't use import in dhall!()") }; - let expr = rc(expr.as_ref().map_embed(&no_import)); - let output = quote_subexpr(&expr, &Context::new()); + |_: &Import| -> X { panic!("Don't use import in dhall::expr!()") }; + let expr = expr.as_ref().map_embed(&no_import); + let output = quote_expr(&expr, &Context::new()); + output.into() +} + +pub fn subexpr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input_str = input.to_string(); + let expr: SubExpr<X, Import> = parse_expr(&input_str).unwrap(); + let no_import = + |_: &Import| -> X { panic!("Don't use import in dhall::subexpr!()") }; + let expr = expr.as_ref().map_embed(&no_import); + let output = quote_subexpr(&rc(expr), &Context::new()); output.into() } // Returns an expression of type ExprF<T, _, _>, where T is the // type of the subexpressions after interpolation. -pub fn quote_expr<TS>(expr: ExprF<TS, Label, X, X>) -> TokenStream +pub fn quote_exprf<TS>(expr: ExprF<TS, Label, X, X>) -> TokenStream where TS: quote::ToTokens + std::fmt::Debug, { @@ -134,7 +144,42 @@ fn quote_subexpr( } } } - e => bx(quote_expr(e)), + e => bx(quote_exprf(e)), + } +} + +// Returns an expression of type Expr<_, _>. Expects interpolated variables +// to be of type SubExpr<_, _>. +fn quote_expr(expr: &Expr<X, X>, ctx: &Context<Label, ()>) -> TokenStream { + use dhall_core::ExprF::*; + match expr.map_ref( + |e| quote_subexpr(e, ctx), + |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), + |_| unreachable!(), + |_| unreachable!(), + |l| l.clone(), + ) { + Var(V(ref s, n)) => { + match ctx.lookup(s, n) { + // Non-free variable; interpolates as itself + Some(()) => { + let s: String = s.into(); + let var = quote! { dhall_core::V(#s.into(), #n) }; + quote! { dhall_core::ExprF::Var(#var) } + } + // Free variable; interpolates as a rust variable + None => { + let s: String = s.into(); + // TODO: insert appropriate shifts ? + let v: TokenStream = s.parse().unwrap(); + quote! { { + let x: dhall_core::SubExpr<_, _> = #v.clone(); + x.unroll() + } } + } + } + } + e => quote_exprf(e), } } diff --git a/dhall_generator/src/dhall_type.rs b/dhall_generator/src/dhall_type.rs index ec023bc..3b1d1c9 100644 --- a/dhall_generator/src/dhall_type.rs +++ b/dhall_generator/src/dhall_type.rs @@ -48,7 +48,7 @@ pub fn derive_for_struct( }) .collect(); let record = - crate::dhall_expr::quote_expr(dhall_core::ExprF::RecordType(fields)); + crate::dhall_expr::quote_exprf(dhall_core::ExprF::RecordType(fields)); Ok(quote! { dhall_core::rc(#record) }) } @@ -93,7 +93,7 @@ pub fn derive_for_enum( .collect::<Result<_, Error>>()?; let union = - crate::dhall_expr::quote_expr(dhall_core::ExprF::UnionType(variants)); + crate::dhall_expr::quote_exprf(dhall_core::ExprF::UnionType(variants)); Ok(quote! { dhall_core::rc(#union) }) } diff --git a/dhall_generator/src/lib.rs b/dhall_generator/src/lib.rs index d720b67..f31faa4 100644 --- a/dhall_generator/src/lib.rs +++ b/dhall_generator/src/lib.rs @@ -5,9 +5,20 @@ mod dhall_type; use proc_macro::TokenStream; +// Deprecated #[proc_macro] pub fn dhall_expr(input: TokenStream) -> TokenStream { - dhall_expr::dhall_expr(input) + subexpr(input) +} + +#[proc_macro] +pub fn expr(input: TokenStream) -> TokenStream { + dhall_expr::expr(input) +} + +#[proc_macro] +pub fn subexpr(input: TokenStream) -> TokenStream { + dhall_expr::subexpr(input) } #[proc_macro_derive(Type)] |