From f5d2151d35942b957230c3081a928af3619d9400 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 18:47:34 +0200 Subject: Make SubExpr a newtype --- dhall_generator/src/dhall_expr.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index 41e558b..e2187d6 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -4,7 +4,6 @@ use dhall_core::*; use proc_macro2::TokenStream; use quote::quote; use std::collections::BTreeMap; -use std::rc::Rc; pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input_str = input.to_string(); @@ -17,7 +16,7 @@ pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } // Returns an expression of type Expr<_, _>. Expects interpolated variables -// to be of type Rc>. +// to be of type SubExpr<_, _>. fn dhall_to_tokenstream( expr: &DhallExpr, ctx: &Context, @@ -97,7 +96,7 @@ fn dhall_to_tokenstream( } } -// Returns an expression of type Rc> +// Returns an expression of type SubExpr<_, _> fn dhall_to_tokenstream_bx( expr: &DhallExpr, ctx: &Context, @@ -146,7 +145,7 @@ fn label_to_tokenstream(l: &Label) -> TokenStream { } fn map_to_tokenstream( - m: &BTreeMap>>, + m: &BTreeMap>, ctx: &Context, ) -> TokenStream { let (keys, values): (Vec, Vec) = m -- cgit v1.2.3 From bfe3f7f75570540fa184a133653d16e86f22667a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 18:47:57 +0200 Subject: rustfmt --- dhall_generator/src/dhall_type.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_type.rs b/dhall_generator/src/dhall_type.rs index ac8eb4e..270c27c 100644 --- a/dhall_generator/src/dhall_type.rs +++ b/dhall_generator/src/dhall_type.rs @@ -168,9 +168,7 @@ pub fn derive_type_inner( // Ensure that all the fields have a Type impl let mut where_clause = orig_where_clause.clone(); for ty in constraints.iter() { - where_clause - .predicates - .push(parse_quote!(#ty: dhall::Type)); + where_clause.predicates.push(parse_quote!(#ty: dhall::Type)); } let ident = &input.ident; -- cgit v1.2.3 From 7374d0524ccd53b256107667b213597c05720d2d Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 19:08:08 +0200 Subject: Move recursion out of Expr --- dhall_generator/src/dhall_expr.rs | 36 ++++++++++++++++++------------------ dhall_generator/src/dhall_type.rs | 4 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index e2187d6..c4b15e8 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -21,7 +21,7 @@ fn dhall_to_tokenstream( expr: &DhallExpr, ctx: &Context, ) -> TokenStream { - use dhall_core::Expr::*; + use dhall_core::ExprF::*; match expr.as_ref() { Var(_) => { let v = dhall_to_tokenstream_bx(expr, ctx); @@ -31,66 +31,66 @@ fn dhall_to_tokenstream( let t = dhall_to_tokenstream_bx(t, ctx); let b = dhall_to_tokenstream_bx(b, &ctx.insert(x.clone(), ())); let x = label_to_tokenstream(x); - quote! { dhall_core::Expr::Pi(#x, #t, #b) } + quote! { dhall_core::ExprF::Pi(#x, #t, #b) } } Lam(x, t, b) => { let t = dhall_to_tokenstream_bx(t, ctx); let b = dhall_to_tokenstream_bx(b, &ctx.insert(x.clone(), ())); let x = label_to_tokenstream(x); - quote! { dhall_core::Expr::Lam(#x, #t, #b) } + quote! { dhall_core::ExprF::Lam(#x, #t, #b) } } App(f, a) => { let f = dhall_to_tokenstream_bx(f, ctx); let a = vec_to_tokenstream(a, ctx); - quote! { dhall_core::Expr::App(#f, #a) } + quote! { dhall_core::ExprF::App(#f, #a) } } Const(c) => { let c = const_to_tokenstream(*c); - quote! { dhall_core::Expr::Const(#c) } + quote! { dhall_core::ExprF::Const(#c) } } Builtin(b) => { let b = builtin_to_tokenstream(*b); - quote! { dhall_core::Expr::Builtin(#b) } + quote! { dhall_core::ExprF::Builtin(#b) } } BinOp(o, a, b) => { let o = binop_to_tokenstream(*o); let a = dhall_to_tokenstream_bx(a, ctx); let b = dhall_to_tokenstream_bx(b, ctx); - quote! { dhall_core::Expr::BinOp(#o, #a, #b) } + quote! { dhall_core::ExprF::BinOp(#o, #a, #b) } } NaturalLit(n) => { - quote! { dhall_core::Expr::NaturalLit(#n) } + quote! { dhall_core::ExprF::NaturalLit(#n) } } BoolLit(b) => { - quote! { dhall_core::Expr::BoolLit(#b) } + quote! { dhall_core::ExprF::BoolLit(#b) } } EmptyOptionalLit(x) => { let x = dhall_to_tokenstream_bx(x, ctx); - quote! { dhall_core::Expr::EmptyOptionalLit(#x) } + quote! { dhall_core::ExprF::EmptyOptionalLit(#x) } } NEOptionalLit(x) => { let x = dhall_to_tokenstream_bx(x, ctx); - quote! { dhall_core::Expr::NEOptionalLit(#x) } + quote! { dhall_core::ExprF::NEOptionalLit(#x) } } EmptyListLit(t) => { let t = dhall_to_tokenstream_bx(t, ctx); - quote! { dhall_core::Expr::EmptyListLit(#t) } + quote! { dhall_core::ExprF::EmptyListLit(#t) } } NEListLit(es) => { let es = vec_to_tokenstream(es, ctx); - quote! { dhall_core::Expr::NEListLit(#es) } + quote! { dhall_core::ExprF::NEListLit(#es) } } RecordType(m) => { let m = map_to_tokenstream(m, ctx); - quote! { dhall_core::Expr::RecordType(#m) } + quote! { dhall_core::ExprF::RecordType(#m) } } RecordLit(m) => { let m = map_to_tokenstream(m, ctx); - quote! { dhall_core::Expr::RecordLit(#m) } + quote! { dhall_core::ExprF::RecordLit(#m) } } UnionType(m) => { let m = map_to_tokenstream(m, ctx); - quote! { dhall_core::Expr::UnionType(#m) } + quote! { dhall_core::ExprF::UnionType(#m) } } e => unimplemented!("{:?}", e), } @@ -101,7 +101,7 @@ fn dhall_to_tokenstream_bx( expr: &DhallExpr, ctx: &Context, ) -> TokenStream { - use dhall_core::Expr::*; + use dhall_core::ExprF::*; match expr.as_ref() { Var(V(s, n)) => { match ctx.lookup(&s, *n) { @@ -109,7 +109,7 @@ fn dhall_to_tokenstream_bx( Some(()) => { let s: String = s.into(); let var = quote! { dhall_core::V(#s.into(), #n) }; - bx(quote! { dhall_core::Expr::Var(#var) }) + bx(quote! { dhall_core::ExprF::Var(#var) }) } // Free variable; interpolates as a rust variable None => { diff --git a/dhall_generator/src/dhall_type.rs b/dhall_generator/src/dhall_type.rs index 270c27c..876d261 100644 --- a/dhall_generator/src/dhall_type.rs +++ b/dhall_generator/src/dhall_type.rs @@ -48,7 +48,7 @@ pub fn derive_for_struct( ); } }); - Ok(quote! { dhall_core::rc(dhall_core::Expr::RecordType({ + Ok(quote! { dhall_core::rc(dhall_core::ExprF::RecordType({ use std::collections::BTreeMap; let mut m = BTreeMap::new(); #(#fields)* @@ -101,7 +101,7 @@ pub fn derive_for_enum( }) .collect::, Error>>()?; - Ok(quote! { dhall_core::rc(dhall_core::Expr::UnionType({ + Ok(quote! { dhall_core::rc(dhall_core::ExprF::UnionType({ use std::collections::BTreeMap; let mut m = BTreeMap::new(); #(#variants)* -- cgit v1.2.3 From 737472abf9c0ca2030ab8c2bb0b1d4af41167183 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 19:37:29 +0200 Subject: Remove evil Deref impl --- dhall_generator/src/dhall_expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index c4b15e8..2e3adf7 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -10,7 +10,7 @@ pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expr: SubExpr = parse_expr(&input_str).unwrap(); let no_import = |_: &Import| -> X { panic!("Don't use import in dhall!()") }; - let expr = rc(expr.map_embed(&no_import)); + let expr = rc(expr.as_ref().map_embed(&no_import)); let output = dhall_to_tokenstream_bx(&expr, &Context::new()); output.into() } -- cgit v1.2.3 From c4fe2f4290089437d3ff1d6d15df58b4cf29a11e Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 20:38:04 +0200 Subject: Make quoting generic --- dhall_generator/src/dhall_expr.rs | 122 +++++++++++++++++--------------------- dhall_generator/src/dhall_type.rs | 46 ++++++-------- 2 files changed, 70 insertions(+), 98 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index 2e3adf7..96201e8 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -11,51 +11,56 @@ pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let no_import = |_: &Import| -> X { panic!("Don't use import in dhall!()") }; let expr = rc(expr.as_ref().map_embed(&no_import)); - let output = dhall_to_tokenstream_bx(&expr, &Context::new()); + let output = quote_subexpr(&expr, &Context::new()); output.into() } -// Returns an expression of type Expr<_, _>. Expects interpolated variables -// to be of type SubExpr<_, _>. -fn dhall_to_tokenstream( - expr: &DhallExpr, - ctx: &Context, -) -> TokenStream { +// Returns an expression of type ExprF, where T is the +// type of the subexpressions after interpolation. +pub fn quote_expr(expr: ExprF) -> TokenStream +where + TS: quote::ToTokens + std::fmt::Debug, +{ + let quote_map = |m: BTreeMap| -> TokenStream { + let (keys, values): (Vec, Vec) = + m.into_iter().map(|(k, v)| (quote_label(&k), v)).unzip(); + quote! { { + use std::collections::BTreeMap; + let mut m = BTreeMap::new(); + #( m.insert(#keys, #values); )* + m + } } + }; + + let quote_vec = |e: Vec| -> TokenStream { + quote! { vec![ #(#e),* ] } + }; + use dhall_core::ExprF::*; - match expr.as_ref() { - Var(_) => { - let v = dhall_to_tokenstream_bx(expr, ctx); - quote! { *#v } - } + match expr { + Var(_) => unreachable!(), Pi(x, t, b) => { - let t = dhall_to_tokenstream_bx(t, ctx); - let b = dhall_to_tokenstream_bx(b, &ctx.insert(x.clone(), ())); - let x = label_to_tokenstream(x); + let x = quote_label(&x); quote! { dhall_core::ExprF::Pi(#x, #t, #b) } } Lam(x, t, b) => { - let t = dhall_to_tokenstream_bx(t, ctx); - let b = dhall_to_tokenstream_bx(b, &ctx.insert(x.clone(), ())); - let x = label_to_tokenstream(x); + let x = quote_label(&x); quote! { dhall_core::ExprF::Lam(#x, #t, #b) } } App(f, a) => { - let f = dhall_to_tokenstream_bx(f, ctx); - let a = vec_to_tokenstream(a, ctx); + let a = quote_vec(a); quote! { dhall_core::ExprF::App(#f, #a) } } Const(c) => { - let c = const_to_tokenstream(*c); + let c = quote_const(c); quote! { dhall_core::ExprF::Const(#c) } } Builtin(b) => { - let b = builtin_to_tokenstream(*b); + let b = quote_builtin(b); quote! { dhall_core::ExprF::Builtin(#b) } } BinOp(o, a, b) => { - let o = binop_to_tokenstream(*o); - let a = dhall_to_tokenstream_bx(a, ctx); - let b = dhall_to_tokenstream_bx(b, ctx); + let o = quote_binop(o); quote! { dhall_core::ExprF::BinOp(#o, #a, #b) } } NaturalLit(n) => { @@ -65,46 +70,51 @@ fn dhall_to_tokenstream( quote! { dhall_core::ExprF::BoolLit(#b) } } EmptyOptionalLit(x) => { - let x = dhall_to_tokenstream_bx(x, ctx); quote! { dhall_core::ExprF::EmptyOptionalLit(#x) } } NEOptionalLit(x) => { - let x = dhall_to_tokenstream_bx(x, ctx); quote! { dhall_core::ExprF::NEOptionalLit(#x) } } EmptyListLit(t) => { - let t = dhall_to_tokenstream_bx(t, ctx); quote! { dhall_core::ExprF::EmptyListLit(#t) } } NEListLit(es) => { - let es = vec_to_tokenstream(es, ctx); + let es = quote_vec(es); quote! { dhall_core::ExprF::NEListLit(#es) } } RecordType(m) => { - let m = map_to_tokenstream(m, ctx); + let m = quote_map(m); quote! { dhall_core::ExprF::RecordType(#m) } } RecordLit(m) => { - let m = map_to_tokenstream(m, ctx); + let m = quote_map(m); quote! { dhall_core::ExprF::RecordLit(#m) } } UnionType(m) => { - let m = map_to_tokenstream(m, ctx); + let m = quote_map(m); quote! { dhall_core::ExprF::UnionType(#m) } } e => unimplemented!("{:?}", e), } } -// Returns an expression of type SubExpr<_, _> -fn dhall_to_tokenstream_bx( - expr: &DhallExpr, +// Returns an expression of type SubExpr<_, _>. Expects interpolated variables +// to be of type SubExpr<_, _>. +fn quote_subexpr( + expr: &SubExpr, ctx: &Context, ) -> TokenStream { use dhall_core::ExprF::*; - match expr.as_ref() { - Var(V(s, n)) => { - match ctx.lookup(&s, *n) { + match map_subexpr( + expr.as_ref(), + |e| quote_subexpr(e, ctx), + |_| unreachable!(), + |_| unreachable!(), + |l| l.clone(), + |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), + ) { + Var(V(ref s, n)) => { + match ctx.lookup(s, n) { // Non-free variable; interpolates as itself Some(()) => { let s: String = s.into(); @@ -123,53 +133,27 @@ fn dhall_to_tokenstream_bx( } } } - _ => bx(dhall_to_tokenstream(expr, ctx)), + e => bx(quote_expr(e)), } } -fn builtin_to_tokenstream(b: Builtin) -> TokenStream { +fn quote_builtin(b: Builtin) -> TokenStream { format!("dhall_core::Builtin::{:?}", b).parse().unwrap() } -fn const_to_tokenstream(c: Const) -> TokenStream { +fn quote_const(c: Const) -> TokenStream { format!("dhall_core::Const::{:?}", c).parse().unwrap() } -fn binop_to_tokenstream(b: BinOp) -> TokenStream { +fn quote_binop(b: BinOp) -> TokenStream { format!("dhall_core::BinOp::{:?}", b).parse().unwrap() } -fn label_to_tokenstream(l: &Label) -> TokenStream { +fn quote_label(l: &Label) -> TokenStream { let l = String::from(l); quote! { #l.into() } } -fn map_to_tokenstream( - m: &BTreeMap>, - ctx: &Context, -) -> TokenStream { - let (keys, values): (Vec, Vec) = m - .iter() - .map(|(k, v)| { - (label_to_tokenstream(k), dhall_to_tokenstream_bx(&*v, ctx)) - }) - .unzip(); - quote! { { - use std::collections::BTreeMap; - let mut m = BTreeMap::new(); - #( m.insert(#keys, #values); )* - m - } } -} - -fn vec_to_tokenstream( - e: &Vec, - ctx: &Context, -) -> TokenStream { - let e = e.iter().map(|x| dhall_to_tokenstream_bx(x, ctx)); - quote! { vec![ #(#e),* ] } -} - fn bx(x: TokenStream) -> TokenStream { quote! { dhall_core::bx(#x) } } diff --git a/dhall_generator/src/dhall_type.rs b/dhall_generator/src/dhall_type.rs index 876d261..ec023bc 100644 --- a/dhall_generator/src/dhall_type.rs +++ b/dhall_generator/src/dhall_type.rs @@ -39,21 +39,17 @@ pub fn derive_for_struct( .collect(), syn::Fields::Unit => vec![], }; - let fields = fields.into_iter().map(|(name, ty)| { - constraints.push(ty.clone()); - quote! { - m.insert( - dhall_core::Label::from(#name), - <#ty as dhall::Type>::get_type() - ); - } - }); - Ok(quote! { dhall_core::rc(dhall_core::ExprF::RecordType({ - use std::collections::BTreeMap; - let mut m = BTreeMap::new(); - #(#fields)* - m - })) }) + let fields = fields + .into_iter() + .map(|(name, ty)| { + let name = dhall_core::Label::from(name); + constraints.push(ty.clone()); + (name, quote!(<#ty as dhall::Type>::get_type())) + }) + .collect(); + let record = + crate::dhall_expr::quote_expr(dhall_core::ExprF::RecordType(fields)); + Ok(quote! { dhall_core::rc(#record) }) } pub fn derive_for_enum( @@ -64,7 +60,7 @@ pub fn derive_for_enum( .variants .iter() .map(|v| { - let name = v.ident.to_string(); + let name = dhall_core::Label::from(v.ident.to_string()); let ty = match &v.fields { syn::Fields::Unnamed(fields) if fields.unnamed.is_empty() => { Err(Error::new( @@ -92,21 +88,13 @@ pub fn derive_for_enum( }; let ty = ty?; constraints.push(ty.clone()); - Ok(quote! { - m.insert( - dhall_core::Label::from(#name), - <#ty as dhall::Type>::get_type() - ); - }) + Ok((name, quote!(<#ty as dhall::Type>::get_type()))) }) - .collect::, Error>>()?; + .collect::>()?; - Ok(quote! { dhall_core::rc(dhall_core::ExprF::UnionType({ - use std::collections::BTreeMap; - let mut m = BTreeMap::new(); - #(#variants)* - m - })) }) + let union = + crate::dhall_expr::quote_expr(dhall_core::ExprF::UnionType(variants)); + Ok(quote! { dhall_core::rc(#union) }) } pub fn derive_type_inner( -- cgit v1.2.3 From 62970fd2010b01260cf45a1f2a6a582c6a8c0c12 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 31 Mar 2019 21:04:10 +0200 Subject: Make Expr generic in Label --- dhall_generator/src/dhall_expr.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index 96201e8..b057850 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -17,17 +17,20 @@ pub fn dhall_expr(input: proc_macro::TokenStream) -> proc_macro::TokenStream { // Returns an expression of type ExprF, where T is the // type of the subexpressions after interpolation. -pub fn quote_expr(expr: ExprF) -> TokenStream +pub fn quote_expr(expr: ExprF) -> TokenStream where TS: quote::ToTokens + std::fmt::Debug, { let quote_map = |m: BTreeMap| -> TokenStream { - let (keys, values): (Vec, Vec) = - m.into_iter().map(|(k, v)| (quote_label(&k), v)).unzip(); + let entries = + m.into_iter().map(|(k, v)| { + let k = quote_label(&k); + quote!(m.insert(#k, #v);) + }); quote! { { use std::collections::BTreeMap; let mut m = BTreeMap::new(); - #( m.insert(#keys, #values); )* + #( #entries )* m } } }; @@ -151,7 +154,7 @@ fn quote_binop(b: BinOp) -> TokenStream { fn quote_label(l: &Label) -> TokenStream { let l = String::from(l); - quote! { #l.into() } + quote! { dhall_core::Label::from(#l) } } fn bx(x: TokenStream) -> TokenStream { -- cgit v1.2.3 From 57ccbfa16f48f373ac5545b8523de56fb996ba3e Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 1 Apr 2019 00:17:44 +0200 Subject: Refactor and clarify various map methods --- dhall_generator/src/dhall_expr.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'dhall_generator') diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index b057850..9da23b6 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -22,11 +22,10 @@ where TS: quote::ToTokens + std::fmt::Debug, { let quote_map = |m: BTreeMap| -> TokenStream { - let entries = - m.into_iter().map(|(k, v)| { - let k = quote_label(&k); - quote!(m.insert(#k, #v);) - }); + let entries = m.into_iter().map(|(k, v)| { + let k = quote_label(&k); + quote!(m.insert(#k, #v);) + }); quote! { { use std::collections::BTreeMap; let mut m = BTreeMap::new(); @@ -108,13 +107,12 @@ fn quote_subexpr( ctx: &Context, ) -> TokenStream { use dhall_core::ExprF::*; - match map_subexpr( - expr.as_ref(), + match expr.as_ref().map_ref( |e| quote_subexpr(e, ctx), + |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), |_| unreachable!(), |_| unreachable!(), |l| l.clone(), - |l, e| quote_subexpr(e, &ctx.insert(l.clone(), ())), ) { Var(V(ref s, n)) => { match ctx.lookup(s, n) { -- cgit v1.2.3