Repository: tweag/nickel
Pull request #545 (2022-01-05 14:30:33)

Fix: #522, Use eval_full to test examples
Fix: #522 


Patch:
diff --git a/examples/config-gcc/config-gcc.ncl b/examples/config-gcc/config-gcc.ncl
index 238c166c..a944eba9 100644
--- a/examples/config-gcc/config-gcc.ncl
+++ b/examples/config-gcc/config-gcc.ncl
@@ -4,7 +4,7 @@ let GccFlag =
   // We only allow the following flags
   let available = ["W", "c", "S", "e", "o"] in
   fun label value =>
-  if builtins.isStr value then
+  if builtins.is_str value then
     if strings.length value > 0 &&
       lists.any (fun x => x == strings.substring 0 1 value) available then
       value
@@ -27,7 +27,7 @@ let GccFlag =
 let Path =
   let pattern = m#"^(.+)/([^/]+)$"#m in
   fun label value =>
-    if builtins.isStr value then
+    if builtins.is_str value then
       if strings.is_match pattern value then
         value
       else
@@ -36,7 +36,7 @@ let Path =
       contracts.blame_with "not a string" label in
 
 let SharedObjectFile = fun label value =>
-  if builtins.isStr value then
+  if builtins.is_str value then
     if strings.is_match m#"\.so$"#m value then
       value
     else
diff --git a/src/eval.rs b/src/eval.rs
index fde94d63..05ec7354 100644
--- a/src/eval.rs
+++ b/src/eval.rs
@@ -665,6 +665,29 @@ pub fn eval_full<R>(
     global_env: &Environment,
     resolver: &mut R,
 ) -> Result<RichTerm, EvalError>
+where
+    R: ImportResolver,
+{
+    eval_deep_closure(t0, global_env, resolver).map(|(term, env)| subst(term, global_env, &env))
+}
+
+/// Fully evaluates a Nickel term like `eval_full`, but does not substitute all variables.
+pub fn eval_deep<R>(
+    t0: RichTerm,
+    global_env: &Environment,
+    resolver: &mut R,
+) -> Result<RichTerm, EvalError>
+where
+    R: ImportResolver,
+{
+    eval_deep_closure(t0, global_env, resolver).map(|(term, _)| term)
+}
+
+fn eval_deep_closure<R>(
+    t0: RichTerm,
+    global_env: &Environment,
+    resolver: &mut R,
+) -> Result<(RichTerm, Environment), EvalError>
 where
     R: ImportResolver,
 {
@@ -681,7 +704,6 @@ where
         ),
     );
     eval_closure(Closure::atomic_closure(wrapper), global_env, resolver, true)
-        .map(|(term, env)| subst(term, global_env, &env))
 }
 
 /// Evaluate a Nickel Term, stopping when a meta value is encountered at the top-level without
diff --git a/src/program.rs b/src/program.rs
index 5050b827..f111672a 100644
--- a/src/program.rs
+++ b/src/program.rs
@@ -89,6 +89,12 @@ impl Program {
         eval::eval_full(t, &global_env, &mut self.cache).map_err(|e| e.into())
     }
 
+    /// Same as `eval_full`, but does not substitute all variables.
+    pub fn eval_deep(&mut self) -> Result<RichTerm, Error> {
+        let (t, global_env) = self.prepare_eval()?;
+        eval::eval_deep(t, &global_env, &mut self.cache).map_err(|e| e.into())
+    }
+
     /// Wrapper for [`query`](./fn.query.html).
     pub fn query(&mut self, path: Option<String>) -> Result<Term, Error> {
         let global_env = self.cache.prepare_stdlib()?;


Test patch:
diff --git a/tests/examples.rs b/tests/examples.rs
index 4b5ed2e7..0139b106 100644
--- a/tests/examples.rs
+++ b/tests/examples.rs
@@ -8,7 +8,7 @@ fn eval_file(file: &str) -> Result<RichTerm, Error> {
     let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
     path.push(format!("examples/{}", file));
     let mut p = Program::new_from_file(path).expect("could not load file as a program");
-    p.eval()
+    p.eval_deep()
 }
 
 #[test]