From b950171a130189907f42bf294d053dbfa16c4fc4 Mon Sep 17 00:00:00 2001 From: Matthew Pope Date: Tue, 21 Nov 2023 23:12:08 -0800 Subject: [PATCH] Adds data model for macro definitions --- .../java/com/amazon/ion/impl/macro/Macro.kt | 23 +++++++++ .../com/amazon/ion/impl/macro/MacroRef.kt | 9 ++++ .../amazon/ion/impl/macro/MacroSignature.kt | 16 +++++++ .../ion/impl/macro/TemplateExpression.kt | 47 +++++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 src/main/java/com/amazon/ion/impl/macro/Macro.kt create mode 100644 src/main/java/com/amazon/ion/impl/macro/MacroRef.kt create mode 100644 src/main/java/com/amazon/ion/impl/macro/MacroSignature.kt create mode 100644 src/main/java/com/amazon/ion/impl/macro/TemplateExpression.kt diff --git a/src/main/java/com/amazon/ion/impl/macro/Macro.kt b/src/main/java/com/amazon/ion/impl/macro/Macro.kt new file mode 100644 index 000000000..ef3300fc6 --- /dev/null +++ b/src/main/java/com/amazon/ion/impl/macro/Macro.kt @@ -0,0 +1,23 @@ +package com.amazon.ion.impl.macro + +import java.math.BigDecimal + +/** + * Marker interface for Macros + */ +sealed interface Macro + +/** + * Represents a template macro. A template macro is defined by a name, a signature, and a list of template expressions. + */ +data class TemplateMacro(val name: String, val f: BigDecimal, val signature: MacroSignature, val body: List): Macro + +/** + * Macros that are built in, rather than being defined by a template. + */ +enum class SystemMacro: Macro { + Stream, // A stream is technically not a macro, but we can implement it as a macro that is the identity function. + Annotate, + MakeString, + // TODO: Other system macros +} diff --git a/src/main/java/com/amazon/ion/impl/macro/MacroRef.kt b/src/main/java/com/amazon/ion/impl/macro/MacroRef.kt new file mode 100644 index 000000000..b89ab664e --- /dev/null +++ b/src/main/java/com/amazon/ion/impl/macro/MacroRef.kt @@ -0,0 +1,9 @@ +package com.amazon.ion.impl.macro + +/** + * A reference to a particular macro, either by name or by template id. + */ +sealed interface MacroRef { + @JvmInline value class ByName(val name: String): MacroRef + @JvmInline value class ById(val id: Long): MacroRef +} diff --git a/src/main/java/com/amazon/ion/impl/macro/MacroSignature.kt b/src/main/java/com/amazon/ion/impl/macro/MacroSignature.kt new file mode 100644 index 000000000..0a11d1ca3 --- /dev/null +++ b/src/main/java/com/amazon/ion/impl/macro/MacroSignature.kt @@ -0,0 +1,16 @@ +package com.amazon.ion.impl.macro + +/** + * Represents the signature of a macro. + */ +@JvmInline value class MacroSignature(val parameters: List) { + + data class Parameter(val variableName: String, val type: Encoding, val grouped: Boolean) + + enum class Encoding(val ionTextName: String?) { + Tagged(null), + Any("any"), + Int8("int8"), + // TODO: List all of the possible tagless encodings + } +} \ No newline at end of file diff --git a/src/main/java/com/amazon/ion/impl/macro/TemplateExpression.kt b/src/main/java/com/amazon/ion/impl/macro/TemplateExpression.kt new file mode 100644 index 000000000..5552fae54 --- /dev/null +++ b/src/main/java/com/amazon/ion/impl/macro/TemplateExpression.kt @@ -0,0 +1,47 @@ +package com.amazon.ion.impl.macro + +import com.amazon.ion.SymbolToken +import com.amazon.ion.impl.macro.ionelement.api.IonElement + +/** + * Represents an expression in the body of a template. + */ +sealed interface TemplateExpression { + // TODO: Special Forms (if_void, for, ...)? + + /** + * A value that is taken literally. I.e. there can be no variable substitutions or macros inside here. Usually, + * these will just be scalars, but it is possible for it to be a container type. + * + * We cannot use [`IonValue`](com.amazon.ion.IonValue) for this because `IonValue` requires references to parent + * containers and to an IonSystem which makes it impractical for reading and writing macros definitions. + * For now, we are using [IonElement], but that is not a good permanent solution. It is copy/pasted into this repo + * to avoid a circular dependency, and the dependencies are shaded, so it is not suitable for a public API. + */ + @JvmInline value class LiteralValue(val value: IonElement): TemplateExpression + + /** + * An Ion List that could contain variables or macro invocations. + */ + data class ListValue(val annotations: List, val expressionRange: IntRange): TemplateExpression + + /** + * An Ion SExp that could contain variables or macro invocations. + */ + data class SExpValue(val annotations: List, val expressionRange: IntRange): TemplateExpression + + /** + * An Ion Struct that could contain variables or macro invocations. + */ + data class StructValue(val annotations: List, val expressionRange: IntRange, val templateStructIndex: Map) + + /** + * A reference to a variable that needs to be expanded. + */ + @JvmInline value class Variable(val signatureIndex: Int): TemplateExpression + + /** + * A macro invocation that needs to be expanded. + */ + data class MacroInvocation(val macro: MacroRef, val argumentExpressionsRange: IntRange): TemplateExpression +} \ No newline at end of file