diff options
| author | Nadrieril | 2019-03-09 14:32:07 +0100 | 
|---|---|---|
| committer | Nadrieril | 2019-03-09 14:32:07 +0100 | 
| commit | e27adcdce55dc15c97bb0ac6d5bc0b082d2232c2 (patch) | |
| tree | 0b9580165db1bde863bc4cff619593fbce5bf4c3 /dhall_core | |
| parent | d8b69acc45334743c848a3d8b7689729d89eaf3a (diff) | |
Use new Label type instead of &str in parser
Diffstat (limited to 'dhall_core')
| -rw-r--r-- | dhall_core/src/core.rs | 57 | ||||
| -rw-r--r-- | dhall_core/src/grammar_util.rs | 4 | ||||
| -rw-r--r-- | dhall_core/src/lib.rs | 1 | ||||
| -rw-r--r-- | dhall_core/src/parser.rs | 104 | 
4 files changed, 105 insertions, 61 deletions
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index eed9e0c..7bd1318 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -68,6 +68,41 @@ pub struct Import {      pub hash: Option<()>,  } +// The type for labels throughout the AST +// It owns the data because otherwise lifetimes would make recursive imports impossible +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Label(String); + +impl From<String> for Label { +    fn from(s: String) -> Self { +        Label(s) +    } +} + +impl From<&'static str> for Label { +    fn from(s: &'static str) -> Self { +        Label(s.to_owned()) +    } +} + +impl From<Label> for String { +    fn from(x: Label) -> String { +        x.0 +    } +} + +impl Display for Label { +    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { +        self.0.fmt(f) +    } +} + +impl Label { +    pub fn from_str<'a>(s: &'a str) -> Label { +        s.to_owned().into() +    } +} +  /// Label for a bound variable  ///  /// The `String` field is the variable's name (i.e. \"`x`\"). @@ -268,7 +303,6 @@ pub trait StringLike:      + Hash      + Ord      + Eq -    + Default      + Into<String>      + From<String>      + From<&'static str> @@ -282,7 +316,6 @@ impl<T> StringLike for T where          + Hash          + Ord          + Eq -        + Default          + Into<String>          + From<String>          + From<&'static str> @@ -340,6 +373,18 @@ impl<Label: StringLike, S, A> Expr<Label, S, A> {          self.map_shallow(recurse, |x| x.clone(), map_embed, |x| x.clone())      } +    pub fn map_label<L2: StringLike, F>(&self, map_label: &F) -> Expr<L2, S, A> +    where +        A: Clone, +        S: Clone, +        F: Fn(&Label) -> L2, +    { +        let recurse = |e: &Expr<Label, S, A>| -> Expr<L2, S, A> { +            e.map_label(map_label) +        }; +        self.map_shallow(recurse, |x| x.clone(), |x| x.clone(), map_label) +    } +      pub fn bool_lit(&self) -> Option<bool> {          match *self {              Expr::BoolLit(v) => Some(v), @@ -362,11 +407,11 @@ impl<Label: StringLike, S, A> Expr<Label, S, A> {      }  } -impl<'i, S: Clone, A: Clone> Expr<&'i str, S, A> { -    pub fn take_ownership_of_labels<L: StringLike + From<String>>( +impl<S: Clone, A: Clone> Expr<&'static str, S, A> { +    pub fn take_ownership_of_labels<L: StringLike>(          &self,      ) -> Expr<L, S, A> { -        let recurse = |e: &Expr<&'i str, S, A>| -> Expr<L, S, A> { +        let recurse = |e: &Expr<&'static str, S, A>| -> Expr<L, S, A> {              e.take_ownership_of_labels()          };          map_shallow( @@ -787,7 +832,7 @@ where      S: Clone,      T: Clone,      Label1: -        Display + fmt::Debug + Clone + Hash + Ord + Eq + Into<String> + Default, +        Display + fmt::Debug + Clone + Hash + Ord + Eq + Into<String>,      Label2: StringLike,      F1: Fn(&Expr<Label1, S, A>) -> Expr<Label2, T, B>,      F2: FnOnce(&S) -> T, diff --git a/dhall_core/src/grammar_util.rs b/dhall_core/src/grammar_util.rs deleted file mode 100644 index 2547e94..0000000 --- a/dhall_core/src/grammar_util.rs +++ /dev/null @@ -1,4 +0,0 @@ -use crate::core::{Expr, Import, X}; - -pub type ParsedExpr<'i> = Expr<&'i str, X, Import>; -pub type BoxExpr<'i> = Box<ParsedExpr<'i>>; diff --git a/dhall_core/src/lib.rs b/dhall_core/src/lib.rs index bd53603..386d6bc 100644 --- a/dhall_core/src/lib.rs +++ b/dhall_core/src/lib.rs @@ -4,5 +4,4 @@  pub mod core;  pub use crate::core::*;  pub mod context; -mod grammar_util;  pub mod parser; diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index 0ba1586..7073a93 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -7,7 +7,9 @@ use dhall_parser::{DhallParser, Rule};  use crate::core;  use crate::core::*; -use crate::grammar_util::{BoxExpr, ParsedExpr}; + +pub type ParsedExpr = Expr<Label, X, Import>; +pub type BoxExpr = Box<ParsedExpr>;  pub type ParseError = pest::error::Error<Rule>; @@ -418,6 +420,8 @@ named!(str<&'a str>; captured_str!(s) => s.trim());  named!(raw_str<&'a str>; captured_str!(s) => s); +named!(label<Label>; captured_str!(s) => Label::from(s.trim().to_owned())); +  // TODO: parse escapes and interpolation  rule!(double_quote_literal<String>;      children!(strs*: raw_str) => { @@ -537,7 +541,7 @@ rule!(import_hashed_raw<(ImportLocation, Option<()>)>;      }  ); -rule!(import_raw<BoxExpr<'a>>; +rule!(import_raw<BoxExpr>;      // TODO: handle "as Text"      children!(import: import_hashed_raw) => {          let (location, hash) = import; @@ -549,7 +553,7 @@ rule!(import_raw<BoxExpr<'a>>;      }  ); -rule_group!(expression<BoxExpr<'a>>; +rule_group!(expression<BoxExpr>;      identifier_raw,      lambda_expression,      ifthenelse_expression, @@ -586,47 +590,47 @@ rule_group!(expression<BoxExpr<'a>>;      final_expression  ); -rule!(lambda_expression<BoxExpr<'a>>; -    children!(label: str, typ: expression, body: expression) => { -        bx(Expr::Lam(label, typ, body)) +rule!(lambda_expression<BoxExpr>; +    children!(l: label, typ: expression, body: expression) => { +        bx(Expr::Lam(l, typ, body))      }  ); -rule!(ifthenelse_expression<BoxExpr<'a>>; +rule!(ifthenelse_expression<BoxExpr>;      children!(cond: expression, left: expression, right: expression) => {          bx(Expr::BoolIf(cond, left, right))      }  ); -rule!(let_expression<BoxExpr<'a>>; +rule!(let_expression<BoxExpr>;      children!(bindings*: let_binding, final_expr: expression) => {          bindings.fold(final_expr, |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc)))      }  ); -rule!(let_binding<(&'a str, Option<BoxExpr<'a>>, BoxExpr<'a>)>; -    children!(name: str, annot?: expression, expr: expression) => (name, annot, expr) +rule!(let_binding<(Label, Option<BoxExpr>, BoxExpr)>; +    children!(name: label, annot?: expression, expr: expression) => (name, annot, expr)  ); -rule!(forall_expression<BoxExpr<'a>>; -    children!(label: str, typ: expression, body: expression) => { -        bx(Expr::Pi(label, typ, body)) +rule!(forall_expression<BoxExpr>; +    children!(l: label, typ: expression, body: expression) => { +        bx(Expr::Pi(l, typ, body))      }  ); -rule!(arrow_expression<BoxExpr<'a>>; +rule!(arrow_expression<BoxExpr>;      children!(typ: expression, body: expression) => { -        bx(Expr::Pi("_", typ, body)) +        bx(Expr::Pi("_".into(), typ, body))      }  ); -rule!(merge_expression<BoxExpr<'a>>; +rule!(merge_expression<BoxExpr>;      children!(x: expression, y: expression, z?: expression) => {          bx(Expr::Merge(x, y, z))      }  ); -rule!(empty_collection<BoxExpr<'a>>; +rule!(empty_collection<BoxExpr>;      children!(x: str, y: expression) => {         match x {            "Optional" => bx(Expr::OptionalLit(Some(y), vec![])), @@ -636,7 +640,7 @@ rule!(empty_collection<BoxExpr<'a>>;      }  ); -rule!(non_empty_optional<BoxExpr<'a>>; +rule!(non_empty_optional<BoxExpr>;      children!(x: expression, _y: str, z: expression) => {          bx(Expr::OptionalLit(Some(z), vec![*x]))      } @@ -644,7 +648,7 @@ rule!(non_empty_optional<BoxExpr<'a>>;  macro_rules! binop {      ($rule:ident, $op:ident) => { -        rule!($rule<BoxExpr<'a>>; +        rule!($rule<BoxExpr>;              children!(first: expression, rest*: expression) => {                  rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::$op, acc, e)))              } @@ -652,7 +656,7 @@ macro_rules! binop {      };  } -rule!(annotated_expression<BoxExpr<'a>>; +rule!(annotated_expression<BoxExpr>;      children!(e: expression, annot: expression) => {          bx(Expr::Annot(e, annot))      }, @@ -672,19 +676,19 @@ binop!(times_expression, NaturalTimes);  binop!(equal_expression, BoolEQ);  binop!(not_equal_expression, BoolNE); -rule!(application_expression<BoxExpr<'a>>; +rule!(application_expression<BoxExpr>;      children!(first: expression, rest*: expression) => {          rest.fold(first, |acc, e| bx(Expr::App(acc, e)))      }  ); -rule!(selector_expression_raw<BoxExpr<'a>>; -    children!(first: expression, rest*: str) => { +rule!(selector_expression_raw<BoxExpr>; +    children!(first: expression, rest*: label) => {          rest.fold(first, |acc, e| bx(Expr::Field(acc, e)))      }  ); -rule!(literal_expression_raw<BoxExpr<'a>>; +rule!(literal_expression_raw<BoxExpr>;      children!(n: double_literal_raw) => bx(Expr::DoubleLit(n)),      children!(n: minus_infinity_literal) => bx(Expr::DoubleLit(std::f64::NEG_INFINITY)),      children!(n: plus_infinity_literal) => bx(Expr::DoubleLit(std::f64::INFINITY)), @@ -696,7 +700,7 @@ rule!(literal_expression_raw<BoxExpr<'a>>;      children!(e: expression) => e,  ); -rule!(identifier_raw<BoxExpr<'a>>; +rule!(identifier_raw<BoxExpr>;      children!(name: str, idx?: natural_literal_raw) => {          match Builtin::parse(name) {              Some(b) => bx(Expr::Builtin(b)), @@ -705,40 +709,40 @@ rule!(identifier_raw<BoxExpr<'a>>;                  "False" => bx(Expr::BoolLit(false)),                  "Type" => bx(Expr::Const(Const::Type)),                  "Kind" => bx(Expr::Const(Const::Kind)), -                name => bx(Expr::Var(V(name, idx.unwrap_or(0)))), +                name => bx(Expr::Var(V(Label::from(name.to_owned()), idx.unwrap_or(0)))),              }          }      }  ); -rule!(empty_record_literal<BoxExpr<'a>>; +rule!(empty_record_literal<BoxExpr>;      children!() => bx(Expr::RecordLit(BTreeMap::new()))  ); -rule!(empty_record_type<BoxExpr<'a>>; +rule!(empty_record_type<BoxExpr>;      children!() => bx(Expr::Record(BTreeMap::new()))  ); -rule!(non_empty_record_type_or_literal<BoxExpr<'a>>; -    children!(first_label: str, rest: non_empty_record_type) => { +rule!(non_empty_record_type_or_literal<BoxExpr>; +    children!(first_label: label, rest: non_empty_record_type) => {          let (first_expr, mut map) = rest;          map.insert(first_label, *first_expr);          bx(Expr::Record(map))      }, -    children!(first_label: str, rest: non_empty_record_literal) => { +    children!(first_label: label, rest: non_empty_record_literal) => {          let (first_expr, mut map) = rest;          map.insert(first_label, *first_expr);          bx(Expr::RecordLit(map))      },  ); -rule!(non_empty_record_type<(BoxExpr<'a>, BTreeMap<&'a str, ParsedExpr<'a>>)>; +rule!(non_empty_record_type<(BoxExpr, BTreeMap<Label, ParsedExpr>)>;      self!(x: partial_record_entries) => x  ); -named!(partial_record_entries<(BoxExpr<'a>, BTreeMap<&'a str, ParsedExpr<'a>>)>; +named!(partial_record_entries<(BoxExpr, BTreeMap<Label, ParsedExpr>)>;      children!(expr: expression, entries*: record_entry) => { -        let mut map: BTreeMap<&str, ParsedExpr> = BTreeMap::new(); +        let mut map: BTreeMap<Label, ParsedExpr> = BTreeMap::new();          for (n, e) in entries {              map.insert(n, *e);          } @@ -746,15 +750,15 @@ named!(partial_record_entries<(BoxExpr<'a>, BTreeMap<&'a str, ParsedExpr<'a>>)>;      }  ); -named!(record_entry<(&'a str, BoxExpr<'a>)>; -    children!(name: str, expr: expression) => (name, expr) +named!(record_entry<(Label, BoxExpr)>; +    children!(name: label, expr: expression) => (name, expr)  ); -rule!(non_empty_record_literal<(BoxExpr<'a>, BTreeMap<&'a str, ParsedExpr<'a>>)>; +rule!(non_empty_record_literal<(BoxExpr, BTreeMap<Label, ParsedExpr>)>;      self!(x: partial_record_entries) => x  ); -rule!(union_type_or_literal<BoxExpr<'a>>; +rule!(union_type_or_literal<BoxExpr>;      children!(_e: empty_union_type) => {          bx(Expr::Union(BTreeMap::new()))      }, @@ -769,25 +773,25 @@ rule!(union_type_or_literal<BoxExpr<'a>>;  rule!(empty_union_type<()>; children!() => ());  rule!(non_empty_union_type_or_literal -      <(Option<(&'a str, BoxExpr<'a>)>, BTreeMap<&'a str, ParsedExpr<'a>>)>; -    children!(label: str, e: expression, entries: union_type_entries) => { -        (Some((label, e)), entries) +      <(Option<(Label, BoxExpr)>, BTreeMap<Label, ParsedExpr>)>; +    children!(l: label, e: expression, entries: union_type_entries) => { +        (Some((l, e)), entries)      }, -    children!(l: str, e: expression, rest: non_empty_union_type_or_literal) => { +    children!(l: label, e: expression, rest: non_empty_union_type_or_literal) => {          let (x, mut entries) = rest;          entries.insert(l, *e);          (x, entries)      }, -    children!(l: str, e: expression) => { +    children!(l: label, e: expression) => {          let mut entries = BTreeMap::new();          entries.insert(l, *e);          (None, entries)      },  ); -rule!(union_type_entries<BTreeMap<&'a str, ParsedExpr<'a>>>; +rule!(union_type_entries<BTreeMap<Label, ParsedExpr>>;      children!(entries*: union_type_entry) => { -        let mut map: BTreeMap<&str, ParsedExpr> = BTreeMap::new(); +        let mut map: BTreeMap<Label, ParsedExpr> = BTreeMap::new();          for (n, e) in entries {              map.insert(n, *e);          } @@ -795,21 +799,21 @@ rule!(union_type_entries<BTreeMap<&'a str, ParsedExpr<'a>>>;      }  ); -rule!(union_type_entry<(&'a str, BoxExpr<'a>)>; -    children!(name: str, expr: expression) => (name, expr) +rule!(union_type_entry<(Label, BoxExpr)>; +    children!(name: label, expr: expression) => (name, expr)  ); -rule!(non_empty_list_literal_raw<BoxExpr<'a>>; +rule!(non_empty_list_literal_raw<BoxExpr>;      children!(items*: expression) => {          bx(Expr::ListLit(None, items.map(|x| *x).collect()))      }  ); -rule!(final_expression<BoxExpr<'a>>; +rule!(final_expression<BoxExpr>;      children!(e: expression, _eoi: EOI) => e  ); -pub fn parse_expr<'i>(s: &'i str) -> ParseResult<BoxExpr<'i>> { +pub fn parse_expr<'i>(s: &'i str) -> ParseResult<BoxExpr> {      let pairs = DhallParser::parse(Rule::final_expression, s)?;      // Match the only item in the pairs iterator      match_iter!(@panic; pairs; (p) => expression(p))  | 
