diff options
-rw-r--r-- | Cargo.lock | 19 | ||||
-rw-r--r-- | abnf_to_pest/Cargo.toml | 11 | ||||
-rw-r--r-- | abnf_to_pest/README.md | 22 | ||||
-rw-r--r-- | abnf_to_pest/src/lib.rs | 35 | ||||
-rw-r--r-- | dhall/src/binary.rs | 4 | ||||
-rw-r--r-- | dhall/src/normalize.rs | 2 | ||||
-rw-r--r-- | dhall/src/tests.rs | 2 | ||||
-rw-r--r-- | dhall/src/typecheck.rs | 14 | ||||
-rw-r--r-- | dhall_core/src/core.rs | 4 | ||||
-rw-r--r-- | dhall_core/src/parser.rs | 8 | ||||
-rw-r--r-- | dhall_core/src/printer.rs | 8 | ||||
-rw-r--r-- | dhall_core/src/visitor.rs | 4 |
12 files changed, 109 insertions, 24 deletions
@@ -2,17 +2,18 @@ # It is not intended for manual editing. [[package]] name = "abnf" -version = "0.1.1" -source = "git+https://github.com/Nadrieril/abnf#aaa09ce40f5356daec5618b358be1c8b6e9b05d8" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "abnf_to_pest" -version = "0.1.0" +version = "0.1.1" dependencies = [ - "abnf 0.1.1 (git+https://github.com/Nadrieril/abnf)", + "abnf 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -92,7 +93,7 @@ dependencies = [ name = "dhall_generated_parser" version = "0.1.0" dependencies = [ - "abnf_to_pest 0.1.0", + "abnf_to_pest 0.1.1", "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -150,6 +151,11 @@ name = "improved_slice_patterns" version = "1.0.1" [[package]] +name = "indexmap" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "itertools" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -405,7 +411,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] -"checksum abnf 0.1.1 (git+https://github.com/Nadrieril/abnf)" = "<none>" +"checksum abnf 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3cd52ccec58f8b39e3b25620953fd8dfbdcf932b50907b29d577cf1dd12477b6" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" @@ -419,6 +425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum half 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9353c2a89d550b58fa0061d8ed8d002a7d8cdf2494eb0e432859bd3a9e543836" +"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" diff --git a/abnf_to_pest/Cargo.toml b/abnf_to_pest/Cargo.toml index ff4dc01..9573c67 100644 --- a/abnf_to_pest/Cargo.toml +++ b/abnf_to_pest/Cargo.toml @@ -1,14 +1,19 @@ [package] name = "abnf_to_pest" -version = "0.1.0" +version = "0.1.1" # remember to update html_root_url authors = ["Nadrieril <nadrieril@users.noreply.github.com>"] -license = "BSD-2-Clause" +license = "MIT OR Apache-2.0" edition = "2018" +description = "A tiny crate that helps convert ABNF grammars to pest" +readme = "README.md" +repository = "https://github.com/Nadrieril/dhall-rust" +documentation = "https://docs.rs/abnf_to_pest" [lib] doctest = false [dependencies] -abnf = { git = "https://github.com/Nadrieril/abnf" } +abnf = "0.1.2" +indexmap = "1.0.2" itertools = "0.8.0" pretty = "0.5.2" diff --git a/abnf_to_pest/README.md b/abnf_to_pest/README.md new file mode 100644 index 0000000..466cf70 --- /dev/null +++ b/abnf_to_pest/README.md @@ -0,0 +1,22 @@ +# `abnf_to_pest` + +A tiny crate that helps convert ABNF grammars to [pest][pest]. + +[pest]: https://pest.rs + +## License + +Licensed under either of + + * Apache License, Version 2.0 + (http://www.apache.org/licenses/LICENSE-2.0) + * MIT license + (http://opensource.org/licenses/MIT) + +at your option. + +## Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions diff --git a/abnf_to_pest/src/lib.rs b/abnf_to_pest/src/lib.rs index 1b8fc9c..625798b 100644 --- a/abnf_to_pest/src/lib.rs +++ b/abnf_to_pest/src/lib.rs @@ -1,6 +1,25 @@ -#![allow(clippy::implicit_hasher, clippy::or_fun_call)] +#![doc(html_root_url = "https://docs.rs/abnf_to_pest/0.1.1")] //! A tiny crate that helps convert ABNF grammars to [pest][pest]. +//! +//! Example usage: +//! ``` +//! let abnf_path = "src/grammar.abnf"; +//! let pest_path = "src/grammar.pest"; +//! +//! let mut file = File::open(abnf_path)?; +//! let mut data = Vec::new(); +//! file.read_to_end(&mut data)?; +//! data.push('\n' as u8); +//! +//! let mut rules = abnf_to_pest::parse_abnf(&data)?; +//! rules.remove("some_inconvenient_rule"); +//! +//! let mut file = File::create(pest_path)?; +//! writeln!(&mut file, "{}", render_rules_to_pest(rules).pretty(80))?; +//! ``` +//! +//! [pest]: https://pest.rs use abnf::abnf::Rule; pub use abnf::abnf::{ @@ -8,7 +27,7 @@ pub use abnf::abnf::{ }; use itertools::Itertools; use pretty::{BoxDoc, Doc}; -use std::collections::HashMap; +use indexmap::map::IndexMap; trait Pretty { fn pretty(&self) -> Doc<'static, BoxDoc<'static, ()>>; @@ -40,7 +59,7 @@ impl Pretty for Repetition { self.repeat .as_ref() .map(Repeat::pretty) - .unwrap_or(Doc::nil()), + .unwrap_or_else(Doc::nil), ) } } @@ -93,6 +112,10 @@ impl Pretty for Range { } } +/// Escape the rule name to be a valid Rust identifier. +/// +/// Replaces e.g. `if` with `if_`, and `rule-name` with `rule_name`. +/// Also changes `whitespace` to `whitespace_` because of https://github.com/pest-parser/pest/pull/374 pub fn escape_rulename(x: &str) -> String { let x = x.replace("-", "_"); if x == "if" @@ -110,8 +133,8 @@ pub fn escape_rulename(x: &str) -> String { } } -fn format_char(x: usize) -> String { - if x <= usize::from(u8::max_value()) { +fn format_char(x: u32) -> String { + if x <= u32::from(u8::max_value()) { let x: u8 = x as u8; if x.is_ascii_graphic() { let x: char = x as char; @@ -146,7 +169,7 @@ impl Pretty for (String, PestyRule) { /// Parse an abnf file. Returns a map of rules. pub fn parse_abnf( data: &[u8], -) -> Result<HashMap<String, PestyRule>, std::io::Error> { +) -> Result<IndexMap<String, PestyRule>, std::io::Error> { let make_err = |e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e)); let rules: Vec<Rule> = diff --git a/dhall/src/binary.rs b/dhall/src/binary.rs index 8a23e76..72704de 100644 --- a/dhall/src/binary.rs +++ b/dhall/src/binary.rs @@ -107,7 +107,7 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> { } [U64(5), t] => { let t = cbor_value_to_dhall(&t)?; - EmptyOptionalLit(t) + OldOptionalLit(None, t) } [U64(5), Null, x] => { let x = cbor_value_to_dhall(&x)?; @@ -116,7 +116,7 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> { [U64(5), t, x] => { let x = cbor_value_to_dhall(&x)?; let t = cbor_value_to_dhall(&t)?; - Annot(rc(NEOptionalLit(x)), t) + OldOptionalLit(Some(x), t) } [U64(6), x, y] => { let x = cbor_value_to_dhall(&x)?; diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs index 716b7ee..58deb87 100644 --- a/dhall/src/normalize.rs +++ b/dhall/src/normalize.rs @@ -265,6 +265,8 @@ fn normalize_ref(expr: &Expr<X, Normalized<'static>>) -> Expr<X, X> { BoolIf(BoolLit(false), _, f) => DoneRef(f), // TODO: interpolation // TextLit(t) => + OldOptionalLit(None, t) => Done(EmptyOptionalLit(t.roll())), + OldOptionalLit(Some(x), _) => Done(NEOptionalLit(x.roll())), BinOp(BoolAnd, BoolLit(x), BoolLit(y)) => Done(BoolLit(*x && *y)), BinOp(BoolOr, BoolLit(x), BoolLit(y)) => Done(BoolLit(*x || *y)), BinOp(BoolEQ, BoolLit(x), BoolLit(y)) => Done(BoolLit(x == y)), diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index f57f23f..ce24bfc 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -124,7 +124,7 @@ pub fn run_test( let expected = parse_file_str(&expected_file_path)? .resolve()? .skip_typecheck() - .skip_normalize(); + .normalize(); match feature { Parser => unreachable!(), diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index b8f2d86..5162f4f 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -266,6 +266,9 @@ fn type_of_builtin<S>(b: Builtin) -> Expr<S, Normalized<'static>> { forall (nothing: optional) -> optional ), + OptionalNone => dhall::expr!( + forall (a: Type) -> Optional a + ), _ => panic!("Unimplemented typecheck case: {:?}", b), } } @@ -544,6 +547,17 @@ fn type_last_layer( let t = x.get_type_move()?.into_normalized()?.into_expr(); Ok(RetExpr(dhall::expr!(List t))) } + OldOptionalLit(None, t) => { + let t = t.into_expr(); + let e = dhall::subexpr!(None t); + Ok(RetType(type_with(ctx, e)?.get_type()?.into_owned())) + } + OldOptionalLit(Some(x), t) => { + let x = x.into_expr(); + let t = t.into_expr(); + let e = dhall::subexpr!(Some x : Optional t); + Ok(RetType(type_with(ctx, e)?.get_type()?.into_owned())) + } EmptyOptionalLit(t) => { let t = t.normalize().into_type(); ensure_simple_type!( diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index 7859c73..c0e04ed 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -174,6 +174,10 @@ pub enum ExprF<SubExpr, Label, Note, Embed> { EmptyListLit(SubExpr), /// [x, y, z] NEListLit(Vec<SubExpr>), + /// Deprecated Optional literal form + /// [] : Optional a + /// [x] : Optional a + OldOptionalLit(Option<SubExpr>, SubExpr), /// None t EmptyOptionalLit(SubExpr), /// Some e diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index cea7cea..c4ae2e5 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -641,13 +641,13 @@ make_parser! { spanned(span, EmptyListLit(rc(t))) }, [Optional(_), expression(t)] => { - spanned(span, EmptyOptionalLit(rc(t))) + spanned(span, OldOptionalLit(None, rc(t))) }, )); rule!(non_empty_optional<ParsedExpr<'a>> as expression; span; children!( [expression(x), Optional(_), expression(t)] => { - spanned(span, Annot(rc(NEOptionalLit(rc(x))), rc(t))) + spanned(span, OldOptionalLit(Option::Some(rc(x)), rc(t))) } )); @@ -747,10 +747,6 @@ make_parser! { rule!(application_expression<ParsedExpr<'a>> as expression; span; children!( [expression(e)] => e, - [expression(Builtin(crate::Builtin::OptionalNone)), - expression(e), expression(rest)..] => { - spanned(span, app(EmptyOptionalLit(rc(e)), rest.map(rc).collect())) - }, [Some(()), expression(e), expression(rest)..] => { spanned(span, app(NEOptionalLit(rc(e)), rest.map(rc).collect())) }, diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs index e53c1ec..bb094de 100644 --- a/dhall_core/src/printer.rs +++ b/dhall_core/src/printer.rs @@ -32,6 +32,12 @@ impl<SE: Display + Clone, N, E: Display> Display for ExprF<SE, Label, N, E> { NEListLit(es) => { fmt_list("[", ", ", "]", es, f, Display::fmt)?; } + OldOptionalLit(None, t) => { + write!(f, "[] : Optional {}", t)?; + } + OldOptionalLit(Some(x), t) => { + write!(f, "[{}] : Optional {}", x, t)?; + } EmptyOptionalLit(t) => { write!(f, "None {}", t)?; } @@ -149,6 +155,7 @@ impl<S: Clone, A: Display + Clone> Expr<S, A> { | Let(_, _, _, _) | EmptyListLit(_) | NEListLit(_) + | OldOptionalLit(_, _) | EmptyOptionalLit(_) | NEOptionalLit(_) | Merge(_, _, _) @@ -189,6 +196,7 @@ impl<S: Clone, A: Display + Clone> Expr<S, A> { b.phase(PrintPhase::BinOp(op)), ), EmptyListLit(t) => EmptyListLit(t.phase(Import)), + OldOptionalLit(x, t) => OldOptionalLit(x, t.phase(Import)), EmptyOptionalLit(t) => EmptyOptionalLit(t.phase(Import)), NEOptionalLit(e) => NEOptionalLit(e.phase(Import)), ExprF::App(a, args) => ExprF::App( diff --git a/dhall_core/src/visitor.rs b/dhall_core/src/visitor.rs index b0424ac..3b06f8b 100644 --- a/dhall_core/src/visitor.rs +++ b/dhall_core/src/visitor.rs @@ -148,6 +148,10 @@ where ), EmptyListLit(t) => EmptyListLit(v.visit_subexpr(t)?), NEListLit(es) => NEListLit(vec(es, |e| v.visit_subexpr(e))?), + OldOptionalLit(x, t) => OldOptionalLit( + opt(x, |e| v.visit_subexpr(e))?, + v.visit_subexpr(t)?, + ), EmptyOptionalLit(t) => EmptyOptionalLit(v.visit_subexpr(t)?), NEOptionalLit(e) => NEOptionalLit(v.visit_subexpr(e)?), RecordType(kts) => RecordType(btmap(kts, v)?), |