Skip to content

Commit

Permalink
Rewrite MacroEvaluator to support flatten, and container-making mac…
Browse files Browse the repository at this point in the history
…ros (#1019)
  • Loading branch information
popematt authored Jan 2, 2025
1 parent 5ea6d73 commit f816953
Show file tree
Hide file tree
Showing 13 changed files with 907 additions and 638 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,16 @@ private void readStreamAsExpressionGroup(
* @param expressions receives the expressions as they are materialized.
*/
protected void readValueAsExpression(boolean isImplicitRest, List<Expression.EExpressionBodyExpression> expressions) {
if (isMacroInvocation()) {
if (isImplicitRest && !isContainerAnExpressionGroup()) {
readStreamAsExpressionGroup(expressions);
return;
} else if (isMacroInvocation()) {
collectEExpressionArgs(expressions); // TODO avoid recursion
return;
}
IonType type = reader.encodingType();
List<SymbolToken> annotations = getAnnotations();
if (isImplicitRest && !isContainerAnExpressionGroup()) {
readStreamAsExpressionGroup(expressions);
} else if (IonType.isContainer(type)) {
if (IonType.isContainer(type) && !reader.isNullValue()) {
readContainerValueAsExpression(type, annotations, expressions);
} else {
readScalarValueAsExpression(type, annotations, expressions);
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/amazon/ion/impl/macro/Environment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ data class Environment private constructor(
val parentEnvironment: Environment?,
) {
fun createChild(arguments: List<Expression>, argumentIndices: List<Int>) = Environment(arguments, argumentIndices, this)

override fun toString() = """
|Environment(
| argumentIndices: $argumentIndices,
| argumentExpressions: [${arguments.mapIndexed { index, expression -> "\n| $index. $expression" }.joinToString() }
| ],
| parent: ${parentEnvironment.toString().lines().joinToString("\n| ")},
|)
""".trimMargin()

companion object {
@JvmStatic
val EMPTY = Environment(emptyList(), emptyList(), null)
Expand Down
30 changes: 25 additions & 5 deletions src/main/java/com/amazon/ion/impl/macro/Expression.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,21 @@ sealed interface Expression {
* These expressions are the only ones that may be the output from the macro evaluator.
* All [DataModelExpression]s are also valid to use as [TemplateBodyExpression]s and [EExpressionBodyExpression]s.
*/
sealed interface DataModelExpression : Expression, EExpressionBodyExpression, TemplateBodyExpression
sealed interface DataModelExpression : Expression, EExpressionBodyExpression, TemplateBodyExpression, ExpansionOutputExpression

/** Output of a macro expansion (internal to the macro evaluator) */
sealed interface ExpansionOutputExpressionOrContinue
/** Output of the macro evaluator */
sealed interface ExpansionOutputExpression : ExpansionOutputExpressionOrContinue

/**
* Indicates to the macro evaluator that the current expansion did not produce a value this time, but it may
* produce more expressions. The macro evaluator should request another expression from that macro.
*/
data object ContinueExpansion : ExpansionOutputExpressionOrContinue

/** Signals the end of an expansion in the macro evaluator. */
data object EndOfExpansion : ExpansionOutputExpression

/**
* Interface for expressions that are _values_ in the Ion data model.
Expand All @@ -69,6 +83,8 @@ sealed interface Expression {

/**
* A temporary placeholder that is used only while a macro or e-expression is partially compiled.
*
* TODO: See if we can get rid of this by e.g. using nulls during macro compilation.
*/
object Placeholder : TemplateBodyExpression, EExpressionBodyExpression

Expand Down Expand Up @@ -221,21 +237,25 @@ sealed interface Expression {
*/
data class VariableRef(val signatureIndex: Int) : TemplateBodyExpression

sealed interface InvokableExpression : HasStartAndEnd, Expression {
val macro: Macro
}

/**
* A macro invocation that needs to be expanded.
*/
data class MacroInvocation(
val macro: Macro,
override val macro: Macro,
override val selfIndex: Int,
override val endExclusive: Int
) : TemplateBodyExpression, HasStartAndEnd
) : TemplateBodyExpression, HasStartAndEnd, InvokableExpression

/**
* An e-expression that needs to be expanded.
*/
data class EExpression(
val macro: Macro,
override val macro: Macro,
override val selfIndex: Int,
override val endExclusive: Int
) : EExpressionBodyExpression, HasStartAndEnd
) : EExpressionBodyExpression, HasStartAndEnd, InvokableExpression
}
Loading

0 comments on commit f816953

Please sign in to comment.