From 45be2ff1f5bb3d6e0faa098402adf985b3d5e7ca Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 4 May 2019 12:38:36 +0200 Subject: Rename dhall_core to dhall_syntax --- dhall_core/src/printer.rs | 498 ---------------------------------------------- 1 file changed, 498 deletions(-) delete mode 100644 dhall_core/src/printer.rs (limited to 'dhall_core/src/printer.rs') diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs deleted file mode 100644 index 704000a..0000000 --- a/dhall_core/src/printer.rs +++ /dev/null @@ -1,498 +0,0 @@ -use crate::*; -use itertools::Itertools; -use std::fmt::{self, Display}; - -/// Generic instance that delegates to subexpressions -impl Display for ExprF { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use crate::ExprF::*; - match self { - Lam(a, b, c) => { - write!(f, "λ({} : {}) → {}", a, b, c)?; - } - BoolIf(a, b, c) => { - write!(f, "if {} then {} else {}", a, b, c)?; - } - Pi(a, b, c) if &String::from(a) == "_" => { - write!(f, "{} → {}", b, c)?; - } - Pi(a, b, c) => { - write!(f, "∀({} : {}) → {}", a, b, c)?; - } - Let(a, b, c, d) => { - write!(f, "let {}", a)?; - if let Some(b) = b { - write!(f, " : {}", b)?; - } - write!(f, " = {} in {}", c, d)?; - } - EmptyListLit(t) => { - write!(f, "[] : List {}", t)?; - } - NEListLit(es) => { - fmt_list("[", ", ", "]", es, f, Display::fmt)?; - } - OldOptionalLit(None, t) => { - write!(f, "[] : Optional {}", t)?; - } - OldOptionalLit(Some(x), t) => { - write!(f, "[{}] : Optional {}", x, t)?; - } - SomeLit(e) => { - write!(f, "Some {}", e)?; - } - Merge(a, b, c) => { - write!(f, "merge {} {}", a, b)?; - if let Some(c) = c { - write!(f, " : {}", c)?; - } - } - Annot(a, b) => { - write!(f, "{} : {}", a, b)?; - } - ExprF::BinOp(op, a, b) => { - write!(f, "{} {} {}", a, op, b)?; - } - ExprF::App(a, b) => { - write!(f, "{} {}", a, b)?; - } - Field(a, b) => { - write!(f, "{}.{}", a, b)?; - } - Projection(e, ls) => { - write!(f, "{}.", e)?; - fmt_list("{ ", ", ", " }", ls, f, Display::fmt)?; - } - 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)?, - TextLit(a) => a.fmt(f)?, - RecordType(a) if a.is_empty() => f.write_str("{}")?, - RecordType(a) => fmt_list("{ ", ", ", " }", a, f, |(k, t), f| { - write!(f, "{} : {}", k, t) - })?, - RecordLit(a) if a.is_empty() => f.write_str("{=}")?, - RecordLit(a) => fmt_list("{ ", ", ", " }", a, f, |(k, v), f| { - write!(f, "{} = {}", k, v) - })?, - UnionType(a) => fmt_list("< ", " | ", " >", a, f, |(k, v), f| { - write!(f, "{}", k)?; - if let Some(v) = v { - write!(f, ": {}", v)?; - } - Ok(()) - })?, - UnionLit(a, b, c) => { - write!(f, "< {} = {}", a, b)?; - for (k, v) in c { - write!(f, " | {}", k)?; - if let Some(v) = v { - write!(f, ": {}", v)?; - } - } - f.write_str(" >")? - } - Embed(a) => a.fmt(f)?, - Note(_, b) => b.fmt(f)?, - } - Ok(()) - } -} - -// 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, S, A>(&'a SubExpr, PrintPhase); - -impl<'a, S: Clone, A: Display + Clone> Display for PhasedExpr<'a, S, A> { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.0.as_ref().fmt_phase(f, self.1) - } -} - -impl<'a, S: Clone, A: Display + Clone> PhasedExpr<'a, S, A> { - fn phase(self, phase: PrintPhase) -> PhasedExpr<'a, S, A> { - PhasedExpr(self.0, phase) - } -} - -impl Expr { - fn fmt_phase( - &self, - f: &mut fmt::Formatter, - mut phase: PrintPhase, - ) -> Result<(), fmt::Error> { - use crate::ExprF::*; - use PrintPhase::*; - - let needs_paren = match self { - Lam(_, _, _) - | BoolIf(_, _, _) - | Pi(_, _, _) - | Let(_, _, _, _) - | EmptyListLit(_) - | NEListLit(_) - | OldOptionalLit(_, _) - | SomeLit(_) - | Merge(_, _, _) - | 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(_, _) if phase > Import => true, - _ => false, - }; - - if needs_paren { - phase = Base; - } - - // Annotate subexpressions with the appropriate phase, defaulting to Base - let phased_self = match self.map_ref_simple(|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(Import), - b.phase(Import), - c.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)), - ), - EmptyListLit(t) => EmptyListLit(t.phase(Import)), - OldOptionalLit(x, t) => OldOptionalLit(x, t.phase(Import)), - SomeLit(e) => SomeLit(e.phase(Import)), - ExprF::App(f, a) => ExprF::App(f.phase(Import), a.phase(Import)), - Field(a, b) => Field(a.phase(Primitive), b), - Projection(e, ls) => Projection(e.phase(Primitive), ls), - Note(n, b) => Note(n, b.phase(phase)), - e => e, - }; - - if needs_paren { - f.write_str("(")?; - } - - // Uses the ExprF, _, _, _> instance - phased_self.fmt(f)?; - - if needs_paren { - f.write_str(")")?; - } - Ok(()) - } -} - -impl Display for SubExpr { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.as_ref().fmt_phase(f, PrintPhase::Base) - } -} - -fn fmt_list( - open: &str, - sep: &str, - close: &str, - it: I, - f: &mut fmt::Formatter, - func: F, -) -> Result<(), fmt::Error> -where - I: IntoIterator, - 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) -} - -impl Display for InterpolatedText { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - f.write_str("\"")?; - for x in self.iter() { - match x { - InterpolatedTextContents::Text(a) => { - for c in a.chars() { - match c { - '\\' => f.write_str("\\\\"), - '"' => f.write_str("\\\""), - '$' => f.write_str("\\$"), - '\u{0008}' => f.write_str("\\b"), - '\u{000C}' => f.write_str("\\f"), - '\n' => f.write_str("\\n"), - '\r' => f.write_str("\\r"), - '\t' => f.write_str("\\t"), - c => write!(f, "{}", c), - }?; - } - } - InterpolatedTextContents::Expr(e) => { - f.write_str("${ ")?; - e.fmt(f)?; - f.write_str(" }")?; - } - } - } - f.write_str("\"")?; - Ok(()) - } -} - -impl Display for Const { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - ::fmt(self, f) - } -} - -impl Display for BinOp { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use crate::BinOp::*; - f.write_str(match self { - BoolOr => "||", - TextAppend => "++", - NaturalPlus => "+", - BoolAnd => "&&", - Combine => "/\\", - NaturalTimes => "*", - BoolEQ => "==", - BoolNE => "!=", - CombineTypes => "//\\\\", - ImportAlt => "?", - Prefer => "//", - ListAppend => "#", - }) - } -} - -impl Display for NaiveDouble { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - let v = f64::from(*self); - if v == std::f64::INFINITY { - f.write_str("Infinity") - } else if v == std::f64::NEG_INFINITY { - f.write_str("-Infinity") - } else if v.is_nan() { - f.write_str("NaN") - } else { - let s = format!("{}", v); - if s.contains('e') || s.contains('.') { - f.write_str(&s) - } else { - write!(f, "{}.0", s) - } - } - } -} - -impl Display for Label { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - // TODO: distinguish between reserved and nonreserved locations for quoting builtins - let s = String::from(self); - let is_reserved = match s.as_str() { - "let" | "in" | "if" | "then" | "else" | "Type" | "Kind" - | "Sort" | "True" | "False" => true, - _ => crate::Builtin::parse(&s).is_some(), - }; - if !is_reserved && s.chars().all(|c| c.is_ascii_alphanumeric()) { - write!(f, "{}", s) - } else { - write!(f, "`{}`", s) - } - } -} - -impl Display for Hash { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "{}:{}", self.protocol, self.hash) - } -} -impl Display for ImportHashed { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use std::path::PathBuf; - use FilePrefix::*; - use ImportLocation::*; - let quoted_path_component = |s: &str| -> String { - if s.chars().all(|c| c.is_ascii_alphanumeric()) { - s.to_owned() - } else { - format!("\"{}\"", s) - } - }; - let fmt_path = |f: &mut fmt::Formatter, p: &PathBuf| { - let res: String = p - .iter() - .map(|c| quoted_path_component(c.to_string_lossy().as_ref())) - .join("/"); - f.write_str(&res) - }; - - match &self.location { - Local(prefix, path) => { - let prefix = match prefix { - Here => ".", - Parent => "..", - Home => "~", - Absolute => "", - }; - write!(f, "{}/", prefix)?; - fmt_path(f, path)?; - } - Remote(url) => { - write!(f, "{}://{}/", url.scheme, url.authority,)?; - fmt_path(f, &url.path)?; - if let Some(q) = &url.query { - write!(f, "?{}", q)? - } - if let Some(h) = &url.headers { - write!(f, " using ({})", h)? - } - } - Env(s) => { - write!(f, "env:")?; - if s.chars().all(|c| c.is_ascii_alphanumeric()) { - write!(f, "{}", s)?; - } else { - write!(f, "\"")?; - for c in s.chars() { - match c { - '"' => f.write_str("\\\"")?, - '\\' => f.write_str("\\\\")?, - '\u{0007}' => f.write_str("\\a")?, - '\u{0008}' => f.write_str("\\b")?, - '\u{000C}' => f.write_str("\\f")?, - '\n' => f.write_str("\\n")?, - '\r' => f.write_str("\\r")?, - '\t' => f.write_str("\\t")?, - '\u{000B}' => f.write_str("\\v")?, - _ => write!(f, "{}", c)?, - } - } - write!(f, "\"")?; - } - } - Missing => { - write!(f, "missing")?; - } - } - if let Some(hash) = &self.hash { - write!(f, " ")?; - hash.fmt(f)?; - } - Ok(()) - } -} - -impl Display for Import { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.location_hashed.fmt(f)?; - use ImportMode::*; - match self.mode { - Code => {} - RawText => write!(f, " as Text")?, - } - Ok(()) - } -} - -impl Display for Builtin { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use crate::Builtin::*; - f.write_str(match *self { - Bool => "Bool", - Natural => "Natural", - Integer => "Integer", - Double => "Double", - Text => "Text", - List => "List", - Optional => "Optional", - OptionalNone => "None", - NaturalBuild => "Natural/build", - NaturalFold => "Natural/fold", - NaturalIsZero => "Natural/isZero", - NaturalEven => "Natural/even", - NaturalOdd => "Natural/odd", - NaturalToInteger => "Natural/toInteger", - NaturalShow => "Natural/show", - IntegerToDouble => "Integer/toDouble", - IntegerShow => "Integer/show", - DoubleShow => "Double/show", - ListBuild => "List/build", - ListFold => "List/fold", - ListLength => "List/length", - ListHead => "List/head", - ListLast => "List/last", - ListIndexed => "List/indexed", - ListReverse => "List/reverse", - OptionalFold => "Optional/fold", - OptionalBuild => "Optional/build", - TextShow => "Text/show", - }) - } -} - -impl Display for Scheme { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use crate::Scheme::*; - f.write_str(match *self { - HTTP => "http", - HTTPS => "https", - }) - } -} - -impl Display for V