diff options
author | Nadrieril | 2019-03-09 00:42:46 +0100 |
---|---|---|
committer | Nadrieril | 2019-03-09 00:43:13 +0100 |
commit | 505e6a34cc5aadac1831d31ef64b94b61c2ace13 (patch) | |
tree | 1cca4b507552df613c9852d755e9ada8dee67d7d /dhall/src | |
parent | c6aafe818ca56ec8bc6d3cd27824eba0a2d6b874 (diff) |
First import works !
Diffstat (limited to 'dhall/src')
-rw-r--r-- | dhall/src/imports.rs | 86 | ||||
-rw-r--r-- | dhall/src/lib.rs | 47 | ||||
-rw-r--r-- | dhall/src/main.rs | 3 |
3 files changed, 85 insertions, 51 deletions
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index ad0ae0f..d6da4d7 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -1,11 +1,89 @@ // use dhall_core::{Expr, FilePrefix, Import, ImportLocation, ImportMode, X}; -use dhall_core::{Expr, StringLike, Import, X}; +use dhall_core::{Expr, Import, StringLike, X}; // use std::path::Path; -// use std::path::PathBuf; +use dhall_core::*; +use std::fmt; +use std::fs::File; +use std::io::Read; +use std::path::Path; +use std::path::PathBuf; -pub fn resolve_imports<Label: StringLike, S: Clone>( +pub fn panic_imports<Label: StringLike, S: Clone>( expr: &Expr<Label, S, Import>, ) -> Expr<Label, S, X> { - let no_import = |_: &Import| -> X { panic!("ahhh import") }; + let no_import = |i: &Import| -> X { panic!("ahhh import: {:?}", i) }; expr.map_embed(&no_import) } + +/// A root from which to resolve relative imports. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ImportRoot { + LocalDir(PathBuf), +} + +fn resolve_import( + import: &Import, + root: &ImportRoot, +) -> Result<Expr<String, X, X>, DhallError> { + use self::ImportRoot::*; + use dhall_core::FilePrefix::*; + use dhall_core::ImportLocation::*; + let cwd = match root { + LocalDir(cwd) => cwd, + }; + match &import.location { + Local(prefix, path) => { + let path = match prefix { + Parent => cwd.parent().unwrap().join(path), + _ => unimplemented!(), + }; + load_dhall_file(&path, false) + } + } +} + +#[derive(Debug)] +pub enum DhallError { + ParseError(parser::ParseError), + IOError(std::io::Error), +} +impl From<parser::ParseError> for DhallError { + fn from(e: parser::ParseError) -> Self { + DhallError::ParseError(e) + } +} +impl From<std::io::Error> for DhallError { + fn from(e: std::io::Error) -> Self { + DhallError::IOError(e) + } +} +impl fmt::Display for DhallError { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + use self::DhallError::*; + match self { + ParseError(e) => e.fmt(f), + IOError(e) => e.fmt(f), + } + } +} + +pub fn load_dhall_file( + f: &Path, + resolve_imports: bool, +) -> Result<Expr<String, X, X>, DhallError> { + let mut buffer = String::new(); + File::open(f)?.read_to_string(&mut buffer)?; + let expr = parser::parse_expr(&*buffer)?; + let expr = expr.take_ownership_of_labels(); + let expr = if resolve_imports { + let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); + let resolve = |import: &Import| -> Expr<String, X, X> { + resolve_import(import, &root).unwrap() + }; + let expr = expr.map_embed(&resolve).squash_embed(); + expr + } else { + panic_imports(&expr) + }; + Ok(expr) +} diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 95f7f6f..8add5b6 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -7,49 +7,4 @@ pub use crate::normalize::*; pub mod imports; pub mod typecheck; -use dhall_core::*; -use std::fmt; -use std::fs::File; -use std::io::Read; -use std::path::Path; - -#[derive(Debug)] -pub enum DhallError { - ParseError(parser::ParseError), - IOError(std::io::Error), -} -impl From<parser::ParseError> for DhallError { - fn from(e: parser::ParseError) -> Self { - DhallError::ParseError(e) - } -} -impl From<std::io::Error> for DhallError { - fn from(e: std::io::Error) -> Self { - DhallError::IOError(e) - } -} -impl fmt::Display for DhallError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use self::DhallError::*; - match self { - ParseError(e) => e.fmt(f), - IOError(e) => e.fmt(f), - } - } -} - -/// `source_pool` is a Vec of strings to be used to store the contents of imported files. -/// No ideal but necessary for lifetime reasons for now. -pub fn load_dhall_file<'i, 'a: 'i>( - f: &Path, - source_pool: &'a mut Vec<String>, - _resolve_imports: bool, -) -> Result<Expr<String, X, X>, DhallError> { - source_pool.push(String::new()); - let mut buffer = source_pool.last_mut().unwrap(); - File::open(f)?.read_to_string(&mut buffer)?; - let expr = parser::parse_expr(&*buffer)?; - let expr = expr.take_ownership_of_labels(); - let expr = imports::resolve_imports(&expr); - Ok(expr) -} +pub use crate::imports::{load_dhall_file, DhallError}; diff --git a/dhall/src/main.rs b/dhall/src/main.rs index 23c8108..d072fe7 100644 --- a/dhall/src/main.rs +++ b/dhall/src/main.rs @@ -65,7 +65,8 @@ fn main() { } }; - let expr: Expr<String, _, _> = imports::resolve_imports(&expr.take_ownership_of_labels()); + let expr: Expr<String, _, _> = + imports::panic_imports(&expr.take_ownership_of_labels()); let type_expr = match typecheck::type_of(&expr) { Err(e) => { |