summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2019-03-21 22:08:23 +0100
committerNadrieril2019-03-21 22:08:23 +0100
commit4b99a3fb46191a83fa8551f21b98cff689bbb338 (patch)
tree0d07b39dbcf794c9fe1174aeb6fb4923df2fd9b7
parentea08d2528d2ee46446ac8981e72af5c610e43ce1 (diff)
Improve import handling in parser
-rw-r--r--dhall/src/binary.rs15
-rw-r--r--dhall/src/imports.rs9
-rw-r--r--dhall/src/lib.rs11
-rw-r--r--dhall/tests/common/mod.rs13
-rw-r--r--dhall/tests/parser.rs2
-rw-r--r--dhall_core/src/core.rs6
-rw-r--r--dhall_core/src/parser.rs21
-rw-r--r--dhall_core/src/printer.rs14
-rw-r--r--dhall_parser/src/dhall.abnf4
-rw-r--r--dhall_parser/src/dhall.pest.visibility2
10 files changed, 80 insertions, 17 deletions
diff --git a/dhall/src/binary.rs b/dhall/src/binary.rs
index 8c5b902..1fa075e 100644
--- a/dhall/src/binary.rs
+++ b/dhall/src/binary.rs
@@ -1,6 +1,7 @@
use dhall_core::*;
use itertools::*;
use serde_cbor::value::value as cbor;
+use std::path::PathBuf;
use std::rc::Rc;
type ParsedExpr = Rc<Expr<X, Import>>;
@@ -175,6 +176,20 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> {
.collect::<Result<_, _>>()?,
)))
}
+ [U64(24), Null, U64(0), U64(3), rest..] => {
+ let mut path = PathBuf::new();
+ for s in rest {
+ match s {
+ String(s) => path.push(s),
+ _ => Err(DecodeError::WrongFormatError)?,
+ }
+ }
+ Embed(Import {
+ mode: ImportMode::Code,
+ hash: None,
+ location: ImportLocation::Local(FilePrefix::Here, path),
+ })
+ }
[U64(25), bindings..] => {
let mut tuples = bindings.iter().tuples();
let bindings = (&mut tuples)
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs
index 2435663..9f60ee7 100644
--- a/dhall/src/imports.rs
+++ b/dhall/src/imports.rs
@@ -84,3 +84,12 @@ pub fn load_dhall_file(
};
Ok(expr)
}
+
+pub fn load_dhall_file_no_resolve_imports(
+ f: &Path,
+) -> Result<ParsedExpr, DhallError> {
+ let mut buffer = String::new();
+ File::open(f)?.read_to_string(&mut buffer)?;
+ let expr = parse_expr(&*buffer)?;
+ Ok(expr)
+}
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs
index d8ca955..dcc1ff3 100644
--- a/dhall/src/lib.rs
+++ b/dhall/src/lib.rs
@@ -10,7 +10,16 @@
mod normalize;
pub use crate::normalize::*;
pub mod binary;
+pub mod dhall_type;
pub mod imports;
pub mod typecheck;
-pub use crate::imports::{load_dhall_file, DhallError};
+pub use crate::imports::*;
+
+pub struct DhallExpr(dhall_core::DhallExpr);
+
+impl DhallExpr {
+ pub fn normalize(self) -> Self {
+ DhallExpr(crate::normalize::normalize(self.0))
+ }
+}
diff --git a/dhall/tests/common/mod.rs b/dhall/tests/common/mod.rs
index ffc6d06..6b893e0 100644
--- a/dhall/tests/common/mod.rs
+++ b/dhall/tests/common/mod.rs
@@ -46,6 +46,12 @@ pub fn read_dhall_file<'i>(file_path: &str) -> Result<Expr<X, X>, DhallError> {
load_dhall_file(&PathBuf::from(file_path), true)
}
+pub fn read_dhall_file_no_resolve_imports<'i>(
+ file_path: &str,
+) -> Result<ParsedExpr, DhallError> {
+ load_dhall_file_no_resolve_imports(&PathBuf::from(file_path))
+}
+
pub fn run_test(base_path: &str, feature: Feature) {
use self::Feature::*;
let base_path_prefix = match feature {
@@ -61,7 +67,7 @@ pub fn run_test(base_path: &str, feature: Feature) {
ParserSuccess => {
let expr_file_path = base_path.clone() + "A.dhall";
let expected_file_path = base_path + "B.dhallb";
- let expr = read_dhall_file(&expr_file_path)
+ let expr = read_dhall_file_no_resolve_imports(&expr_file_path)
.map_err(|e| println!("{}", e))
.unwrap();
@@ -71,18 +77,17 @@ pub fn run_test(base_path: &str, feature: Feature) {
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
let expected = dhall::binary::decode(&data).unwrap();
- let expected = dhall::imports::panic_imports(&expected);
assert_eq_pretty!(expr, expected);
// Round-trip pretty-printer
let expr = parse_expr(&expr.to_string()).unwrap();
- let expr = dhall::imports::panic_imports(&expr);
assert_eq!(expr, expected);
}
ParserFailure => {
let file_path = base_path + ".dhall";
- let err = read_dhall_file(&file_path).unwrap_err();
+ let err =
+ read_dhall_file_no_resolve_imports(&file_path).unwrap_err();
match err {
DhallError::ParseError(_) => {}
e => panic!("Expected parse error, got: {:?}", e),
diff --git a/dhall/tests/parser.rs b/dhall/tests/parser.rs
index 4fa0ff7..79a059d 100644
--- a/dhall/tests/parser.rs
+++ b/dhall/tests/parser.rs
@@ -17,7 +17,7 @@ parser_success!(spec_parser_success_annotations, "annotations");
// parser_success!(spec_parser_success_asText, "asText");
parser_success!(spec_parser_success_blockComment, "blockComment");
parser_success!(spec_parser_success_builtins, "builtins");
-// parser_success!(spec_parser_success_collectionImportType, "collectionImportType");
+parser_success!(spec_parser_success_collectionImportType, "collectionImportType");
parser_success!(spec_parser_success_double, "double");
parser_success!(spec_parser_success_doubleQuotedString, "doubleQuotedString");
// parser_success!(spec_parser_success_environmentVariables, "environmentVariables");
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs
index 9f26b65..bc5a666 100644
--- a/dhall_core/src/core.rs
+++ b/dhall_core/src/core.rs
@@ -164,9 +164,9 @@ pub enum Builtin {
TextShow,
}
-pub type ParsedExpr<S> = SubExpr<S, Import>;
-pub type ResolvedExpr<S> = SubExpr<S, X>;
-pub type DhallExpr = ResolvedExpr<X>;
+pub type ParsedExpr = SubExpr<X, Import>;
+pub type ResolvedExpr = SubExpr<X, X>;
+pub type DhallExpr = ResolvedExpr;
pub type SubExpr<Note, Embed> = Rc<Expr<Note, Embed>>;
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 7de75d2..865e791 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -12,7 +12,6 @@ use crate::*;
// their own crate because they are quite general and useful. For now they
// are here and hopefully you can figure out how they work.
-type ParsedExpr = crate::ParsedExpr<X>;
type ParsedText = InterpolatedText<X, Import>;
type ParsedTextContents<'a> = InterpolatedTextContents<'a, X, Import>;
@@ -370,9 +369,21 @@ make_parser! {
}
);
- rule!(path<PathBuf>;
- captured_str!(s) => (".".to_owned() + s).into()
- );
+ rule!(unquoted_path_component<&'a str>; captured_str!(s) => s);
+ rule!(quoted_path_component<&'a str>; captured_str!(s) => s);
+ rule!(path_component<&'a str>; children!(
+ [unquoted_path_component(s)] => s,
+ [quoted_path_component(s)] => s,
+ ));
+ rule!(path<PathBuf>; children!(
+ [path_component(components..)] => {
+ let mut path = PathBuf::new();
+ for s in components {
+ path.push(s);
+ }
+ path
+ }
+ ));
rule_group!(local_raw<(FilePrefix, PathBuf)>);
@@ -728,7 +739,7 @@ make_parser! {
));
}
-pub fn parse_expr(s: &str) -> ParseResult<crate::ParsedExpr<X>> {
+pub fn parse_expr(s: &str) -> ParseResult<ParsedExpr> {
let mut pairs = DhallParser::parse(Rule::final_expression, s)?;
let expr = parse_any(pairs.next().unwrap())?;
assert_eq!(pairs.next(), None);
diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs
index e43f1be..bd38863 100644
--- a/dhall_core/src/printer.rs
+++ b/dhall_core/src/printer.rs
@@ -286,7 +286,19 @@ impl Display for Const {
impl Display for Import {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- <Self as fmt::Debug>::fmt(self, f)
+ use FilePrefix::*;
+ use ImportLocation::*;
+ match &self.location {
+ Local(prefix, path) => {
+ let prefix = match prefix {
+ Here => ".",
+ Parent => "..",
+ Home => "~",
+ Absolute => "",
+ };
+ write!(f, "{}/{}", prefix, path.to_str().unwrap())
+ }
+ }
}
}
diff --git a/dhall_parser/src/dhall.abnf b/dhall_parser/src/dhall.abnf
index d803770..c5c9a84 100644
--- a/dhall_parser/src/dhall.abnf
+++ b/dhall_parser/src/dhall.abnf
@@ -378,8 +378,10 @@ quoted-path-character =
; %x2F = "/"
/ %x30-10FFFF
+unquoted-path-component = 1*path-character
+quoted-path-component = 1*quoted-path-character
-path-component = "/" ( 1*path-character / %x22 1*quoted-path-character %x22 )
+path-component = "/" ( unquoted-path-component / %x22 quoted-path-component %x22 )
path = 1*path-component
diff --git a/dhall_parser/src/dhall.pest.visibility b/dhall_parser/src/dhall.pest.visibility
index 8610f7b..00075d3 100644
--- a/dhall_parser/src/dhall.pest.visibility
+++ b/dhall_parser/src/dhall.pest.visibility
@@ -92,7 +92,7 @@ identifier_raw
identifier
# path_character
# quoted_path_character
-# path_component
+path_component
path
# local_raw
scheme