From 40bee3cdcb9ac0c76996feeceb6ca160a6bd8b42 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 11 Feb 2020 19:04:44 +0000 Subject: Introduce LitKind to factor out common enum nodes --- dhall/src/syntax/ast/expr.rs | 22 ++++++++++++++-------- dhall/src/syntax/ast/visitor.rs | 5 +---- dhall/src/syntax/binary/decode.rs | 18 +++++++++--------- dhall/src/syntax/binary/encode.rs | 9 +++++---- dhall/src/syntax/text/parser.rs | 11 ++++++----- dhall/src/syntax/text/printer.rs | 30 ++++++++++++++++++++---------- 6 files changed, 55 insertions(+), 40 deletions(-) (limited to 'dhall/src/syntax') diff --git a/dhall/src/syntax/ast/expr.rs b/dhall/src/syntax/ast/expr.rs index 512010a..18ec9fd 100644 --- a/dhall/src/syntax/ast/expr.rs +++ b/dhall/src/syntax/ast/expr.rs @@ -103,6 +103,19 @@ pub struct Expr { pub type UnspannedExpr = ExprKind; +/// Simple literals +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LitKind { + /// `True` + Bool(bool), + /// `1` + Natural(Natural), + /// `+2` + Integer(Integer), + /// `3.24` + Double(Double), +} + /// Syntax tree for expressions // Having the recursion out of the enum definition enables writing // much more generic code and improves pattern-matching behind @@ -110,6 +123,7 @@ pub type UnspannedExpr = ExprKind; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ExprKind { Const(Const), + Lit(LitKind), /// `x` /// `x@n` Var(V), @@ -131,16 +145,8 @@ pub enum ExprKind { Builtin(Builtin), // Binary operations BinOp(BinOp, SubExpr, SubExpr), - /// `True` - BoolLit(bool), /// `if x then y else z` BoolIf(SubExpr, SubExpr, SubExpr), - /// `1` - NaturalLit(Natural), - /// `+2` - IntegerLit(Integer), - /// `3.24` - DoubleLit(Double), /// `"Some ${interpolated} text"` TextLit(InterpolatedText), /// `[] : t` diff --git a/dhall/src/syntax/ast/visitor.rs b/dhall/src/syntax/ast/visitor.rs index 39959ac..c361bc1 100644 --- a/dhall/src/syntax/ast/visitor.rs +++ b/dhall/src/syntax/ast/visitor.rs @@ -91,10 +91,7 @@ where Annot(x, t) => Annot(expr!(x)?, expr!(t)?), Const(k) => Const(*k), Builtin(v) => Builtin(*v), - BoolLit(b) => BoolLit(*b), - NaturalLit(n) => NaturalLit(*n), - IntegerLit(n) => IntegerLit(*n), - DoubleLit(n) => DoubleLit(*n), + Lit(l) => Lit(l.clone()), TextLit(t) => TextLit(t.traverse_ref(|e| expr!(e))?), BinOp(o, x, y) => BinOp(*o, expr!(x)?, expr!(y)?), BoolIf(b, t, f) => BoolIf(expr!(b)?, expr!(t)?, expr!(f)?), diff --git a/dhall/src/syntax/binary/decode.rs b/dhall/src/syntax/binary/decode.rs index 6fbcc10..2e50d61 100644 --- a/dhall/src/syntax/binary/decode.rs +++ b/dhall/src/syntax/binary/decode.rs @@ -6,8 +6,8 @@ use crate::error::DecodeError; use crate::syntax; use crate::syntax::{ Expr, ExprKind, FilePath, FilePrefix, Hash, ImportLocation, ImportMode, - Integer, InterpolatedText, Label, Natural, Scheme, Span, UnspannedExpr, - URL, V, + Integer, InterpolatedText, Label, LitKind, Natural, Scheme, Span, + UnspannedExpr, URL, V, }; use crate::DecodedExpr; @@ -31,8 +31,8 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result { String(s) => match Builtin::parse(s) { Some(b) => ExprKind::Builtin(b), None => match s.as_str() { - "True" => BoolLit(true), - "False" => BoolLit(false), + "True" => Lit(LitKind::Bool(true)), + "False" => Lit(LitKind::Bool(false)), "Type" => Const(Const::Type), "Kind" => Const(Const::Kind), "Sort" => Const(Const::Sort), @@ -40,8 +40,8 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result { }, }, U64(n) => Var(V(Label::from("_"), *n as usize)), - F64(x) => DoubleLit((*x).into()), - Bool(b) => BoolLit(*b), + F64(x) => Lit(LitKind::Double((*x).into())), + Bool(b) => Lit(LitKind::Bool(*b)), Array(vec) => match vec.as_slice() { [String(l), U64(n)] => { if l.as_str() == "_" { @@ -216,9 +216,9 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result { let z = cbor_value_to_dhall(&z)?; BoolIf(x, y, z) } - [U64(15), U64(x)] => NaturalLit(*x as Natural), - [U64(16), U64(x)] => IntegerLit(*x as Integer), - [U64(16), I64(x)] => IntegerLit(*x as Integer), + [U64(15), U64(x)] => Lit(LitKind::Natural(*x as Natural)), + [U64(16), U64(x)] => Lit(LitKind::Integer(*x as Integer)), + [U64(16), I64(x)] => Lit(LitKind::Integer(*x as Integer)), [U64(18), String(first), rest @ ..] => { TextLit(InterpolatedText::from(( first.clone(), diff --git a/dhall/src/syntax/binary/encode.rs b/dhall/src/syntax/binary/encode.rs index 686f737..291ac4a 100644 --- a/dhall/src/syntax/binary/encode.rs +++ b/dhall/src/syntax/binary/encode.rs @@ -46,6 +46,7 @@ where use std::iter::once; use syntax::Builtin; use syntax::ExprKind::*; + use syntax::LitKind::*; use self::Serialize::{RecordMap, UnionMap}; fn expr(x: &Expr) -> self::Serialize<'_> { @@ -60,10 +61,10 @@ where match e.as_ref() { Const(c) => ser.serialize_str(&c.to_string()), Builtin(b) => ser.serialize_str(&b.to_string()), - BoolLit(b) => ser.serialize_bool(*b), - NaturalLit(n) => ser_seq!(ser; tag(15), U64(*n as u64)), - IntegerLit(n) => ser_seq!(ser; tag(16), I64(*n as i64)), - DoubleLit(n) => { + Lit(Bool(b)) => ser.serialize_bool(*b), + Lit(Natural(n)) => ser_seq!(ser; tag(15), U64(*n as u64)), + Lit(Integer(n)) => ser_seq!(ser; tag(16), I64(*n as i64)), + Lit(Double(n)) => { let n: f64 = (*n).into(); ser.serialize_f64(n) } diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs index 0ff1363..f3ebd2b 100644 --- a/dhall/src/syntax/text/parser.rs +++ b/dhall/src/syntax/text/parser.rs @@ -7,6 +7,7 @@ use pest_consume::{match_nodes, Parser}; use crate::syntax::map::{DupTreeMap, DupTreeSet}; use crate::syntax::ExprKind::*; +use crate::syntax::LitKind::*; use crate::syntax::{ Double, Expr, FilePath, FilePrefix, Hash, ImportLocation, ImportMode, Integer, InterpolatedText, InterpolatedTextContents, Label, NaiveDouble, @@ -344,8 +345,8 @@ impl DhallParser { let e = match crate::syntax::Builtin::parse(s) { Some(b) => Builtin(b), None => match s { - "True" => BoolLit(true), - "False" => BoolLit(false), + "True" => Lit(Bool(true)), + "False" => Lit(Bool(false)), "Type" => Const(crate::syntax::Const::Type), "Kind" => Const(crate::syntax::Const::Kind), "Sort" => Const(crate::syntax::Const::Sort), @@ -833,9 +834,9 @@ impl DhallParser { #[alias(expression, shortcut = true)] fn primitive_expression(input: ParseInput) -> ParseResult { Ok(match_nodes!(input.children(); - [double_literal(n)] => spanned(input, DoubleLit(n)), - [natural_literal(n)] => spanned(input, NaturalLit(n)), - [integer_literal(n)] => spanned(input, IntegerLit(n)), + [double_literal(n)] => spanned(input, Lit(Double(n))), + [natural_literal(n)] => spanned(input, Lit(Natural(n))), + [integer_literal(n)] => spanned(input, Lit(Integer(n))), [double_quote_literal(s)] => spanned(input, TextLit(s)), [single_quote_literal(s)] => spanned(input, TextLit(s)), [record_type_or_literal(e)] => spanned(input, e), diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs index d1c9588..8891d41 100644 --- a/dhall/src/syntax/text/printer.rs +++ b/dhall/src/syntax/text/printer.rs @@ -196,15 +196,7 @@ impl Display for ExprKind { Var(a) => a.fmt(f)?, Const(k) => k.fmt(f)?, Builtin(v) => v.fmt(f)?, - BoolLit(true) => f.write_str("True")?, - BoolLit(false) => f.write_str("False")?, - NaturalLit(a) => a.fmt(f)?, - IntegerLit(a) if *a >= 0 => { - f.write_str("+")?; - a.fmt(f)?; - } - IntegerLit(a) => a.fmt(f)?, - DoubleLit(a) => a.fmt(f)?, + Lit(a) => a.fmt(f)?, TextLit(a) => a.fmt(f)?, RecordType(a) if a.is_empty() => f.write_str("{}")?, RecordType(a) => fmt_list("{ ", ", ", " }", a, f, |(k, t), f| { @@ -239,7 +231,25 @@ impl Display for ExprKind { impl Display for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.as_ref().fmt_phase(f, PrintPhase::Base) + self.kind().fmt_phase(f, PrintPhase::Base) + } +} + +impl Display for LitKind { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + use LitKind::*; + match self { + Bool(true) => f.write_str("True")?, + Bool(false) => f.write_str("False")?, + Natural(a) => a.fmt(f)?, + Integer(a) if *a >= 0 => { + f.write_str("+")?; + a.fmt(f)?; + } + Integer(a) => a.fmt(f)?, + Double(a) => a.fmt(f)?, + } + Ok(()) } } -- cgit v1.2.3