summaryrefslogtreecommitdiff
path: root/dhall/src/syntax/text
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dhall/src/syntax/text/parser.rs29
-rw-r--r--dhall/src/syntax/text/printer.rs275
2 files changed, 152 insertions, 152 deletions
diff --git a/dhall/src/syntax/text/parser.rs b/dhall/src/syntax/text/parser.rs
index f6b6577..90cb4b1 100644
--- a/dhall/src/syntax/text/parser.rs
+++ b/dhall/src/syntax/text/parser.rs
@@ -7,13 +7,12 @@ use pest_consume::{match_nodes, Parser};
use crate::semantics::phase::Normalized;
use crate::syntax;
-use crate::syntax::core;
use crate::syntax::map::{DupTreeMap, DupTreeSet};
-use crate::syntax::ExprF::*;
+use crate::syntax::ExprKind::*;
use crate::syntax::{
- FilePath, FilePrefix, Hash, ImportLocation, ImportMode, InterpolatedText,
- InterpolatedTextContents, Label, NaiveDouble, RawExpr, Scheme, Span, URL,
- V,
+ Double, FilePath, FilePrefix, Hash, ImportLocation, ImportMode, Integer,
+ InterpolatedText, InterpolatedTextContents, Label, NaiveDouble, Natural,
+ Scheme, Span, UnspannedExpr, URL, V,
};
// This file consumes the parse tree generated by pest and turns it into
@@ -77,10 +76,14 @@ impl crate::syntax::Builtin {
fn input_to_span(input: ParseInput) -> Span {
Span::make(input.user_data().clone(), input.as_pair().as_span())
}
-fn spanned(input: ParseInput, x: RawExpr<Normalized>) -> Expr {
+fn spanned(input: ParseInput, x: UnspannedExpr<Normalized>) -> Expr {
Expr::new(x, input_to_span(input))
}
-fn spanned_union(span1: Span, span2: Span, x: RawExpr<Normalized>) -> Expr {
+fn spanned_union(
+ span1: Span,
+ span2: Span,
+ x: UnspannedExpr<Normalized>,
+) -> Expr {
Expr::new(x, span1.union(&span2))
}
@@ -349,20 +352,20 @@ impl DhallParser {
}
#[alias(double_literal)]
- fn NaN(_input: ParseInput) -> ParseResult<core::Double> {
+ fn NaN(_input: ParseInput) -> ParseResult<Double> {
Ok(std::f64::NAN.into())
}
#[alias(double_literal)]
- fn minus_infinity_literal(_input: ParseInput) -> ParseResult<core::Double> {
+ fn minus_infinity_literal(_input: ParseInput) -> ParseResult<Double> {
Ok(std::f64::NEG_INFINITY.into())
}
#[alias(double_literal)]
- fn plus_infinity_literal(_input: ParseInput) -> ParseResult<core::Double> {
+ fn plus_infinity_literal(_input: ParseInput) -> ParseResult<Double> {
Ok(std::f64::INFINITY.into())
}
#[alias(double_literal)]
- fn numeric_double_literal(input: ParseInput) -> ParseResult<core::Double> {
+ fn numeric_double_literal(input: ParseInput) -> ParseResult<Double> {
let s = input.as_str().trim();
match s.parse::<f64>() {
Ok(x) if x.is_infinite() => Err(input.error(format!(
@@ -374,7 +377,7 @@ impl DhallParser {
}
}
- fn natural_literal(input: ParseInput) -> ParseResult<core::Natural> {
+ fn natural_literal(input: ParseInput) -> ParseResult<Natural> {
input
.as_str()
.trim()
@@ -382,7 +385,7 @@ impl DhallParser {
.map_err(|e| input.error(format!("{}", e)))
}
- fn integer_literal(input: ParseInput) -> ParseResult<core::Integer> {
+ fn integer_literal(input: ParseInput) -> ParseResult<Integer> {
input
.as_str()
.trim()
diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs
index 8df456b..78942ed 100644
--- a/dhall/src/syntax/text/printer.rs
+++ b/dhall/src/syntax/text/printer.rs
@@ -2,10 +2,137 @@ use crate::syntax::*;
use itertools::Itertools;
use std::fmt::{self, Display};
+// There is a one-to-one correspondence between the formatter and the grammar. Each phase is
+// named after a corresponding grammar group, and the structure of the formatter reflects
+// the relationship between the corresponding grammar rules. This leads to the nice property
+// of automatically getting all the parentheses and precedences right.
+#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
+enum PrintPhase {
+ Base,
+ Operator,
+ BinOp(ast::BinOp),
+ App,
+ Import,
+ Primitive,
+}
+
+// Wraps an Expr with a phase, so that phase selection can be done separate from the actual
+// printing.
+#[derive(Clone)]
+struct PhasedExpr<'a, E>(&'a Expr<E>, PrintPhase);
+
+impl<'a, E: Display + Clone> PhasedExpr<'a, E> {
+ fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, E> {
+ PhasedExpr(self.0, phase)
+ }
+}
+
+impl<E: Display + Clone> UnspannedExpr<E> {
+ // Annotate subexpressions with the appropriate phase, defaulting to Base
+ fn annotate_with_phases<'a>(&'a self) -> ExprKind<PhasedExpr<'a, E>, E> {
+ use crate::syntax::ExprKind::*;
+ use PrintPhase::*;
+ let with_base = self.map_ref(|e| PhasedExpr(e, Base));
+ match with_base {
+ Pi(a, b, c) => {
+ if &String::from(&a) == "_" {
+ Pi(a, b.phase(Operator), c)
+ } else {
+ Pi(a, b, c)
+ }
+ }
+ Merge(a, b, c) => Merge(
+ a.phase(PrintPhase::Import),
+ b.phase(PrintPhase::Import),
+ c.map(|x| x.phase(PrintPhase::App)),
+ ),
+ ToMap(a, b) => ToMap(
+ a.phase(PrintPhase::Import),
+ b.map(|x| x.phase(PrintPhase::App)),
+ ),
+ Annot(a, b) => Annot(a.phase(Operator), b),
+ ExprKind::BinOp(op, a, b) => ExprKind::BinOp(
+ op,
+ a.phase(PrintPhase::BinOp(op)),
+ b.phase(PrintPhase::BinOp(op)),
+ ),
+ SomeLit(e) => SomeLit(e.phase(PrintPhase::Import)),
+ ExprKind::App(f, a) => ExprKind::App(
+ f.phase(PrintPhase::Import),
+ a.phase(PrintPhase::Import),
+ ),
+ Field(a, b) => Field(a.phase(Primitive), b),
+ Projection(e, ls) => Projection(e.phase(Primitive), ls),
+ ProjectionByExpr(a, b) => ProjectionByExpr(a.phase(Primitive), b),
+ e => e,
+ }
+ }
+
+ fn fmt_phase(
+ &self,
+ f: &mut fmt::Formatter,
+ phase: PrintPhase,
+ ) -> Result<(), fmt::Error> {
+ use crate::syntax::ExprKind::*;
+
+ let needs_paren = match self {
+ Lam(_, _, _)
+ | BoolIf(_, _, _)
+ | Pi(_, _, _)
+ | Let(_, _, _, _)
+ | EmptyListLit(_)
+ | NEListLit(_)
+ | SomeLit(_)
+ | Merge(_, _, _)
+ | ToMap(_, _)
+ | Annot(_, _) => phase > PrintPhase::Base,
+ // Precedence is magically handled by the ordering of BinOps.
+ ExprKind::BinOp(op, _, _) => phase > PrintPhase::BinOp(*op),
+ ExprKind::App(_, _) => phase > PrintPhase::App,
+ Field(_, _) | Projection(_, _) | ProjectionByExpr(_, _) => {
+ phase > PrintPhase::Import
+ }
+ _ => false,
+ };
+
+ if needs_paren {
+ f.write_str("(")?;
+ }
+ self.annotate_with_phases().fmt(f)?;
+ if needs_paren {
+ f.write_str(")")?;
+ }
+
+ Ok(())
+ }
+}
+
+fn fmt_list<T, I, F>(
+ open: &str,
+ sep: &str,
+ close: &str,
+ it: I,
+ f: &mut fmt::Formatter,
+ func: F,
+) -> Result<(), fmt::Error>
+where
+ I: IntoIterator<Item = T>,
+ F: Fn(T, &mut fmt::Formatter) -> Result<(), fmt::Error>,
+{
+ f.write_str(open)?;
+ for (i, x) in it.into_iter().enumerate() {
+ if i > 0 {
+ f.write_str(sep)?;
+ }
+ func(x, f)?;
+ }
+ f.write_str(close)
+}
+
/// Generic instance that delegates to subexpressions
-impl<SE: Display + Clone, E: Display> Display for ExprF<SE, E> {
+impl<SE: Display + Clone, E: Display> Display for ExprKind<SE, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- use crate::syntax::ExprF::*;
+ use crate::syntax::ExprKind::*;
match self {
Lam(a, b, c) => {
write!(f, "λ({} : {}) → {}", a, b, c)?;
@@ -53,10 +180,10 @@ impl<SE: Display + Clone, E: Display> Display for ExprF<SE, E> {
Assert(a) => {
write!(f, "assert : {}", a)?;
}
- ExprF::BinOp(op, a, b) => {
+ ExprKind::BinOp(op, a, b) => {
write!(f, "{} {} {}", a, op, b)?;
}
- ExprF::App(a, b) => {
+ ExprKind::App(a, b) => {
write!(f, "{} {}", a, b)?;
}
Field(a, b) => {
@@ -104,147 +231,16 @@ impl<SE: Display + Clone, E: Display> Display for ExprF<SE, E> {
}
}
-// There is a one-to-one correspondence between the formatter and the grammar. Each phase is
-// named after a corresponding grammar group, and the structure of the formatter reflects
-// the relationship between the corresponding grammar rules. This leads to the nice property
-// of automatically getting all the parentheses and precedences right.
-#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
-enum PrintPhase {
- Base,
- Operator,
- BinOp(core::BinOp),
- App,
- Import,
- Primitive,
-}
-
-// Wraps an Expr with a phase, so that phase selsction can be done
-// separate from the actual printing
-#[derive(Clone)]
-struct PhasedExpr<'a, A>(&'a Expr<A>, PrintPhase);
-
-impl<'a, A: Display + Clone> Display for PhasedExpr<'a, A> {
- fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- self.0.as_ref().fmt_phase(f, self.1)
- }
-}
-
-impl<'a, A: Display + Clone> PhasedExpr<'a, A> {
- fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, A> {
- PhasedExpr(self.0, phase)
- }
-}
-
-impl<A: Display + Clone> RawExpr<A> {
- fn fmt_phase(
- &self,
- f: &mut fmt::Formatter,
- phase: PrintPhase,
- ) -> Result<(), fmt::Error> {
- use crate::syntax::ExprF::*;
- use PrintPhase::*;
-
- let needs_paren = match self {
- Lam(_, _, _)
- | BoolIf(_, _, _)
- | Pi(_, _, _)
- | Let(_, _, _, _)
- | EmptyListLit(_)
- | NEListLit(_)
- | SomeLit(_)
- | Merge(_, _, _)
- | ToMap(_, _)
- | Annot(_, _)
- if phase > Base =>
- {
- true
- }
- // Precedence is magically handled by the ordering of BinOps.
- ExprF::BinOp(op, _, _) if phase > PrintPhase::BinOp(*op) => true,
- ExprF::App(_, _) if phase > PrintPhase::App => true,
- Field(_, _) | Projection(_, _) | ProjectionByExpr(_, _)
- if phase > PrintPhase::Import =>
- {
- true
- }
- _ => false,
- };
-
- // Annotate subexpressions with the appropriate phase, defaulting to Base
- let phased_self = match self.map_ref(|e| PhasedExpr(e, Base)) {
- Pi(a, b, c) => {
- if &String::from(&a) == "_" {
- Pi(a, b.phase(Operator), c)
- } else {
- Pi(a, b, c)
- }
- }
- Merge(a, b, c) => Merge(
- a.phase(PrintPhase::Import),
- b.phase(PrintPhase::Import),
- c.map(|x| x.phase(PrintPhase::App)),
- ),
- ToMap(a, b) => ToMap(
- a.phase(PrintPhase::Import),
- b.map(|x| x.phase(PrintPhase::App)),
- ),
- Annot(a, b) => Annot(a.phase(Operator), b),
- ExprF::BinOp(op, a, b) => ExprF::BinOp(
- op,
- a.phase(PrintPhase::BinOp(op)),
- b.phase(PrintPhase::BinOp(op)),
- ),
- SomeLit(e) => SomeLit(e.phase(PrintPhase::Import)),
- ExprF::App(f, a) => ExprF::App(
- f.phase(PrintPhase::Import),
- a.phase(PrintPhase::Import),
- ),
- Field(a, b) => Field(a.phase(Primitive), b),
- Projection(e, ls) => Projection(e.phase(Primitive), ls),
- ProjectionByExpr(a, b) => ProjectionByExpr(a.phase(Primitive), b),
- e => e,
- };
-
- if needs_paren {
- f.write_str("(")?;
- }
-
- // Uses the ExprF<PhasedExpr<_>, _> instance
- phased_self.fmt(f)?;
-
- if needs_paren {
- f.write_str(")")?;
- }
- Ok(())
- }
-}
-
-impl<A: Display + Clone> Display for Expr<A> {
+impl<E: Display + Clone> Display for Expr<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.as_ref().fmt_phase(f, PrintPhase::Base)
}
}
-fn fmt_list<T, I, F>(
- open: &str,
- sep: &str,
- close: &str,
- it: I,
- f: &mut fmt::Formatter,
- func: F,
-) -> Result<(), fmt::Error>
-where
- I: IntoIterator<Item = T>,
- F: Fn(T, &mut fmt::Formatter) -> Result<(), fmt::Error>,
-{
- f.write_str(open)?;
- for (i, x) in it.into_iter().enumerate() {
- if i > 0 {
- f.write_str(sep)?;
- }
- func(x, f)?;
+impl<'a, E: Display + Clone> Display for PhasedExpr<'a, E> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ self.0.as_ref().fmt_phase(f, self.1)
}
- f.write_str(close)
}
impl<SubExpr: Display> Display for InterpolatedText<SubExpr> {
@@ -361,6 +357,7 @@ impl Display for Hash {
}
}
}
+
impl<SubExpr: Display> Display for Import<SubExpr> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use FilePrefix::*;