summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock19
-rw-r--r--abnf_to_pest/Cargo.toml11
-rw-r--r--abnf_to_pest/README.md22
-rw-r--r--abnf_to_pest/src/lib.rs35
-rw-r--r--dhall/src/binary.rs4
-rw-r--r--dhall/src/normalize.rs2
-rw-r--r--dhall/src/tests.rs2
-rw-r--r--dhall/src/typecheck.rs14
-rw-r--r--dhall_core/src/core.rs4
-rw-r--r--dhall_core/src/parser.rs8
-rw-r--r--dhall_core/src/printer.rs8
-rw-r--r--dhall_core/src/visitor.rs4
12 files changed, 109 insertions, 24 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 448865e..097dd89 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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)?),