diff --git a/src/main/java/com/amazon/ion/impl/macro/Environment.kt b/src/main/java/com/amazon/ion/impl/macro/Environment.kt index 8513bf206..dfbd05f75 100644 --- a/src/main/java/com/amazon/ion/impl/macro/Environment.kt +++ b/src/main/java/com/amazon/ion/impl/macro/Environment.kt @@ -2,6 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 package com.amazon.ion.impl.macro +/** + * An `Environment` contains variable bindings for a given macro evaluation. + * + * The [arguments] is a list of expressions for the arguments that were passed to the current macro. + * It may also contain other expressions if the current macro invocation is part of a larger evaluation. + * + * The [argumentIndices] is a mapping from parameter index to the start of the corresponding expression in [arguments]. + * + * The [parentEnvironment] is an environment to use if any of the expressions in this environment + * contains a variable that references something from an outer macro invocation. + */ data class Environment private constructor( // Any variables found here have to be looked up in [parentEnvironment] val arguments: List, diff --git a/src/test/java/com/amazon/ion/impl/macro/MacroEvaluatorTest.kt b/src/test/java/com/amazon/ion/impl/macro/MacroEvaluatorTest.kt index c987f45e2..22155128a 100644 --- a/src/test/java/com/amazon/ion/impl/macro/MacroEvaluatorTest.kt +++ b/src/test/java/com/amazon/ion/impl/macro/MacroEvaluatorTest.kt @@ -179,6 +179,40 @@ class MacroEvaluatorTest { assertEquals(null, evaluator.expandNext()) } + @Test + fun `it should be possible to step out of a container before the end is reached`() { + // Given: + // (macro ABCs () ["a", "b", "c"]) + // When: + // (:ABCs) + // Then: + // [ "a", "b", "c" ] + + val evaluator = evaluatorWithMacroTable( + "ABCs" to template( + "", + listOf( + ListValue(emptyList(), 0, 4), + StringValue(value = "a"), + StringValue(value = "b"), + StringValue(value = "c"), + ) + ) + ) + + evaluator.initExpansion( + listOf( + EExpression(MacroRef.ByName("ABCs"), 0, 1) + ) + ) + + assertIsInstance(evaluator.expandNext()) + evaluator.stepIn() + assertEquals(StringValue(value = "a"), evaluator.expandNext()) + evaluator.stepOut() + assertEquals(null, evaluator.expandNext()) + } + @Test fun `a trivial variable substitution`() { // Given: